Showing preview only (1,691K chars total). Download the full file or copy to clipboard to get everything.
Repository: mikefarah/yq
Branch: master
Commit: 34d3a2930855
Files: 536
Total size: 1.5 MB
Directory structure:
gitextract_0o7jw5o7/
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report_v4.md
│ │ └── feature_request.md
│ ├── dependabot.yml
│ ├── instructions/
│ │ └── instructions.md
│ └── workflows/
│ ├── codeql.yml
│ ├── docker-release.yml
│ ├── go.yml
│ ├── release.yml
│ └── snap-release.yml
├── .gitignore
├── .golangci.bck.yml
├── .golangci.yml
├── .goreleaser.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.dev
├── LICENSE
├── Makefile
├── Makefile.variables
├── README.md
├── acceptance_tests/
│ ├── bad_args.sh
│ ├── basic.sh
│ ├── completion.sh
│ ├── empty.sh
│ ├── flags.sh
│ ├── front-matter.sh
│ ├── header-processing-off.sh
│ ├── inputs-format-auto.sh
│ ├── inputs-format.sh
│ ├── leading-separator.sh
│ ├── load-file.sh
│ ├── nul-separator.sh
│ ├── output-format.sh
│ ├── pipe.sh
│ ├── pretty-print.sh
│ ├── shebang.sh
│ └── split-printer.sh
├── action.yml
├── agents.md
├── cmd/
│ ├── completion.go
│ ├── constant.go
│ ├── evaluate_all_command.go
│ ├── evaluate_all_command_test.go
│ ├── evaluate_sequence_command.go
│ ├── evaluate_sequence_command_test.go
│ ├── root.go
│ ├── root_test.go
│ ├── unwrap_flag.go
│ ├── utils.go
│ ├── utils_test.go
│ ├── version.go
│ └── version_test.go
├── cspell.config.yaml
├── examples/
│ ├── array.yaml
│ ├── bad.yaml
│ ├── base64.txt
│ ├── data.lua
│ ├── data1-no-comments.yaml
│ ├── data1.yaml
│ ├── data2.yaml
│ ├── data3.yaml
│ ├── empty-no-comment.yaml
│ ├── empty.yaml
│ ├── environment.yq
│ ├── example.properties
│ ├── front-matter.yaml
│ ├── instruction_sample.yaml
│ ├── kyaml.yml
│ ├── leading-separator.yaml
│ ├── merge-anchor.yaml
│ ├── mike.xml
│ ├── mike2.xml
│ ├── multiline-text.yaml
│ ├── multiple_docs.yaml
│ ├── multiple_docs_small.yaml
│ ├── numbered_keys.yml
│ ├── order.yaml
│ ├── order.yml
│ ├── sample.hcl
│ ├── sample.ini
│ ├── sample.json
│ ├── sample.tf
│ ├── sample.toml
│ ├── sample.yaml
│ ├── sample2.hcl
│ ├── sample_array.yaml
│ ├── sample_array_2.yaml
│ ├── sample_no_sections.ini
│ ├── sample_objects.csv
│ ├── sample_text.yaml
│ ├── simple-anchor-exploded.yaml
│ ├── simple-anchor.yaml
│ ├── small.properties
│ ├── small.xml
│ ├── small.yaml
│ └── thing.yml
├── github-action/
│ ├── Dockerfile
│ └── entrypoint.sh
├── go.mod
├── go.sum
├── go_install_test.go
├── how-it-works.md
├── mkdocs.yml
├── pkg/
│ └── yqlib/
│ ├── all_at_once_evaluator.go
│ ├── all_at_once_evaluator_test.go
│ ├── base64_test.go
│ ├── candidate_node.go
│ ├── candidate_node_goccy_yaml.go
│ ├── candidate_node_test.go
│ ├── candidate_node_yaml.go
│ ├── candidiate_node_json.go
│ ├── chown_linux.go
│ ├── chown_linux_test.go
│ ├── chown_not_linux_os.go
│ ├── color_print.go
│ ├── color_print_test.go
│ ├── context.go
│ ├── context_test.go
│ ├── csv.go
│ ├── csv_test.go
│ ├── data_tree_navigator.go
│ ├── data_tree_navigator_test.go
│ ├── decoder.go
│ ├── decoder_base64.go
│ ├── decoder_csv_object.go
│ ├── decoder_goccy_yaml.go
│ ├── decoder_hcl.go
│ ├── decoder_ini.go
│ ├── decoder_json.go
│ ├── decoder_lua.go
│ ├── decoder_properties.go
│ ├── decoder_test.go
│ ├── decoder_toml.go
│ ├── decoder_uri.go
│ ├── decoder_uri_test.go
│ ├── decoder_xml.go
│ ├── decoder_yaml.go
│ ├── doc/
│ │ ├── .gitignore
│ │ ├── notification-snippet.md
│ │ ├── operators/
│ │ │ ├── add.md
│ │ │ ├── alternative-default-value.md
│ │ │ ├── anchor-and-alias-operators.md
│ │ │ ├── array-to-map.md
│ │ │ ├── assign-update.md
│ │ │ ├── boolean-operators.md
│ │ │ ├── collect-into-array.md
│ │ │ ├── column.md
│ │ │ ├── comment-operators.md
│ │ │ ├── compare.md
│ │ │ ├── contains.md
│ │ │ ├── create-collect-into-object.md
│ │ │ ├── datetime.md
│ │ │ ├── delete.md
│ │ │ ├── divide.md
│ │ │ ├── document-index.md
│ │ │ ├── encode-decode.md
│ │ │ ├── entries.md
│ │ │ ├── env-variable-operators.md
│ │ │ ├── equals.md
│ │ │ ├── error.md
│ │ │ ├── eval.md
│ │ │ ├── file-operators.md
│ │ │ ├── filter.md
│ │ │ ├── first.md
│ │ │ ├── flatten.md
│ │ │ ├── group-by.md
│ │ │ ├── has.md
│ │ │ ├── headers/
│ │ │ │ ├── Main.md
│ │ │ │ ├── add.md
│ │ │ │ ├── alternative-default-value.md
│ │ │ │ ├── anchor-and-alias-operators.md
│ │ │ │ ├── array-to-map.md
│ │ │ │ ├── assign-update.md
│ │ │ │ ├── boolean-operators.md
│ │ │ │ ├── collect-into-array.md
│ │ │ │ ├── column.md
│ │ │ │ ├── comment-operators.md
│ │ │ │ ├── compare.md
│ │ │ │ ├── contains.md
│ │ │ │ ├── create-collect-into-object.md
│ │ │ │ ├── datetime.md
│ │ │ │ ├── delete.md
│ │ │ │ ├── divide.md
│ │ │ │ ├── document-index.md
│ │ │ │ ├── encode-decode.md
│ │ │ │ ├── entries.md
│ │ │ │ ├── env-variable-operators.md
│ │ │ │ ├── equals.md
│ │ │ │ ├── error.md
│ │ │ │ ├── eval.md
│ │ │ │ ├── file-operators.md
│ │ │ │ ├── filter.md
│ │ │ │ ├── first.md
│ │ │ │ ├── flatten.md
│ │ │ │ ├── group-by.md
│ │ │ │ ├── has.md
│ │ │ │ ├── keys.md
│ │ │ │ ├── kind.md
│ │ │ │ ├── length.md
│ │ │ │ ├── line.md
│ │ │ │ ├── load.md
│ │ │ │ ├── map.md
│ │ │ │ ├── max.md
│ │ │ │ ├── min.md
│ │ │ │ ├── modulo.md
│ │ │ │ ├── multiply-merge.md
│ │ │ │ ├── omit.md
│ │ │ │ ├── parent.md
│ │ │ │ ├── path.md
│ │ │ │ ├── pick.md
│ │ │ │ ├── pipe.md
│ │ │ │ ├── pivot.md
│ │ │ │ ├── recursive-descent-glob.md
│ │ │ │ ├── reduce.md
│ │ │ │ ├── reverse.md
│ │ │ │ ├── select.md
│ │ │ │ ├── shuffle.md
│ │ │ │ ├── slice-array.md
│ │ │ │ ├── sort-keys.md
│ │ │ │ ├── sort.md
│ │ │ │ ├── split-into-documents.md
│ │ │ │ ├── string-operators.md
│ │ │ │ ├── style.md
│ │ │ │ ├── subtract.md
│ │ │ │ ├── tag.md
│ │ │ │ ├── to_number.md
│ │ │ │ ├── traverse-read.md
│ │ │ │ ├── union.md
│ │ │ │ ├── unique.md
│ │ │ │ ├── variable-operators.md
│ │ │ │ └── with.md
│ │ │ ├── keys.md
│ │ │ ├── kind.md
│ │ │ ├── length.md
│ │ │ ├── line.md
│ │ │ ├── load.md
│ │ │ ├── map.md
│ │ │ ├── max.md
│ │ │ ├── min.md
│ │ │ ├── modulo.md
│ │ │ ├── multiply-merge.md
│ │ │ ├── omit.md
│ │ │ ├── parent.md
│ │ │ ├── path.md
│ │ │ ├── pick.md
│ │ │ ├── pipe.md
│ │ │ ├── pivot.md
│ │ │ ├── recursive-descent-glob.md
│ │ │ ├── reduce.md
│ │ │ ├── reverse.md
│ │ │ ├── select.md
│ │ │ ├── shuffle.md
│ │ │ ├── slice-array.md
│ │ │ ├── sort-keys.md
│ │ │ ├── sort.md
│ │ │ ├── split-into-documents.md
│ │ │ ├── string-operators.md
│ │ │ ├── style.md
│ │ │ ├── subtract.md
│ │ │ ├── tag.md
│ │ │ ├── to_number.md
│ │ │ ├── traverse-read.md
│ │ │ ├── union.md
│ │ │ ├── unique.md
│ │ │ ├── variable-operators.md
│ │ │ └── with.md
│ │ └── usage/
│ │ ├── base64.md
│ │ ├── convert.md
│ │ ├── csv-tsv.md
│ │ ├── formatting-expressions.md
│ │ ├── hcl.md
│ │ ├── headers/
│ │ │ ├── base64.md
│ │ │ ├── convert.md
│ │ │ ├── csv-tsv.md
│ │ │ ├── formatting-expressions.md
│ │ │ ├── hcl.md
│ │ │ ├── kyaml.md
│ │ │ ├── properties.md
│ │ │ ├── recipes.md
│ │ │ ├── toml.md
│ │ │ └── xml.md
│ │ ├── kyaml.md
│ │ ├── lua.md
│ │ ├── properties.md
│ │ ├── recipes.md
│ │ ├── shellvariables.md
│ │ ├── toml.md
│ │ └── xml.md
│ ├── encoder.go
│ ├── encoder_base64.go
│ ├── encoder_csv.go
│ ├── encoder_hcl.go
│ ├── encoder_ini.go
│ ├── encoder_json.go
│ ├── encoder_kyaml.go
│ ├── encoder_lua.go
│ ├── encoder_properties.go
│ ├── encoder_properties_test.go
│ ├── encoder_sh.go
│ ├── encoder_shellvariables.go
│ ├── encoder_shellvariables_test.go
│ ├── encoder_test.go
│ ├── encoder_toml.go
│ ├── encoder_uri.go
│ ├── encoder_xml.go
│ ├── encoder_yaml.go
│ ├── expression_parser.go
│ ├── expression_parser_test.go
│ ├── expression_postfix.go
│ ├── expression_processing_test.go
│ ├── file_utils.go
│ ├── format.go
│ ├── format_test.go
│ ├── formatting_expressions_test.go
│ ├── front_matter.go
│ ├── front_matter_test.go
│ ├── goccy_yaml_test.go
│ ├── hcl.go
│ ├── hcl_test.go
│ ├── ini.go
│ ├── ini_test.go
│ ├── json.go
│ ├── json_test.go
│ ├── kyaml.go
│ ├── kyaml_test.go
│ ├── lexer.go
│ ├── lexer_participle.go
│ ├── lexer_participle_test.go
│ ├── lib.go
│ ├── lib_test.go
│ ├── lua.go
│ ├── lua_test.go
│ ├── matchKeyString.go
│ ├── matchKeyString_test.go
│ ├── no_base64.go
│ ├── no_csv.go
│ ├── no_hcl.go
│ ├── no_ini.go
│ ├── no_json.go
│ ├── no_kyaml.go
│ ├── no_lua.go
│ ├── no_props.go
│ ├── no_sh.go
│ ├── no_shellvariables.go
│ ├── no_toml.go
│ ├── no_uri.go
│ ├── no_xml.go
│ ├── operation.go
│ ├── operator_add.go
│ ├── operator_add_test.go
│ ├── operator_alternative.go
│ ├── operator_alternative_test.go
│ ├── operator_anchors_aliases.go
│ ├── operator_anchors_aliases_test.go
│ ├── operator_array_to_map_test.go
│ ├── operator_assign.go
│ ├── operator_assign_test.go
│ ├── operator_booleans.go
│ ├── operator_booleans_test.go
│ ├── operator_collect.go
│ ├── operator_collect_object.go
│ ├── operator_collect_object_test.go
│ ├── operator_collect_test.go
│ ├── operator_column.go
│ ├── operator_column_test.go
│ ├── operator_comments.go
│ ├── operator_comments_test.go
│ ├── operator_compare.go
│ ├── operator_contains.go
│ ├── operator_contains_test.go
│ ├── operator_create_map.go
│ ├── operator_create_map_test.go
│ ├── operator_datetime.go
│ ├── operator_datetime_test.go
│ ├── operator_delete.go
│ ├── operator_delete_test.go
│ ├── operator_divide.go
│ ├── operator_divide_test.go
│ ├── operator_document_index.go
│ ├── operator_document_index_test.go
│ ├── operator_encoder_decoder.go
│ ├── operator_encoder_decoder_test.go
│ ├── operator_entries.go
│ ├── operator_entries_test.go
│ ├── operator_env.go
│ ├── operator_env_test.go
│ ├── operator_equals.go
│ ├── operator_equals_test.go
│ ├── operator_error.go
│ ├── operator_error_test.go
│ ├── operator_eval.go
│ ├── operator_eval_test.go
│ ├── operator_expression.go
│ ├── operator_file.go
│ ├── operator_file_test.go
│ ├── operator_filter.go
│ ├── operator_filter_test.go
│ ├── operator_first.go
│ ├── operator_first_test.go
│ ├── operator_flatten.go
│ ├── operator_flatten_test.go
│ ├── operator_group_by.go
│ ├── operator_group_by_test.go
│ ├── operator_has.go
│ ├── operator_has_test.go
│ ├── operator_keys.go
│ ├── operator_keys_test.go
│ ├── operator_kind.go
│ ├── operator_kind_test.go
│ ├── operator_length.go
│ ├── operator_length_test.go
│ ├── operator_line.go
│ ├── operator_line_test.go
│ ├── operator_load.go
│ ├── operator_load_test.go
│ ├── operator_map.go
│ ├── operator_map_test.go
│ ├── operator_modulo.go
│ ├── operator_modulo_test.go
│ ├── operator_multiply.go
│ ├── operator_multiply_test.go
│ ├── operator_omit.go
│ ├── operator_omit_test.go
│ ├── operator_parent.go
│ ├── operator_parent_test.go
│ ├── operator_path.go
│ ├── operator_path_test.go
│ ├── operator_pick.go
│ ├── operator_pick_test.go
│ ├── operator_pipe.go
│ ├── operator_pipe_test.go
│ ├── operator_pivot.go
│ ├── operator_pivot_test.go
│ ├── operator_recursive_descent.go
│ ├── operator_recursive_descent_test.go
│ ├── operator_reduce.go
│ ├── operator_reduce_test.go
│ ├── operator_reverse.go
│ ├── operator_reverse_test.go
│ ├── operator_select.go
│ ├── operator_select_test.go
│ ├── operator_self.go
│ ├── operator_shuffle.go
│ ├── operator_shuffle_test.go
│ ├── operator_slice.go
│ ├── operator_slice_test.go
│ ├── operator_sort.go
│ ├── operator_sort_keys.go
│ ├── operator_sort_keys_test.go
│ ├── operator_sort_test.go
│ ├── operator_split_document.go
│ ├── operator_split_document_test.go
│ ├── operator_strings.go
│ ├── operator_strings_test.go
│ ├── operator_style.go
│ ├── operator_style_test.go
│ ├── operator_subtract.go
│ ├── operator_subtract_test.go
│ ├── operator_tag.go
│ ├── operator_tag_test.go
│ ├── operator_to_number.go
│ ├── operator_to_number_test.go
│ ├── operator_traverse_path.go
│ ├── operator_traverse_path_test.go
│ ├── operator_union.go
│ ├── operator_union_test.go
│ ├── operator_unique.go
│ ├── operator_unique_test.go
│ ├── operator_value.go
│ ├── operator_value_test.go
│ ├── operator_variables.go
│ ├── operator_variables_test.go
│ ├── operator_with.go
│ ├── operator_with_test.go
│ ├── operators.go
│ ├── operators_compare_test.go
│ ├── operators_test.go
│ ├── printer.go
│ ├── printer_node_info.go
│ ├── printer_node_info_test.go
│ ├── printer_test.go
│ ├── printer_writer.go
│ ├── properties.go
│ ├── properties_test.go
│ ├── recipes_test.go
│ ├── security_prefs.go
│ ├── shellvariables.go
│ ├── shellvariables_test.go
│ ├── stream_evaluator.go
│ ├── string_evaluator.go
│ ├── string_evaluator_test.go
│ ├── toml.go
│ ├── toml_test.go
│ ├── utils.go
│ ├── write_in_place_handler.go
│ ├── write_in_place_handler_test.go
│ ├── xml.go
│ ├── xml_test.go
│ ├── yaml.go
│ └── yaml_test.go
├── project-words.txt
├── release_instructions.txt
├── release_notes.txt
├── scripts/
│ ├── acceptance.sh
│ ├── build-small-yq.sh
│ ├── build-tinygo-yq.sh
│ ├── bump-version.sh
│ ├── check.sh
│ ├── compare-jq.sh
│ ├── compare-versions-output.sh
│ ├── copy-docs.sh
│ ├── coverage.sh
│ ├── devtools.sh
│ ├── extract-checksum.sh
│ ├── format.sh
│ ├── generate-man-page-md.sh
│ ├── generate-man-page.sh
│ ├── install-man-page.sh
│ ├── release-deb.sh
│ ├── secure.sh
│ ├── setup.sh
│ ├── shunit2
│ ├── spelling.sh
│ ├── test-docker.sh
│ ├── test.sh
│ └── xcompile.sh
├── snap/
│ └── snapcraft.yaml
├── test/
│ ├── format_test.go
│ └── utils.go
├── test.yq
├── utf8.csv
├── yq.go
└── yq_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
bin/*
================================================
FILE: .github/FUNDING.yml
================================================
github: mikefarah
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report_v4.md
================================================
---
name: Bug report - V4
about: Create a report to help us improve
title: ''
labels: bug, v4
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
Note that any how to questions should be posted in the discussion board and not raised as an issue.
Version of yq: 4.X.X
Operating system: mac/linux/windows/....
Installed via: docker/binary release/homebrew/snap/...
**Input Yaml**
Concise yaml document(s) (as simple as possible to show the bug, please keep it to 10 lines or less)
data1.yml:
```yaml
this: should really work
```
data2.yml:
```yaml
but: it strangely didn't
```
**Command**
The command you ran:
```
yq eval-all 'select(fileIndex==0) | .a.b.c' data1.yml data2.yml
```
**Actual behaviour**
```yaml
cat: meow
```
**Expected behaviour**
```yaml
this: should really work
but: it strangely didn't
```
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request - V4
about: Suggest an idea for this project
title: ''
labels: enhancement, v4
assignees: ''
---
**Please describe your feature request.**
A clear and concise description of what the request is and what it would solve.
Eg. I wish I could use yq to [...]
Note:
- how to questions should be posted in the discussion board and not raised as an issue.
- V3 will no longer have any enhancements.
**Describe the solution you'd like**
If we have data1.yml like:
(please keep to around 10 lines )
```yaml
country: Australia
```
And we run a command:
```bash
yq 'predictWeatherOf(.country)'
```
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.
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: docker
directory: /
schedule:
day: thursday
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
day: thursday
interval: weekly
- package-ecosystem: gomod
directory: /
schedule:
day: thursday
interval: weekly
================================================
FILE: .github/instructions/instructions.md
================================================
When you find a bug - make sure to include a new test that exposes the bug, as well as the fix for the bug itself.
================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '24 3 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v4
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
================================================
FILE: .github/workflows/docker-release.yml
================================================
name: Release Docker
on:
release:
types: [released]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
publishDocker:
environment: dockerhub
env:
IMAGE_NAME: mikefarah/yq
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }} && docker version
- name: Login to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push image
run: |
echo "GithubRef: ${GITHUB_REF}"
VERSION=${GITHUB_REF##*/}
echo "VERSION: ${VERSION}"
IMAGE_VERSION=${VERSION:1}
echo "IMAGE_VERSION: ${IMAGE_VERSION}"
PLATFORMS="linux/amd64,linux/ppc64le,linux/arm64,linux/arm/v7,linux/s390x"
echo "Building and pushing version ${IMAGE_VERSION} of image ${IMAGE_NAME}"
docker buildx build \
--label "org.opencontainers.image.authors=https://github.com/mikefarah/yq/graphs/contributors" \
--label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \
--label "org.opencontainers.image.description=yq is a portable command-line data file processor" \
--label "org.opencontainers.image.documentation=https://mikefarah.gitbook.io/yq/" \
--label "org.opencontainers.image.licenses=MIT" \
--label "org.opencontainers.image.revision=$(git rev-parse HEAD)" \
--label "org.opencontainers.image.source=https://github.com/mikefarah/yq" \
--label "org.opencontainers.image.title=yq" \
--label "org.opencontainers.image.url=https://mikefarah.gitbook.io/yq/" \
--label "org.opencontainers.image.version=${IMAGE_VERSION}" \
--platform "${PLATFORMS}" \
--pull \
--push \
-t "${IMAGE_NAME}:${IMAGE_VERSION}" \
-t "${IMAGE_NAME}:4" \
-t "${IMAGE_NAME}:latest" \
-t "ghcr.io/${IMAGE_NAME}:${IMAGE_VERSION}" \
-t "ghcr.io/${IMAGE_NAME}:4" \
-t "ghcr.io/${IMAGE_NAME}:latest" \
.
cd github-action
docker buildx build \
--label "org.opencontainers.image.authors=https://github.com/mikefarah/yq/graphs/contributors" \
--label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" \
--label "org.opencontainers.image.description=yq is a portable command-line data file processor" \
--label "org.opencontainers.image.documentation=https://mikefarah.gitbook.io/yq/" \
--label "org.opencontainers.image.licenses=MIT" \
--label "org.opencontainers.image.revision=$(git rev-parse HEAD)" \
--label "org.opencontainers.image.source=https://github.com/mikefarah/yq" \
--label "org.opencontainers.image.title=yq" \
--label "org.opencontainers.image.url=https://mikefarah.gitbook.io/yq/" \
--label "org.opencontainers.image.version=${IMAGE_VERSION}" \
--platform "${PLATFORMS}" \
--pull \
--push \
-t "${IMAGE_NAME}:${IMAGE_VERSION}-githubaction" \
-t "${IMAGE_NAME}:4-githubaction" \
-t "${IMAGE_NAME}:latest-githubaction" \
-t "ghcr.io/${IMAGE_NAME}:${IMAGE_VERSION}-githubaction" \
-t "ghcr.io/${IMAGE_NAME}:4-githubaction" \
-t "ghcr.io/${IMAGE_NAME}:latest-githubaction" \
.
================================================
FILE: .github/workflows/go.yml
================================================
name: Build
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '^1.20'
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v6
- 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: Check the build
shell: bash -l {0}
run: |
export PATH=${PATH}:`go env GOPATH`/bin
scripts/devtools.sh
make local build
================================================
FILE: .github/workflows/release.yml
================================================
name: Release YQ
on:
push:
tags:
- 'v4.*'
- 'draft-*'
jobs:
publishGitRelease:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: '^1.20'
check-latest: true
- name: Compile man page markup
id: gen-man-page-md
run: |
./scripts/generate-man-page-md.sh
- name: Get the version
id: get_version
run: echo "VERSION=${GITHUB_REF##*/}" >> "${GITHUB_OUTPUT}"
- name: Generate man page
uses: docker://pandoc/core:2.14.2
id: gen-man-page
with:
args: >-
--standalone
--to man
--variable=title:"YQ"
--variable=section:"1"
--variable=header:"yq (https://github.com/mikefarah/yq/) version ${{ steps.get_version.outputs.VERSION }}"
--variable=author:"Mike Farah"
--output=yq.1
man.md
- name: Cross compile
run: |
sudo apt-get install rhash -y
go install github.com/goreleaser/goreleaser/v2@latest
./scripts/xcompile.sh
- name: Release
uses: softprops/action-gh-release@v1
with:
files: build/*
draft: true
fail_on_unmatched_files: true
================================================
FILE: .github/workflows/snap-release.yml
================================================
name: Release Snap
on:
release:
types: [released]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
buildSnap:
environment: snap
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: snapcore/action-build@v1
id: build
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.STORE_LOGIN }}
with:
snapcraft-args: "remote-build --launchpad-accept-public-upload"
- uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.STORE_LOGIN }}
with:
snap: ${{ steps.build.outputs.snap }}
release: stable
================================================
FILE: .gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
bin
build
build-done
.DS_Store
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
cover.out
coverage.out
coverage.html
coverage_sorted.txt
*.exe
*.test
*.prof
yaml
vendor/
tmp/
cover/
yq
# snapcraft
parts/
prime/
.snapcraft/
yq*.snap
test.yml
test*.yml
test*.tf
test*.xml
test*.toml
test*.yaml
*.kyaml
test_dir1/
test_dir2/
0.yml
1.yml
2.yml
# man page
man.md
yq.1
# debian pkg
_build
debian/files
# intellij
/.idea
# vscode
.vscode
yq3
# Golang
.gomodcache/
.gocache/
================================================
FILE: .golangci.bck.yml
================================================
run:
timeout: 5m
linters:
enable:
- asciicheck
- depguard
- errorlint
- gci
- gochecknoinits
- gofmt
- goimports
- gosec
- gosimple
- staticcheck
- unused
- misspell
- nakedret
- nolintlint
- predeclared
- revive
- unconvert
- unparam
linters-settings:
depguard:
rules:
prevent_unmaintained_packages:
list-mode: lax
files:
- $all
- "!$test"
deny:
- pkg: io/ioutil
desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
issues:
exclude-rules:
- linters:
- revive
text: "var-naming"
================================================
FILE: .golangci.yml
================================================
version: "2"
linters:
enable:
- asciicheck
- depguard
- errorlint
- gochecknoinits
- gosec
- misspell
- nakedret
- nolintlint
- predeclared
- revive
- unconvert
- unparam
settings:
misspell:
locale: UK
ignore-rules:
- color
- colors
depguard:
rules:
prevent_unmaintained_packages:
list-mode: lax
files:
- $all
- '!$test'
deny:
- pkg: io/ioutil
desc: 'replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil'
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- revive
text: var-naming
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
================================================
FILE: .goreleaser.yaml
================================================
version: 2
dist: build
builds:
- id: yq
binary: yq_{{ .Os }}_{{ .Arch }}
ldflags:
- -s -w
env:
- CGO_ENABLED=0
targets:
- darwin_amd64
- darwin_arm64
- freebsd_386
- freebsd_amd64
- freebsd_arm
- linux_386
- linux_amd64
- linux_arm
- linux_arm64
- linux_loong64
- linux_mips
- linux_mips64
- linux_mips64le
- linux_mipsle
- linux_ppc64
- linux_ppc64le
- linux_riscv64
- linux_s390x
- netbsd_386
- netbsd_amd64
- netbsd_arm
- openbsd_386
- openbsd_amd64
- windows_386
- windows_amd64
- windows_arm64
no_unique_dist_dir: true
release:
disable: true
skip_upload: true
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# 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 behaviour 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 behaviour 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
behaviour and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behaviour.
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 behaviours 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 behaviour 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
================================================
FILE: CONTRIBUTING.md
================================================
# Before you begin
Not all new PRs will be merged in
It's recommended to check with the owner first (e.g. raise an issue) to discuss a new feature before developing, to ensure your hard efforts don't go to waste.
PRs to fix bugs and issues are almost always welcome :pray: please ensure you write tests as well.
The following types of PRs will _not_ be accepted:
- **Significant refactors** take a lot of time to understand and can have all sorts of unintended side effects. If you think there's a better way to do things (that requires significant changes) raise an issue for discussion first :)
- **Release pipeline PRs** are a security risk - it's too easy for a serious vulnerability to sneak in (either intended or not). If there is a new cool way of releasing things, raise an issue for discussion first - it will need to be gone over with a fine tooth comb.
- **Version bumps** are handled by dependabot, the bot will auto-raise PRs and they will be regularly merged in.
- **New release platforms** At this stage, yq is not going to maintain any other release platforms other than GitHub and Docker - that said, I'm more than happy to put in other community maintained methods in the README for visibility :heart:
# Development
## Initial Setup
1. Install [Golang](https://golang.org/) (version 1.24.0 or later)
2. Run `scripts/devtools.sh` to install required development tools:
- golangci-lint for code linting
- gosec for security analysis
3. Run `make [local] vendor` to install vendor dependencies
4. Run `make [local] test` to ensure you can run the existing tests
## Development Workflow
1. **Write unit tests first** - Changes will not be accepted without corresponding unit tests (see Testing section below)
2. **Make your code changes**
3. **Run tests and linting**: `make [local] test` (this runs formatting, linting, security checks, and tests)
4. **Create your PR** and get kudos! :)
## Make Commands
- Use `make [local] <command>` for local development (runs in Docker container)
- Use `make <command>` for CI/CD environments
- Common commands:
- `make [local] vendor` - Install dependencies
- `make [local] test` - Run all checks and tests
- `make [local] build` - Build the yq binary
- `make [local] format` - Format code
- `make [local] check` - Run linting and security checks
# Code Quality
## Linting and Formatting
The project uses strict linting rules defined in `.golangci.yml`. All code must pass:
- **Code formatting**: gofmt, goimports, gci
- **Linting**: revive, errorlint, gosec, misspell, and others
- **Security checks**: gosec security analysis
- **Spelling checks**: misspell detection
Run `make [local] check` to verify your code meets all quality standards.
## Code Style Guidelines
- Follow standard Go conventions
- Use meaningful variable names
- Add comments for public functions and complex logic
- Keep functions focused and reasonably sized
- Use the project's existing patterns and conventions
# Testing
## Test Structure
Tests in yq use the `expressionScenario` pattern. Each test scenario includes:
- `expression`: The yq expression to test
- `document`: Input YAML/JSON (optional)
- `expected`: Expected output
- `skipDoc`: Whether to skip documentation generation
## Writing Tests
1. **Find the appropriate test file** (e.g., `operator_add_test.go` for addition operations)
2. **Add your test scenario** to the `*OperatorScenarios` slice
3. **Run the specific test**: `go test -run TestAddOperatorScenarios` (replace with appropriate test name)
4. **Verify documentation generation** (see Documentation section)
## Test Examples
```go
var addOperatorScenarios = []expressionScenario{
{
skipDoc: true,
expression: `"foo" + "bar"`,
expected: []string{
"D0, P[], (!!str)::foobar\n",
},
},
{
document: "apples: 3",
expression: `.apples + 3`,
expected: []string{
"D0, P[apples], (!!int)::6\n",
},
},
}
```
## Running Tests
- **All tests**: `make [local] test`
- **Specific test**: `go test -run TestName`
- **With coverage**: `make [local] cover`
# Documentation
## Documentation Generation
The project uses a documentation system that combines static headers with dynamically generated content from tests.
### How It Works
1. **Static headers** are defined in `pkg/yqlib/doc/operators/headers/*.md`
2. **Dynamic content** is generated from test scenarios in `*_test.go` files
3. **Generated docs** are created in `pkg/yqlib/doc/*.md` by concatenating headers with test-generated content
4. **Documentation is synced** to the gitbook branch for the website
### Updating Operator Documentation
#### For Test-Generated Documentation
Most operator documentation is generated from tests. To update:
1. **Find the test file** (e.g., `operator_add_test.go`)
2. **Update test scenarios** - each `expressionScenario` with `skipDoc: false` becomes documentation
3. **Run the test** to regenerate docs:
```bash
cd pkg/yqlib
go test -run TestAddOperatorScenarios
```
4. **Verify the generated documentation** in `pkg/yqlib/doc/add.md`
5. **Create a PR** with your changes
#### For Header-Only Documentation
If documentation exists only in `headers/*.md` files:
1. **Update the header file directly** (e.g., `pkg/yqlib/doc/operators/headers/add.md`)
2. **Create a PR** with your changes
### Updating Static Documentation
For documentation not in the master branch:
1. **Check the gitbook branch** for additional pages
2. **Update the `*.md` files** directly
3. **Create a PR** to the gitbook branch
### Documentation Best Practices
- **Write clear, concise examples** in test scenarios
- **Use meaningful variable names** in examples
- **Include edge cases** and error conditions
- **Test your documentation changes** by running the specific test
- **Verify generated output** matches expectations
Note: PRs with small changes (e.g. minor typos) may not be merged (see https://joel.net/how-one-guy-ruined-hacktoberfest2020-drama).
# Troubleshooting
## Common Setup Issues
### Docker/Podman Issues
- **Problem**: `make` commands fail with Docker errors
- **Solution**: Ensure Docker or Podman is running and accessible
- **Alternative**: Use `make local <command>` to run in containers
### Go Version Issues
- **Problem**: Build fails with Go version errors
- **Solution**: Ensure you have Go 1.24.0 or later installed
- **Check**: Run `go version` to verify
### Vendor Dependencies
- **Problem**: `make vendor` fails or dependencies are outdated
- **Solution**:
```bash
go mod tidy
make [local] vendor
```
### Linting Failures
- **Problem**: `make check` fails with linting errors
- **Solution**:
```bash
make [local] format # Auto-fix formatting
# Manually fix remaining linting issues
make [local] check # Verify fixes
```
### Test Failures
- **Problem**: Tests fail locally but pass in CI
- **Solution**:
```bash
make [local] test # Run in Docker container
```
- **Problem**: Tests fail with a VCS error:
```bash
error obtaining VCS status: exit status 128
Use -buildvcs=false to disable VCS stamping.
```
- **Solution**:
Git security mechanisms prevent Golang from detecting the Git details inside
the container; either build with the `local` option, or pass GOFLAGS to
disable Golang buildvcs behaviour.
```bash
make local test
# OR
make test GOFLAGS='-buildvcs=true'
```
### Documentation Generation Issues
- **Problem**: Generated docs don't update after test changes
- **Solution**:
```bash
cd pkg/yqlib
go test -run TestSpecificOperatorScenarios
# Check if generated file updated in pkg/yqlib/doc/
```
## Getting Help
- **Check existing issues**: Search GitHub issues for similar problems
- **Create an issue**: If you can't find a solution, create a detailed issue
- **Ask questions**: Use GitHub Discussions for general questions
- **Join the community**: Check the project's community channels
================================================
FILE: Dockerfile
================================================
FROM golang:1.26.1 AS builder
WORKDIR /go/src/mikefarah/yq
COPY . .
RUN CGO_ENABLED=0 go build -ldflags "-s -w" .
# RUN ./scripts/test.sh -- this too often times out in the github pipeline.
RUN ./scripts/acceptance.sh
# Choose alpine as a base image to make this useful for CI, as many
# CI tools expect an interactive shell inside the container
FROM alpine:3 AS production
LABEL maintainer="Mike Farah <mikefarah@users.noreply.github.com>"
COPY --from=builder /go/src/mikefarah/yq/yq /usr/bin/yq
WORKDIR /workdir
RUN set -eux; \
addgroup -g 1000 yq; \
adduser -u 1000 -G yq -s /bin/sh -h /home/yq -D yq
RUN chown -R yq:yq /workdir
USER yq
ENTRYPOINT ["/usr/bin/yq"]
================================================
FILE: Dockerfile.dev
================================================
FROM golang:1.26.1
RUN apt-get update && \
apt-get install -y npm && \
npm install -g npx cspell@latest
COPY scripts/devtools.sh /opt/devtools.sh
RUN set -e -x && \
/opt/devtools.sh
ENV PATH=/go/bin:$PATH
ENV CGO_ENABLED 0
ENV GOPATH /go:/yq
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2017 Mike Farah
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.
================================================
FILE: Makefile
================================================
MAKEFLAGS += --warn-undefined-variables
SHELL := /bin/bash
.SHELLFLAGS := -o pipefail -euc
.DEFAULT_GOAL := install
ENGINE := $(shell { (podman version > /dev/null 2>&1 && command -v podman) || command -v docker; } 2>/dev/null)
include Makefile.variables
.PHONY: help
help:
@echo 'Management commands for cicdtest:'
@echo
@echo 'Usage:'
@echo ' ## Develop / Test Commands'
@echo ' make build Build yq binary.'
@echo ' make install Install yq.'
@echo ' make xcompile Build cross-compiled binaries of yq.'
@echo ' make vendor Install dependencies to vendor directory.'
@echo ' make format Run code formatter.'
@echo ' make check Run static code analysis (lint).'
@echo ' make secure Run gosec.'
@echo ' make test Run tests on project.'
@echo ' make cover Run tests and capture code coverage metrics on project.'
@echo ' make clean Clean the directory tree of produced artifacts.'
@echo
@echo ' ## Utility Commands'
@echo ' make setup Configures Minishfit/Docker directory mounts.'
@echo
.PHONY: clean
clean:
@rm -rf bin build cover *.out
## prefix before other make targets to run in your local dev environment
local: | quiet
@$(eval ENGINERUN= )
@$(eval GOFLAGS="$(GOFLAGS)" )
@mkdir -p tmp
@touch tmp/dev_image_id
quiet: # this is silly but shuts up 'Nothing to be done for `local`'
@:
prepare: tmp/dev_image_id
tmp/dev_image_id: Dockerfile.dev scripts/devtools.sh
@mkdir -p tmp
@${ENGINE} rmi -f ${DEV_IMAGE} > /dev/null 2>&1 || true
@${ENGINE} build -t ${DEV_IMAGE} -f Dockerfile.dev .
@${ENGINE} inspect -f "{{ .ID }}" ${DEV_IMAGE} > tmp/dev_image_id
# ----------------------------------------------
# build
.PHONY: build
build: build/dev
.PHONY: build/dev
build/dev: test *.go
@mkdir -p bin/
${ENGINERUN} go build --ldflags "$(LDFLAGS)"
${ENGINERUN} bash ./scripts/acceptance.sh
## Compile the project for multiple OS and Architectures.
xcompile: check
@rm -rf build/
@mkdir -p build
${ENGINERUN} bash ./scripts/xcompile.sh
@find build -type d -exec chmod 755 {} \; || :
@find build -type f -exec chmod 755 {} \; || :
.PHONY: install
install: build
${ENGINERUN} go install
# Each of the fetch should be an entry within vendor.json; not currently included within project
.PHONY: vendor
vendor: tmp/dev_image_id
@mkdir -p vendor
${ENGINERUN} go mod vendor
# ----------------------------------------------
# develop and test
.PHONY: format
format: vendor
${ENGINERUN} bash ./scripts/format.sh
.PHONY: spelling
spelling: format
${ENGINERUN} bash ./scripts/spelling.sh
.PHONY: secure
secure: spelling
${ENGINERUN} bash ./scripts/secure.sh
.PHONY: check
check: secure
${ENGINERUN} bash ./scripts/check.sh
.PHONY: test
test: check
${ENGINERUN} bash ./scripts/test.sh
.PHONY: cover
cover: check
@rm -rf cover/
@mkdir -p cover
${ENGINERUN} bash ./scripts/coverage.sh
@find cover -type d -exec chmod 755 {} \; || :
@find cover -type f -exec chmod 644 {} \; || :
.PHONY: release
release: xcompile
${ENGINERUN} bash ./scripts/publish.sh
# ----------------------------------------------
# utilities
.PHONY: setup
setup:
@bash ./scripts/setup.sh
================================================
FILE: Makefile.variables
================================================
export PROJECT = yq
IMPORT_PATH := github.com/mikefarah/${PROJECT}
export GIT_COMMIT = $(shell git rev-parse --short HEAD)
export GIT_DIRTY = $(shell test -n "$$(git status --porcelain)" && echo "+CHANGES" || true)
export GIT_DESCRIBE = $(shell git describe --tags --always)
GOFLAGS :=
LDFLAGS :=
LDFLAGS += -X main.GitCommit=${GIT_COMMIT}${GIT_DIRTY}
LDFLAGS += -X main.GitDescribe=${GIT_DESCRIBE}
LDFLAGS += -w -s
GITHUB_TOKEN ?=
# Windows environment?
CYG_CHECK := $(shell hash cygpath 2>/dev/null && echo 1)
ifeq ($(CYG_CHECK),1)
VBOX_CHECK := $(shell hash VBoxManage 2>/dev/null && echo 1)
# Docker Toolbox (pre-Windows 10)
ifeq ($(VBOX_CHECK),1)
ROOT := /${PROJECT}
else
# Docker Windows
ROOT := $(shell cygpath -m -a "$(shell pwd)")
endif
else
# all non-windows environments
ROOT := $(shell pwd)
# Deliberately use `command -v` instead of `which` to be POSIX compliant
SELINUX := $(shell command -v getenforce >/dev/null 2>&1 && echo :z)
endif
DEV_IMAGE := ${PROJECT}_dev
ENGINERUN := ${ENGINE} run --rm \
-e LDFLAGS="${LDFLAGS}" \
-e GOFLAGS="${GOFLAGS}" \
-e GITHUB_TOKEN="${GITHUB_TOKEN}" \
-v ${ROOT}/vendor:/go/src${SELINUX} \
-v ${ROOT}:/${PROJECT}/src/${IMPORT_PATH}${SELINUX} \
-w /${PROJECT}/src/${IMPORT_PATH} \
${DEV_IMAGE}
================================================
FILE: README.md
================================================
# yq
    
A lightweight and portable command-line YAML, JSON, INI and XML processor. `yq` uses [jq](https://github.com/stedolan/jq) (a popular JSON processor) like syntax but works with yaml files as well as json, kyaml, xml, ini, properties, csv and tsv. It doesn't yet support everything `jq` does - but it does support the most common operations and functions, and more is being added continuously.
yq is written in Go - so you can download a dependency free binary for your platform and you are good to go! If you prefer there are a variety of package managers that can be used as well as Docker and Podman, all listed below.
## Quick Usage Guide
### Basic Operations
**Read a value:**
```bash
yq '.a.b[0].c' file.yaml
```
**Pipe from STDIN:**
```bash
yq '.a.b[0].c' < file.yaml
```
**Update a yaml file in place:**
```bash
yq -i '.a.b[0].c = "cool"' file.yaml
```
**Update using environment variables:**
```bash
NAME=mike yq -i '.a.b[0].c = strenv(NAME)' file.yaml
```
### Advanced Operations
**Merge multiple files:**
```bash
# merge two files
yq -n 'load("file1.yaml") * load("file2.yaml")'
# merge using globs (note: `ea` evaluates all files at once instead of in sequence)
yq ea '. as $item ireduce ({}; . * $item )' path/to/*.yml
```
**Multiple updates to a yaml file:**
```bash
yq -i '
.a.b[0].c = "cool" |
.x.y.z = "foobar" |
.person.name = strenv(NAME)
' file.yaml
```
**Find and update an item in an array:**
```bash
# Note: requires input file - add your file at the end
yq -i '(.[] | select(.name == "foo") | .address) = "12 cat st"' data.yaml
```
**Convert between formats:**
```bash
# Convert JSON to YAML (pretty print)
yq -Poy sample.json
# Convert YAML to JSON
yq -o json file.yaml
# Convert XML to YAML
yq -o yaml file.xml
```
See [recipes](https://mikefarah.gitbook.io/yq/recipes) for more examples and the [documentation](https://mikefarah.gitbook.io/yq/) for more information.
Take a look at the discussions for [common questions](https://github.com/mikefarah/yq/discussions/categories/q-a), and [cool ideas](https://github.com/mikefarah/yq/discussions/categories/show-and-tell)
## Install
### [Download the latest binary](https://github.com/mikefarah/yq/releases/latest)
### wget
Use wget to download pre-compiled binaries. Choose your platform and architecture:
**For Linux (example):**
```bash
# Set your platform variables (adjust as needed)
VERSION=v4.2.0
PLATFORM=linux_amd64
# Download compressed binary
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/yq_${PLATFORM}.tar.gz -O - |\
tar xz && sudo mv yq_${PLATFORM} /usr/local/bin/yq
# Or download plain binary
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/yq_${PLATFORM} -O /usr/local/bin/yq &&\
chmod +x /usr/local/bin/yq
```
**Latest version (Linux AMD64):**
```bash
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq &&\
chmod +x /usr/local/bin/yq
```
**Available platforms:** `linux_amd64`, `linux_arm64`, `linux_arm`, `linux_386`, `darwin_amd64`, `darwin_arm64`, `windows_amd64`, `windows_386`, etc.
### MacOS / Linux via Homebrew:
Using [Homebrew](https://brew.sh/)
```
brew install yq
```
### Linux via snap:
```
snap install yq
```
#### Snap notes
`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 '.a.path'
```
And to write to a root file you can either use [sponge](https://linux.die.net/man/1/sponge):
```
sudo cat /etc/myfile | yq '.a.path = "value"' | sudo sponge /etc/myfile
```
or write to a temporary file:
```
sudo cat /etc/myfile | yq '.a.path = "value"' | sudo tee /etc/myfile.tmp
sudo mv /etc/myfile.tmp /etc/myfile
rm /etc/myfile.tmp
```
### Run with Docker or Podman
#### One-time use:
```bash
# Docker - process files in current directory
docker run --rm -v "${PWD}":/workdir mikefarah/yq '.a.b[0].c' file.yaml
# Podman - same usage as Docker
podman run --rm -v "${PWD}":/workdir mikefarah/yq '.a.b[0].c' file.yaml
```
**Security note:** You can run `yq` in Docker with restricted privileges:
```bash
docker run --rm --security-opt=no-new-privileges --cap-drop all --network none \
-v "${PWD}":/workdir mikefarah/yq '.a.b[0].c' file.yaml
```
#### Pipe data via STDIN:
You'll need to pass the `-i --interactive` flag to Docker/Podman:
```bash
# Process piped data
docker run -i --rm mikefarah/yq '.this.thing' < myfile.yml
# Same with Podman
podman run -i --rm mikefarah/yq '.this.thing' < myfile.yml
```
#### Run commands interactively:
```bash
docker run --rm -it -v "${PWD}":/workdir --entrypoint sh mikefarah/yq
```
```bash
podman run --rm -it -v "${PWD}":/workdir --entrypoint sh mikefarah/yq
```
It can be useful to have a bash function to avoid typing the whole docker command:
```bash
yq() {
docker run --rm -i -v "${PWD}":/workdir mikefarah/yq "$@"
}
```
```bash
yq() {
podman run --rm -i -v "${PWD}":/workdir mikefarah/yq "$@"
}
```
#### Running as root:
`yq`'s container image no longer runs under root (https://github.com/mikefarah/yq/pull/860). If you'd like to install more things in the container image, or you're having permissions issues when attempting to read/write files you'll need to either:
```
docker run --user="root" -it --entrypoint sh mikefarah/yq
```
```
podman run --user="root" -it --entrypoint sh mikefarah/yq
```
Or, in your Dockerfile:
```
FROM mikefarah/yq
USER root
RUN apk add --no-cache bash
USER yq
```
#### Missing timezone data
By default, the alpine image yq uses does not include timezone data. If you'd like to use the `tz` operator, you'll need to include this data:
```
FROM mikefarah/yq
USER root
RUN apk add --no-cache tzdata
USER yq
```
#### Podman with SELinux
If you are using podman with SELinux, you will need to set the shared volume flag `:z` on the volume mount:
```
-v "${PWD}":/workdir:z
```
### GitHub Action
```
- name: Set foobar to cool
uses: mikefarah/yq@master
with:
cmd: yq -i '.foo.bar = "cool"' 'config.yml'
- name: Get an entry with a variable that might contain dots or spaces
id: get_username
uses: mikefarah/yq@master
with:
cmd: yq '.all.children.["${{ matrix.ip_address }}"].username' ops/inventories/production.yml
- name: Reuse a variable obtained in another step
run: echo ${{ steps.get_username.outputs.result }}
```
See https://mikefarah.gitbook.io/yq/usage/github-action for more.
### Go Install:
```
go install github.com/mikefarah/yq/v4@latest
```
## Community Supported Installation methods
As these are supported by the community :heart: - however, they may be out of date with the officially supported releases.
_Please note that the Debian package (previously supported by @rmescandon) is no longer maintained. Please use an alternative installation method._
### X-CMD
Checkout `yq` on x-cmd: https://x-cmd.com/mod/yq
- Instant Results: See the output of your yq filter in real-time.
- Error Handling: Encounter a syntax error? It will display the error message and the results of the closest valid filter
Thanks @edwinjhlee!
### Nix
```
nix profile install nixpkgs#yq-go
```
See [here](https://search.nixos.org/packages?channel=unstable&show=yq-go&from=0&size=50&sort=relevance&type=packages&query=yq-go)
### Webi
```
webi yq
```
See [webi](https://webinstall.dev/)
Supported by @adithyasunil26 (https://github.com/webinstall/webi-installers/tree/master/yq)
### Arch Linux
```
pacman -S go-yq
```
### Windows:
Using [Chocolatey](https://chocolatey.org)
[](https://chocolatey.org/packages/yq)
[](https://chocolatey.org/packages/yq)
```
choco install yq
```
Supported by @chillum (https://chocolatey.org/packages/yq)
Using [scoop](https://scoop.sh/)
```
scoop install main/yq
```
Using [winget](https://learn.microsoft.com/en-us/windows/package-manager/)
```
winget install --id MikeFarah.yq
```
### MacPorts:
Using [MacPorts](https://www.macports.org/)
```
sudo port selfupdate
sudo port install yq
```
Supported by @herbygillot (https://ports.macports.org/maintainer/github/herbygillot)
### Alpine Linux
Alpine Linux v3.20+ (and Edge):
```
apk add yq-go
```
Alpine Linux up to v3.19:
```
apk add yq
```
Supported by Tuan Hoang (https://pkgs.alpinelinux.org/packages?name=yq-go)
### Flox:
Flox can be used to install yq on Linux, MacOS, and Windows through WSL.
```
flox install yq
```
### MacOS / Linux via gah:
Using [gah](https://github.com/marverix/gah)
```
gah install yq
```
## Features
- [Detailed documentation with many examples](https://mikefarah.gitbook.io/yq/)
- Written in portable go, so you can download a lovely dependency free binary
- Uses similar syntax as `jq` but works with YAML, INI, [JSON](https://mikefarah.gitbook.io/yq/usage/convert) and [XML](https://mikefarah.gitbook.io/yq/usage/xml) files
- Fully supports multi document yaml files
- Supports yaml [front matter](https://mikefarah.gitbook.io/yq/usage/front-matter) blocks (e.g. jekyll/assemble)
- Colorized yaml output
- [Date/Time manipulation and formatting with TZ](https://mikefarah.gitbook.io/yq/operators/datetime)
- [Deep data structures](https://mikefarah.gitbook.io/yq/operators/traverse-read)
- [Sort keys](https://mikefarah.gitbook.io/yq/operators/sort-keys)
- Manipulate yaml [comments](https://mikefarah.gitbook.io/yq/operators/comment-operators), [styling](https://mikefarah.gitbook.io/yq/operators/style), [tags](https://mikefarah.gitbook.io/yq/operators/tag) and [anchors and aliases](https://mikefarah.gitbook.io/yq/operators/anchor-and-alias-operators).
- [Update in place](https://mikefarah.gitbook.io/yq/v/v4.x/commands/evaluate#flags)
- [Complex expressions to select and update](https://mikefarah.gitbook.io/yq/operators/select#select-and-update-matching-values-in-map)
- Keeps yaml formatting and comments when updating (though there are issues with whitespace)
- [Decode/Encode base64 data](https://mikefarah.gitbook.io/yq/operators/encode-decode)
- [Load content from other files](https://mikefarah.gitbook.io/yq/operators/load)
- [Convert to/from json/ndjson](https://mikefarah.gitbook.io/yq/v/v4.x/usage/convert)
- [Convert to/from xml](https://mikefarah.gitbook.io/yq/v/v4.x/usage/xml)
- [Convert to/from hcl (terraform)](https://mikefarah.gitbook.io/yq/v/v4.x/usage/hcl)
- [Convert to/from toml](https://mikefarah.gitbook.io/yq/v/v4.x/usage/toml)
- [Convert to/from properties](https://mikefarah.gitbook.io/yq/v/v4.x/usage/properties)
- [Convert to/from csv/tsv](https://mikefarah.gitbook.io/yq/usage/csv-tsv)
- [General shell completion scripts (bash/zsh/fish/powershell)](https://mikefarah.gitbook.io/yq/v/v4.x/commands/shell-completion)
- [Reduce](https://mikefarah.gitbook.io/yq/operators/reduce) to merge multiple files or sum an array or other fancy things.
- [Github Action](https://mikefarah.gitbook.io/yq/usage/github-action) to use in your automated pipeline (thanks @devorbitus)
## [Usage](https://mikefarah.gitbook.io/yq/)
Check out the [documentation](https://mikefarah.gitbook.io/yq/) for more detailed and advanced usage.
```
Usage:
yq [flags]
yq [command]
Examples:
# yq tries to auto-detect the file format based off the extension, and defaults to YAML if it's unknown (or piping through STDIN)
# Use the '-p/--input-format' flag to specify a format type.
cat file.xml | yq -p xml
# read the "stuff" node from "myfile.yml"
yq '.stuff' < myfile.yml
# update myfile.yml in place
yq -i '.stuff = "foo"' myfile.yml
# print contents of sample.json as idiomatic YAML
yq -P -oy sample.json
Available Commands:
completion Generate the autocompletion script for the specified shell
eval (default) Apply the expression to each document in each yaml file in sequence
eval-all Loads _all_ yaml documents of _all_ yaml files and runs expression once
help Help about any command
Flags:
-C, --colors force print with colors
--csv-auto-parse parse CSV YAML/JSON values (default true)
--csv-separator char CSV Separator character (default ,)
--debug-node-info debug node info
-e, --exit-status set exit status if there are no matches or null or false is returned
--expression string forcibly set the expression argument. Useful when yq argument detection thinks your expression is a file.
--from-file string Load expression from specified file.
-f, --front-matter string (extract|process) first input as yaml front-matter. Extract will pull out the yaml content, process will run the expression against the yaml content, leaving the remaining data intact
--header-preprocess Slurp any header comments and separators before processing expression. (default true)
-h, --help help for yq
-I, --indent int sets indent level for output (default 2)
-i, --inplace update the file in place of first file given.
-p, --input-format string [auto|a|yaml|y|json|j|kyaml|ky|props|p|csv|c|tsv|t|xml|x|base64|uri|toml|hcl|h|lua|l|ini|i] parse format for input. (default "auto")
--lua-globals output keys as top-level global variables
--lua-prefix string prefix (default "return ")
--lua-suffix string suffix (default ";\n")
--lua-unquoted output unquoted string keys (e.g. {foo="bar"})
-M, --no-colors force print with no colors
-N, --no-doc Don't print document separators (---)
-0, --nul-output Use NUL char to separate values. If unwrap scalar is also set, fail if unwrapped scalar contains NUL char.
-n, --null-input Don't read input, simply evaluate the expression given. Useful for creating docs from scratch.
-o, --output-format string [auto|a|yaml|y|json|j|kyaml|ky|props|p|csv|c|tsv|t|xml|x|base64|uri|toml|hcl|h|shell|s|lua|l|ini|i] output format type. (default "auto")
-P, --prettyPrint pretty print, shorthand for '... style = ""'
--properties-array-brackets use [x] in array paths (e.g. for SpringBoot)
--properties-separator string separator to use between keys and values (default " = ")
--security-disable-env-ops Disable env related operations.
--security-disable-file-ops Disable file related operations (e.g. load)
--shell-key-separator string separator for shell variable key paths (default "_")
-s, --split-exp string print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter. The necessary directories will be created.
--split-exp-file string Use a file to specify the split-exp expression.
--string-interpolation Toggles strings interpolation of \(exp) (default true)
--tsv-auto-parse parse TSV YAML/JSON values (default true)
-r, --unwrapScalar unwrap scalar, print the value with no quotes, colors or comments. Defaults to true for yaml (default true)
-v, --verbose verbose mode
-V, --version Print version information and quit
--xml-attribute-prefix string prefix for xml attributes (default "+@")
--xml-content-name string name for xml content (if no attribute name is present). (default "+content")
--xml-directive-name string name for xml directives (e.g. <!DOCTYPE thing cat>) (default "+directive")
--xml-keep-namespace enables keeping namespace after parsing attributes (default true)
--xml-proc-inst-prefix string prefix for xml processing instructions (e.g. <?xml version="1"?>) (default "+p_")
--xml-raw-token enables using RawToken method instead Token. Commonly disables namespace translations. See https://pkg.go.dev/encoding/xml#Decoder.RawToken for details. (default true)
--xml-skip-directives skip over directives (e.g. <!DOCTYPE thing cat>)
--xml-skip-proc-inst skip over process instructions (e.g. <?xml version="1"?>)
--xml-strict-mode enables strict parsing of XML. See https://pkg.go.dev/encoding/xml for more details.
--yaml-fix-merge-anchor-to-spec Fix merge anchor to match YAML spec. Will default to true in late 2025
Use "yq [command] --help" for more information about a command.
```
## Troubleshooting
### Common Issues
**PowerShell quoting issues:**
```powershell
# Use single quotes for expressions
yq '.a.b[0].c' file.yaml
# Or escape double quotes
yq ".a.b[0].c = \"value\"" file.yaml
```
### Getting Help
- **Check existing issues**: [GitHub Issues](https://github.com/mikefarah/yq/issues)
- **Ask questions**: [GitHub Discussions](https://github.com/mikefarah/yq/discussions)
- **Documentation**: [Complete documentation](https://mikefarah.gitbook.io/yq/)
- **Examples**: [Recipes and examples](https://mikefarah.gitbook.io/yq/recipes)
## Known Issues / Missing Features
- `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)
- Powershell has its own...[opinions on quoting yq](https://mikefarah.gitbook.io/yq/usage/tips-and-tricks#quotes-in-windows-powershell)
- "yes", "no" were dropped as boolean values in the yaml 1.2 standard - which is the standard yq assumes.
See [tips and tricks](https://mikefarah.gitbook.io/yq/usage/tips-and-tricks) for more common problems and solutions.
================================================
FILE: acceptance_tests/bad_args.sh
================================================
#!/bin/bash
testWriteInPlacePipeIn() {
result=$(./yq e -i -n '.a' 2>&1)
assertEquals 1 $?
assertEquals "Error: write in place flag only applicable when giving an expression and at least one file" "$result"
}
testWriteInPlacePipeInEvalall() {
result=$(./yq ea -i -n '.a' 2>&1)
assertEquals 1 $?
assertEquals "Error: write in place flag only applicable when giving an expression and at least one file" "$result"
}
testWriteInPlaceWithSplit() {
result=$(./yq e -s "cat" -i '.a = "thing"' test.yml 2>&1)
assertEquals 1 $?
assertEquals "Error: write in place cannot be used with split file" "$result"
}
testWriteInPlaceWithSplitEvalAll() {
result=$(./yq ea -s "cat" -i '.a = "thing"' test.yml 2>&1)
assertEquals 1 $?
assertEquals "Error: write in place cannot be used with split file" "$result"
}
testNullWithFiles() {
result=$(./yq e -n '.a = "thing"' test.yml 2>&1)
assertEquals 1 $?
assertEquals "Error: cannot pass files in when using null-input flag" "$result"
}
testNullWithFilesEvalAll() {
result=$(./yq ea -n '.a = "thing"' test.yml 2>&1)
assertEquals 1 $?
assertEquals "Error: cannot pass files in when using null-input flag" "$result"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/basic.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml 2>/dev/null || true
rm .xyz 2>/dev/null || true
rm instructions.txt 2>/dev/null || true
}
testBasicEvalRoundTrip() {
./yq -n ".a = 123" > test.yml
X=$(./yq '.a' test.yml)
assertEquals 123 "$X"
}
testBasicTrailingContent() {
cat >test-trailing.yml <<EOL
test:
# this comment will be removed
EOL
read -r -d '' expected << EOM
test:
# this comment will be removed
EOM
X=$(./yq test-trailing.yml -P)
assertEquals "$expected" "$X"
}
testBasicTrailingContent() {
cat >test-trailing.yml <<EOL
test:
# this comment will be removed
EOL
read -r -d '' expected << EOM
test:
# hi
EOM
X=$(./yq '. footComment = "hi"' test-trailing.yml)
assertEquals "$expected" "$X"
}
testBasicTrailingContentEvalAll() {
cat >test-trailing.yml <<EOL
test:
# this comment will be removed
EOL
read -r -d '' expected << EOM
test:
# this comment will be removed
EOM
X=$(./yq ea test-trailing.yml -P)
assertEquals "$expected" "$X"
}
testBasicTrailingContentEvalAll() {
cat >test-trailing.yml <<EOL
test:
# this comment will be removed
EOL
read -r -d '' expected << EOM
test:
# hi
EOM
X=$(./yq ea '. footComment = "hi"' test-trailing.yml)
assertEquals "$expected" "$X"
}
testBasicPipeWithDot() {
./yq -n ".a = 123" > test.yml
X=$(cat test.yml | ./yq '.')
assertEquals "a: 123" "$X"
}
testBasicExpressionMatchesFileName() {
./yq -n ".xyz = 123" > test.yml
touch .xyz
X=$(./yq --expression '.xyz' test.yml)
assertEquals "123" "$X"
X=$(./yq ea --expression '.xyz' test.yml)
assertEquals "123" "$X"
}
testBasicExpressionFromFile() {
./yq -n ".xyz = 123" > test.yml
echo '.xyz = "meow" | .cool = "frog"' > instructions.txt
X=$(./yq --from-file instructions.txt test.yml -o=j -I=0)
assertEquals '{"xyz":"meow","cool":"frog"}' "$X"
X=$(./yq ea --from-file instructions.txt test.yml -o=j -I=0)
assertEquals '{"xyz":"meow","cool":"frog"}' "$X"
}
testBasicExpressionFromFileDos() {
./yq -n ".xyz = 123" > test.yml
echo '.xyz = "meow" | .cool = "frog"' | sed 's/$'"/`echo \\\r`/" > instructions.txt
X=$(./yq --from-file instructions.txt test.yml -o=j -I=0)
assertEquals '{"xyz":"meow","cool":"frog"}' "$X"
X=$(./yq ea --from-file instructions.txt test.yml -o=j -I=0)
assertEquals '{"xyz":"meow","cool":"frog"}' "$X"
}
testBasicGitHubAction() {
./yq -n ".a = 123" > test.yml
X=$(cat /dev/null | ./yq test.yml)
assertEquals "a: 123" "$X"
X=$(cat /dev/null | ./yq e test.yml)
assertEquals "a: 123" "$X"
X=$(cat /dev/null | ./yq ea test.yml)
assertEquals "a: 123" "$X"
}
testBasicGitHubActionWithExpression() {
./yq -n ".a = 123" > test.yml
X=$(cat /dev/null | ./yq '.a' test.yml)
assertEquals "123" "$X"
X=$(cat /dev/null | ./yq e '.a' test.yml)
assertEquals "123" "$X"
X=$(cat /dev/null | ./yq ea '.a' test.yml)
assertEquals "123" "$X"
}
testBasicEvalAllAllFiles() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(./yq ea test.yml test2.yml)
Y=$(./yq e '.' test.yml test2.yml)
assertEquals "$Y" "$X"
}
# when given a file, don't read STDIN
# otherwise strange things start happening
# in scripts
# https://github.com/mikefarah/yq/issues/1115
testBasicCatWithFilesNoDash() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq test2.yml)
Y=$(./yq e '.' test2.yml)
assertEquals "$Y" "$X"
}
# when the nullinput flag is used
# don't automatically read STDIN (this breaks github actions)
testBasicCreateFileGithubAction() {
cat /dev/null | ./yq -n ".a = 123" > test.yml
}
testBasicEvalAllCatWithFilesNoDash() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq ea test2.yml)
Y=$(./yq e '.' test2.yml)
assertEquals "$Y" "$X"
}
testBasicCatWithFilesNoDashWithExp() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq '.a' test2.yml)
Y=$(./yq e '.a' test2.yml)
assertEquals "$Y" "$X"
}
testBasicEvalAllCatWithFilesNoDashWithExp() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq ea '.a' test2.yml)
Y=$(./yq e '.a' test2.yml)
assertEquals "$Y" "$X"
}
testBasicStdInWithFiles() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq - test2.yml)
Y=$(./yq e '.' test.yml test2.yml)
assertEquals "$Y" "$X"
}
testBasicEvalAllStdInWithFiles() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq ea - test2.yml)
Y=$(./yq e '.' test.yml test2.yml)
assertEquals "$Y" "$X"
}
testBasicStdInWithFilesReverse() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq test2.yml -)
Y=$(./yq e '.' test2.yml test.yml)
assertEquals "$Y" "$X"
}
testBasicEvalAllStdInWithFilesReverse() {
./yq -n ".a = 123" > test.yml
./yq -n ".a = 124" > test2.yml
X=$(cat test.yml | ./yq ea test2.yml -)
Y=$(./yq e '.' test2.yml test.yml)
assertEquals "$Y" "$X"
}
testBasicEvalRoundTripNoEval() {
./yq -n ".a = 123" > test.yml
X=$(./yq '.a' test.yml)
assertEquals 123 "$X"
}
testBasicStdInWithOneArg() {
./yq e -n ".a = 123" > test.yml
X=$(cat test.yml | ./yq e ".a")
assertEquals 123 "$X"
X=$(cat test.yml | ./yq ea ".a")
assertEquals 123 "$X"
X=$(cat test.yml | ./yq ".a")
assertEquals 123 "$X"
}
testBasicUpdateInPlaceSequence() {
cat >test.yml <<EOL
a: 0
EOL
./yq e -i ".a = 10" test.yml
X=$(./yq e '.a' test.yml)
assertEquals "10" "$X"
}
testBasicUpdateInPlaceSequenceNoEval() {
cat >test.yml <<EOL
a: 0
EOL
./yq -i ".a = 10" test.yml
X=$(./yq '.a' test.yml)
assertEquals "10" "$X"
}
testBasicUpdateInPlaceSequenceEvalAll() {
cat >test.yml <<EOL
a: 0
EOL
./yq ea -i ".a = 10" test.yml
X=$(./yq e '.a' test.yml)
assertEquals "10" "$X"
}
testBasicUpdateInPlaceMultipleFilesNoExpressionEval() {
cat >test.yml <<EOL
a: 0
EOL
cat >test2.yml <<EOL
a: 1
EOL
read -r -d '' expected << EOM
0
---
1
EOM
./yq -i test.yml test2.yml
X=$(./yq e '.a' test.yml)
assertEquals "$expected" "$X"
}
testBasicUpdateInPlaceMultipleFilesNoExpressionEvalAll() {
cat >test.yml <<EOL
a: 0
EOL
cat >test2.yml <<EOL
a: 1
EOL
read -r -d '' expected << EOM
0
---
1
EOM
./yq -i ea test.yml test2.yml
X=$(./yq e '.a' test.yml)
assertEquals "$expected" "$X"
}
testBasicNoExitStatus() {
echo "a: cat" > test.yml
X=$(./yq e '.z' test.yml)
assertEquals "null" "$X"
}
testBasicExitStatus() {
echo "a: cat" > test.yml
X=$(./yq e -e '.z' test.yml 2&>/dev/null)
assertEquals 1 "$?"
}
testBasicExitStatusNoEval() {
echo "a: cat" > test.yml
X=$(./yq -e '.z' test.yml 2&>/dev/null)
assertEquals 1 "$?"
}
testBasicExtractFieldWithSeparator() {
cat >test.yml <<EOL
---
name: chart-name
version: 1.2.3
EOL
X=$(./yq e '.name' test.yml)
assertEquals "chart-name" "$X"
}
testBasicExtractMultipleFieldWithSeparator() {
cat >test.yml <<EOL
---
name: chart-name
version: 1.2.3
---
name: thing
version: 1.2.3
EOL
read -r -d '' expected << EOM
chart-name
---
thing
EOM
X=$(./yq e '.name' test.yml)
assertEquals "$expected" "$X"
}
testBasicMultiplyAssignMultiDoc() {
cat >test.yml <<EOL
a: 1
---
b: 2
EOL
read -r -d '' expected << EOM
a: 1
c: 3
---
b: 2
c: 3
EOM
X=$(./yq '. *= {"c":3}' test.yml)
assertEquals "$expected" "$X"
}
testBasicClosedStdIn() {
cat >test.yml <<EOL
a: 1
EOL
X=$(./yq e '.a' test.yml <&-)
assertEquals "1" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/completion.sh
================================================
#!/bin/bash
testCompletionRuns() {
result=$(./yq __complete "" 2>&1)
assertEquals 0 $?
assertContains "$result" "Completion ended with directive:"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/empty.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
cat >test.yml <<EOL
# comment
EOL
}
testEmptyEval() {
X=$(./yq e test.yml)
expected="# comment"
assertEquals 0 $?
assertEquals "$expected" "$X"
}
testEmptyEvalNoNewLine() {
echo -n "#comment" >test.yml
X=$(./yq e test.yml)
expected=$(cat test.yml)
assertEquals 0 $?
assertEquals "$expected" "$X"
}
testEmptyEvalNoNewLineWithExpression() {
echo -n "# comment" >test.yml
X=$(./yq e '.apple = "tree"' test.yml)
read -r -d '' expected << EOM
# comment
apple: tree
EOM
assertEquals "$expected" "$X"
}
testEmptyEvalPipe() {
X=$(./yq e - < test.yml)
assertEquals 0 $?
}
testEmptyCommentsWithExpressionEval() {
read -r -d '' expected << EOM
# comment
apple: tree
EOM
X=$(./yq e '.apple="tree"' test.yml)
assertEquals "$expected" "$X"
}
testEmptyCommentsWithExpressionEvalAll() {
read -r -d '' expected << EOM
# comment
apple: tree
EOM
X=$(./yq ea '.apple="tree"' test.yml)
assertEquals "$expected" "$X"
}
testEmptyWithExpressionEval() {
rm test.yml
touch test.yml
expected="apple: tree"
X=$(./yq e '.apple="tree"' test.yml)
assertEquals "$expected" "$X"
}
testEmptyWithExpressionEvalAll() {
rm test.yml
touch test.yml
expected="apple: tree"
X=$(./yq ea '.apple="tree"' test.yml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/flags.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
cat >test.yml <<EOL
# comment
EOL
}
testStringInterpolation() {
X=$(./yq -n '"Mike \(3 + 4)"')
assertEquals "Mike 7" "$X"
}
testNoStringInterpolation() {
X=$(./yq --string-interpolation=f -n '"Mike \(3 + 4)"')
assertEquals "Mike \(3 + 4)" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/front-matter.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
cat >test.yml <<EOL
---
a: apple
b: cat
---
not yaml
c: at
EOL
}
testFrontMatterProcessEval() {
read -r -d '' expected << EOM
---
a: apple
b: dog
---
not yaml
c: at
EOM
./yq e --front-matter="process" '.b = "dog"' test.yml -i
assertEquals "$expected" "$(cat test.yml)"
}
testFrontMatterProcessEvalAll() {
read -r -d '' expected << EOM
---
a: apple
b: dog
---
not yaml
c: at
EOM
./yq ea --front-matter="process" '.b = "dog"' test.yml -i
assertEquals "$expected" "$(cat test.yml)"
}
testFrontMatterExtractEval() {
cat >test.yml <<EOL
a: apple
b: cat
---
not yaml
c: at
EOL
read -r -d '' expected << EOM
a: apple
b: dog
EOM
./yq e --front-matter="extract" '.b = "dog"' test.yml -i
assertEquals "$expected" "$(cat test.yml)"
}
testFrontMatterExtractEvalAll() {
cat >test.yml <<EOL
a: apple
b: cat
---
not yaml
c: at
EOL
read -r -d '' expected << EOM
a: apple
b: dog
EOM
./yq ea --front-matter="extract" '.b = "dog"' test.yml -i
assertEquals "$expected" "$(cat test.yml)"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/header-processing-off.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
}
testLineCountFirstLineComment() {
cat >test.yml <<EOL
#test123
abc: 123
test123: 123123
#comment
lalilu: lalilu
EOL
X=$(./yq '.lalilu | line' --header-preprocess=false < test.yml)
assertEquals "5" "$X"
}
testArrayOfDocs() {
cat >test.yml <<EOL
---
# leading comment doc 1
a: 1
---
# leading comment doc 2
a: 2
EOL
read -r -d '' expected << EOM
- # leading comment doc 1
a: 1
- # leading comment doc 2
a: 2
EOM
X=$(./yq ea '[.]' --header-preprocess=false < test.yml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/inputs-format-auto.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml 2>/dev/null || true
rm test*.toml 2>/dev/null || true
rm test*.tfstate 2>/dev/null || true
rm test*.json 2>/dev/null || true
rm test*.properties 2>/dev/null || true
rm test*.csv 2>/dev/null || true
rm test*.tsv 2>/dev/null || true
rm test*.xml 2>/dev/null || true
}
testInputJson() {
cat >test.json <<EOL
{ "mike" : { "things": "cool" } }
EOL
read -r -d '' expected << EOM
{
"mike": {
"things": "cool"
}
}
EOM
X=$(./yq test.json)
assertEquals "$expected" "$X"
X=$(./yq ea test.json)
assertEquals "$expected" "$X"
}
testInputToml() {
cat >test.toml <<EOL
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00
EOL
read -r -d '' expected << EOM
owner:
name: Tom Preston-Werner
dob: 1979-05-27T07:32:00-08:00
EOM
X=$(./yq -oy test.toml)
assertEquals "$expected" "$X"
X=$(./yq ea -oy test.toml)
assertEquals "$expected" "$X"
}
testInputTfstate() {
cat >test.tfstate <<EOL
{ "mike" : { "things": "cool" } }
EOL
read -r -d '' expected << EOM
{"mike": {"things": "cool"}}
EOM
X=$(./yq test.tfstate)
assertEquals "$expected" "$X"
X=$(./yq ea test.tfstate)
assertEquals "$expected" "$X"
}
testInputJsonOutputYaml() {
cat >test.json <<EOL
{ "mike" : { "things": "cool" } }
EOL
read -r -d '' expected << EOM
mike:
things: cool
EOM
X=$(./yq test.json -oy)
assertEquals "$expected" "$X"
X=$(./yq ea test.json -oy)
assertEquals "$expected" "$X"
}
testInputProperties() {
cat >test.properties <<EOL
mike.things = hello
EOL
read -r -d '' expected << EOM
mike.things = hello
EOM
X=$(./yq e test.properties)
assertEquals "$expected" "$X"
X=$(./yq test.properties)
assertEquals "$expected" "$X"
X=$(./yq ea test.properties)
assertEquals "$expected" "$X"
}
testInputPropertiesGitHubAction() {
cat >test.properties <<EOL
mike.things = hello
EOL
read -r -d '' expected << EOM
mike.things = hello
EOM
X=$(cat /dev/null | ./yq e test.properties)
assertEquals "$expected" "$X"
X=$(cat /dev/null | ./yq ea test.properties)
assertEquals "$expected" "$X"
}
testInputCSV() {
cat >test.csv <<EOL
fruit,yumLevel
apple,5
banana,4
EOL
read -r -d '' expected << EOM
fruit,yumLevel
apple,5
banana,4
EOM
X=$(./yq e test.csv)
assertEquals "$expected" "$X"
X=$(./yq ea test.csv)
assertEquals "$expected" "$X"
}
testInputCSVUTF8() {
read -r -d '' expected << EOM
id,first,last
1,john,smith
1,jane,smith
EOM
X=$(./yq utf8.csv)
assertEquals "$expected" "$X"
}
testInputTSV() {
cat >test.tsv <<EOL
fruit yumLevel
apple 5
banana 4
EOL
read -r -d '' expected << EOM
fruit yumLevel
apple 5
banana 4
EOM
X=$(./yq e test.tsv)
assertEquals "$expected" "$X"
X=$(./yq ea test.tsv)
assertEquals "$expected" "$X"
}
testInputXml() {
cat >test.xml <<EOL
<cat legs="4">BiBi</cat>
EOL
read -r -d '' expected << EOM
<cat legs="4">BiBi</cat>
EOM
X=$(./yq e test.xml)
assertEquals "$expected" "$X"
X=$(./yq ea test.xml)
assertEquals "$expected" "$X"
}
testInputXmlNamespaces() {
cat >test.xml <<EOL
<?xml version="1.0"?>
<map xmlns="some-namespace" xmlns:xsi="some-instance" xsi:schemaLocation="some-url">
</map>
EOL
read -r -d '' expected << EOM
<?xml version="1.0"?>
<map xmlns="some-namespace" xmlns:xsi="some-instance" xsi:schemaLocation="some-url"></map>
EOM
X=$(./yq e test.xml)
assertEquals "$expected" "$X"
X=$(./yq ea test.xml)
assertEquals "$expected" "$X"
}
testInputXmlStrict() {
cat >test.xml <<EOL
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY writer "Catherine.">
<!ENTITY copyright "(r) Great">
]>
<root>
<item>&writer;©right;</item>
</root>
EOL
X=$(./yq --xml-strict-mode test.xml 2>&1)
assertEquals 1 $?
assertEquals "Error: bad file 'test.xml': XML syntax error on line 7: invalid character entity &writer;" "$X"
X=$(./yq ea --xml-strict-mode test.xml 2>&1)
assertEquals "Error: bad file 'test.xml': XML syntax error on line 7: invalid character entity &writer;" "$X"
}
testInputXmlGithubAction() {
cat >test.xml <<EOL
<cat legs="4">BiBi</cat>
EOL
read -r -d '' expected << EOM
<cat legs="4">BiBi</cat>
EOM
X=$(cat /dev/null | ./yq e test.xml)
assertEquals "$expected" "$X"
X=$(cat /dev/null | ./yq ea test.xml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/inputs-format.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml 2>/dev/null || true
rm test*.properties 2>/dev/null || true
rm test*.csv 2>/dev/null || true
rm test*.tsv 2>/dev/null || true
rm test*.xml 2>/dev/null || true
rm test*.tf 2>/dev/null || true
}
testInputProperties() {
cat >test.properties <<EOL
mike.things = hello
EOL
read -r -d '' expected << EOM
mike:
things: hello
EOM
X=$(./yq e -p=props test.properties)
assertEquals "$expected" "$X"
X=$(./yq ea -p=props test.properties)
assertEquals "$expected" "$X"
}
testInputPropertiesGitHubAction() {
cat >test.properties <<EOL
mike.things = hello
EOL
read -r -d '' expected << EOM
mike:
things: hello
EOM
X=$(cat /dev/null | ./yq e -p=props test.properties)
assertEquals "$expected" "$X"
X=$(cat /dev/null | ./yq ea -p=props test.properties)
assertEquals "$expected" "$X"
}
testInputCSV() {
cat >test.csv <<EOL
fruit,yumLevel
apple,5
banana,4
EOL
read -r -d '' expected << EOM
- fruit: apple
yumLevel: 5
- fruit: banana
yumLevel: 4
EOM
X=$(./yq e -p=csv test.csv)
assertEquals "$expected" "$X"
X=$(./yq ea -p=csv test.csv)
assertEquals "$expected" "$X"
}
testInputCSVCustomSeparator() {
cat >test.csv <<EOL
fruit;yumLevel
apple;5
banana;4
EOL
read -r -d '' expected << EOM
- fruit: apple
yumLevel: 5
- fruit: banana
yumLevel: 4
EOM
X=$(./yq -p=csv --csv-separator ";" test.csv)
assertEquals "$expected" "$X"
X=$(./yq ea -p=csv --csv-separator ";" test.csv)
assertEquals "$expected" "$X"
}
testInputCSVNoAuto() {
cat >test.csv <<EOL
thing1
name: cat
EOL
read -r -d '' expected << EOM
- thing1: 'name: cat'
EOM
X=$(./yq --csv-auto-parse=f test.csv -oy)
assertEquals "$expected" "$X"
X=$(./yq ea --csv-auto-parse=f test.csv -oy)
assertEquals "$expected" "$X"
}
testInputTSVNoAuto() {
cat >test.tsv <<EOL
thing1
name: cat
EOL
read -r -d '' expected << EOM
- thing1: 'name: cat'
EOM
X=$(./yq --tsv-auto-parse=f test.tsv -oy)
assertEquals "$expected" "$X"
X=$(./yq ea --tsv-auto-parse=f test.tsv -oy)
assertEquals "$expected" "$X"
}
testInputCSVUTF8() {
read -r -d '' expected << EOM
- id: 1
first: john
last: smith
- id: 1
first: jane
last: smith
EOM
X=$(./yq -p=csv utf8.csv)
assertEquals "$expected" "$X"
}
testInputTSV() {
cat >test.tsv <<EOL
fruit yumLevel
apple 5
banana 4
EOL
read -r -d '' expected << EOM
- fruit: apple
yumLevel: 5
- fruit: banana
yumLevel: 4
EOM
X=$(./yq e -p=t test.tsv)
assertEquals "$expected" "$X"
X=$(./yq ea -p=t test.tsv)
assertEquals "$expected" "$X"
}
testInputKYaml() {
cat >test.kyaml <<'EOL'
# leading
{
a: 1, # a line
# head b
b: 2,
c: [
# head d
"d", # d line
],
}
EOL
read -r -d '' expected <<'EOM'
# leading
a: 1 # a line
# head b
b: 2
c:
# head d
- d # d line
EOM
X=$(./yq e -p=kyaml -P test.kyaml)
assertEquals "$expected" "$X"
X=$(./yq ea -p=kyaml -P test.kyaml)
assertEquals "$expected" "$X"
}
testInputXml() {
cat >test.yml <<EOL
<cat legs="4">BiBi</cat>
EOL
read -r -d '' expected << EOM
cat:
+content: BiBi
+@legs: "4"
EOM
X=$(./yq e -p=xml test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -p=xml test.yml)
assertEquals "$expected" "$X"
}
testInputXmlNamespaces() {
cat >test.xml <<EOL
<?xml version="1.0"?>
<map xmlns="some-namespace" xmlns:xsi="some-instance" xsi:schemaLocation="some-url">
</map>
EOL
read -r -d '' expected << EOM
+p_xml: version="1.0"
map:
+@xmlns: some-namespace
+@xmlns:xsi: some-instance
+@xsi:schemaLocation: some-url
EOM
X=$(./yq e -p=xml test.xml)
assertEquals "$expected" "$X"
X=$(./yq ea -p=xml test.xml)
assertEquals "$expected" "$X"
}
testInputXmlRoundtrip() {
cat >test.yml <<EOL
<?xml version="1.0"?>
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
<map xmlns="some-namespace" xmlns:xsi="some-instance" xsi:schemaLocation="some-url">Meow</map>
EOL
read -r -d '' expected << EOM
<?xml version="1.0"?>
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
<map xmlns="some-namespace" xmlns:xsi="some-instance" xsi:schemaLocation="some-url">Meow</map>
EOM
X=$(./yq -p=xml -o=xml test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -p=xml -o=xml test.yml)
assertEquals "$expected" "$X"
}
testInputXmlStrict() {
cat >test.yml <<EOL
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY writer "Catherine.">
<!ENTITY copyright "(r) Great">
]>
<root>
<item>&writer;©right;</item>
</root>
EOL
X=$(./yq -p=xml --xml-strict-mode test.yml -o=xml 2>&1)
assertEquals 1 $?
assertEquals "Error: bad file 'test.yml': XML syntax error on line 7: invalid character entity &writer;" "$X"
X=$(./yq ea -p=xml --xml-strict-mode test.yml -o=xml 2>&1)
assertEquals "Error: bad file 'test.yml': XML syntax error on line 7: invalid character entity &writer;" "$X"
}
testInputXmlGithubAction() {
cat >test.yml <<EOL
<cat legs="4">BiBi</cat>
EOL
read -r -d '' expected << EOM
cat:
+content: BiBi
+@legs: "4"
EOM
X=$(cat /dev/null | ./yq e -p=xml test.yml)
assertEquals "$expected" "$X"
X=$(cat /dev/null | ./yq ea -p=xml test.yml)
assertEquals "$expected" "$X"
}
testInputTerraform() {
cat >test.tf <<EOL
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
tags = {
Environment = "Dev"
Project = "Test"
}
}
EOL
read -r -d '' expected << EOM
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
tags = {
Environment = "Dev"
Project = "Test"
}
}
EOM
X=$(./yq test.tf)
assertEquals "$expected" "$X"
X=$(./yq ea test.tf)
assertEquals "$expected" "$X"
}
testInputTerraformGithubAction() {
cat >test.tf <<EOL
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
tags = {
Environment = "Dev"
Project = "Test"
}
}
EOL
read -r -d '' expected << EOM
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
tags = {
Environment = "Dev"
Project = "Test"
}
}
EOM
X=$(cat /dev/null | ./yq test.tf)
assertEquals "$expected" "$X"
X=$(cat /dev/null | ./yq ea test.tf)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/leading-separator.sh
================================================
#!/bin/bash
# examples where header-preprocess is required
setUp() {
rm test*.yml || true
cat >test.yml <<EOL
---
a: test
EOL
}
testLeadingSeparatorWithDoc() {
cat >test.yml <<EOL
# hi peeps
# cool
---
a: test
---
b: cool
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
---
a: thing
---
b: cool
EOM
X=$(./yq e '(select(di == 0) | .a) = "thing"' - < test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorWithNewlinesNewDoc() {
cat >test.yml <<EOL
# hi peeps
# cool
---
a: test
---
b: cool
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
---
a: thing
---
b: cool
EOM
X=$(./yq e '(select(di == 0) | .a) = "thing"' - < test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorWithNewlinesMoreComments() {
cat >test.yml <<EOL
# hi peeps
# cool
---
# great
a: test
---
b: cool
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
---
# great
a: thing
---
b: cool
EOM
X=$(./yq e '(select(di == 0) | .a) = "thing"' - < test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorWithDirective() {
cat >test.yml <<EOL
%YAML 1.1
---
this: should really work
EOL
read -r -d '' expected << EOM
%YAML 1.1
---
this: should really work
EOM
X=$(./yq < test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorPipeIntoEvalSeq() {
X=$(./yq e - < test.yml)
expected=$(cat test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorExtractField() {
X=$(./yq e '.a' - < test.yml)
assertEquals "test" "$X"
}
testLeadingSeparatorExtractFieldWithCommentsAfterSep() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
EOL
X=$(./yq e '.a' test.yml)
assertEquals "test" "$X"
}
testLeadingSeparatorExtractFieldWithCommentsBeforeSep() {
cat >test.yml <<EOL
# hi peeps
# cool
---
a: test
EOL
X=$(./yq e '.a' test.yml)
assertEquals "test" "$X"
}
testLeadingSeparatorExtractFieldMultiDoc() {
cat >test.yml <<EOL
---
a: test
---
a: test2
EOL
read -r -d '' expected << EOM
test
---
test2
EOM
X=$(./yq e '.a' test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorExtractFieldMultiDocWithComments() {
cat >test.yml <<EOL
# here
---
# there
a: test
# wherever
---
# you are
a: test2
# woop
EOL
read -r -d '' expected << EOM
test
---
test2
EOM
X=$(./yq e '.a' test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorEvalSeq() {
X=$(./yq e test.yml)
expected=$(cat test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorPipeIntoEvalAll() {
X=$(./yq ea - < test.yml)
expected=$(cat test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorEvalAll() {
X=$(./yq ea test.yml)
expected=$(cat test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalSimple() {
read -r -d '' expected << EOM
---
a: test
---
version: 3
application: MyApp
EOM
X=$(./yq e '.' test.yml examples/order.yaml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocInOneFile() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
---
b: things
EOL
expected=$(cat test.yml)
X=$(./yq e '.' test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocInOneFileEvalAll() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
---
b: things
EOL
expected=$(cat test.yml)
X=$(./yq ea '.' test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalComments() {
cat >test.yml <<EOL
# hi peeps
# cool
a: test
EOL
cat >test2.yml <<EOL
# this is another doc
# great
b: sane
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
a: test
---
# this is another doc
# great
b: sane
EOM
X=$(./yq e '.' test.yml test2.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalCommentsTrailingSep() {
cat >test.yml <<EOL
# hi peeps
# cool
---
a: test
EOL
cat >test2.yml <<EOL
# this is another doc
# great
---
b: sane
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
---
a: test
---
# this is another doc
# great
---
b: sane
EOM
X=$(./yq e '.' test.yml test2.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiMultiDocEvalCommentsTrailingSep() {
cat >test.yml <<EOL
# hi peeps
# cool
---
a: test
---
a1: test2
EOL
cat >test2.yml <<EOL
# this is another doc
# great
---
b: sane
---
b2: cool
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
---
a: test
---
a1: test2
---
# this is another doc
# great
---
b: sane
---
b2: cool
EOM
X=$(./yq e '.' test.yml test2.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalCommentsLeadingSep() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
EOL
cat >test2.yml <<EOL
---
# this is another doc
# great
b: sane
EOL
read -r -d '' expected << EOM
---
# hi peeps
# cool
a: test
---
# this is another doc
# great
b: sane
EOM
X=$(./yq e '.' test.yml test2.yml)
assertEquals "$expected" "$X"
}
# https://github.com/mikefarah/yq/issues/919
testLeadingSeparatorDoesNotBreakCommentsOnOtherFiles() {
cat >test.yml <<EOL
# a1
a: 1
# a2
EOL
cat >test2.yml <<EOL
# b1
b: 2
# b2
EOL
read -r -d '' expected << EOM
# a1
a: 1
# a2
# b1
b: 2
# b2
EOM
X=$(./yq ea 'select(fi == 0) * select(fi == 1)' test.yml test2.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalCommentsStripComments() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
---
# this is another doc
# great
b: sane
EOL
# it will be hard to remove that top level separator
read -r -d '' expected << EOM
a: test
---
b: sane
EOM
X=$(./yq e '... comments=""' test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalCommentsLeadingSepNoDocFlag() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
---
# this is another doc
# great
b: sane
EOL
read -r -d '' expected << EOM
# hi peeps
# cool
a: test
# this is another doc
# great
b: sane
EOM
X=$(./yq e '.' --no-doc test.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalJsonFlag() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
EOL
cat >test2.yml <<EOL
---
# this is another doc
# great
b: sane
EOL
read -r -d '' expected << EOM
{
"a": "test"
}
{
"b": "sane"
}
EOM
X=$(./yq e '.' -j test.yml test2.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalAllJsonFlag() {
cat >test.yml <<EOL
---
# hi peeps
# cool
a: test
EOL
cat >test2.yml <<EOL
---
# this is another doc
# great
b: sane
EOL
read -r -d '' expected << EOM
{
"a": "test"
}
{
"b": "sane"
}
EOM
X=$(./yq ea '.' -j test.yml test2.yml)
assertEquals "$expected" "$X"
}
testLeadingSeparatorMultiDocEvalAll() {
read -r -d '' expected << EOM
---
a: test
---
version: 3
application: MyApp
EOM
X=$(./yq ea '.' test.yml examples/order.yaml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/load-file.sh
================================================
#!/bin/bash
testLoadFileNotExist() {
result=$(./yq e -n 'load("cat.yml")' 2>&1)
assertEquals 1 $?
assertEquals "Error: failed to load cat.yml: open cat.yml: no such file or directory" "$result"
}
testLoadFileExpNotExist() {
result=$(./yq e -n 'load(.a)' 2>&1)
assertEquals 1 $?
assertEquals "Error: filename expression returned nil" "$result"
}
testStrLoadFileNotExist() {
result=$(./yq e -n 'strload("cat.yml")' 2>&1)
assertEquals 1 $?
assertEquals "Error: failed to load cat.yml: open cat.yml: no such file or directory" "$result"
}
testStrLoadFileExpNotExist() {
result=$(./yq e -n 'strload(.a)' 2>&1)
assertEquals 1 $?
assertEquals "Error: filename expression returned nil" "$result"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/nul-separator.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
}
## Convenient bash shortcut to read records of NUL separated values
## from stdin the safe way. See example usage in the next tests.
read-0() {
local eof="" IFS=''
while [ "$1" ]; do
## - The `-r` avoids bad surprise with '\n' and other interpreted
## sequences that can be read.
## - The `-d ''` is the (strange?) way to refer to NUL delimiter.
## - The `--` is how to avoid unpleasant surprises if your
## "$1" starts with "-" (minus) sign. This protection also
## will produce a readable error if you want to try to start
## your variable names with a "-".
read -r -d '' -- "$1" || eof=1
shift
done
[ -z "$eof" ] ## fail on EOF
}
## Convenient bash shortcut to be used with the next function `p-err`
## to read NUL separated values the safe way AND catch any errors from
## the process creating the stream of NUL separated data. See example
## usage in the tests.
read-0-err() {
local ret="$1" eof="" idx=0 last=
read -r -- "${ret?}" <<<"0"
shift
while [ "$1" ]; do
last=$idx
read -r -d '' -- "$1" || {
## Put this last value in ${!ret}
eof="$1"
read -r -- "$ret" <<<"${!eof}"
break
}
((idx++))
shift
done
[ -z "$eof" ] || {
if [ "$last" != 0 ]; then
## Uhoh, we have no idea if the errorlevel of the internal
## command was properly delimited with a NUL char, and
## anyway something went really wrong at least about the
## number of fields separated by NUL char and the one
## expected.
echo "Error: read-0-err couldn't fill all value $ret = '${!ret}', '$eof', '${!eof}'" >&2
read -r -- "$ret" <<<"not-enough-values"
else
if ! [[ "${!ret}" =~ ^[0-9]+$ && "${!ret}" -ge 0 && "${!ret}" -le 127 ]]; then
## This could happen if you don't use `p-err` wrapper,
## or used stdout in unexpected ways in your inner
## command.
echo "Error: last value is not a number, did you finish with an errorlevel ?" >&2
read -r -- "$ret" <<<"last-value-not-a-number"
fi
fi
false
}
}
## Simply runs command given as argument and adds errorlevel in the
## standard output. Is expected to be used in tandem with
## `read-0-err`.
p-err() {
local exp="$1"
"$@"
printf "%s" "$?"
}
wyq-r() {
local exp="$1"
./yq e -0 -r=false "$1"
printf "%s" "$?"
}
testBasicUsageRaw() {
cat >test.yml <<EOL
a: foo
b: bar
EOL
printf "foo\0bar\0" > expected.out
## We need to compare binary content here. We have to filter the compared
## content through a representation that gets rid of NUL chars but accurately
## transcribe the content.
## Also as it would be nice to have a pretty output in case the test fails,
## we use here 'hd': a widely available shortcut to 'hexdump' that will
## pretty-print any binary to it's hexadecimal representation.
##
## Note that the standard `assertEquals` compare its arguments
## value, but they can't hold NUL characters (this comes from the
## limitation of the C API of `exec*(..)` functions that requires
## `const char *arv[]`). And these are NUL terminated strings. As a
## consequence, the NUL characters gets removed in bash arguments.
assertEquals "$(hd expected.out)" \
"$(./yq e -0 '.a, .b' test.yml | hd)"
rm expected.out
}
testBasicUsage() {
local a b
cat >test.yml <<EOL
a: foo
b: bar
EOL
## We provide 2 values, and ask to fill 2 variables.
read-0 a b < <(./yq e -0 '.a, .b' test.yml)
assertEquals "$?" "0" ## Everything is fine
assertEquals "foo" "$a" ## Values are correctly parsed
assertEquals "bar" "$b"
a=YYY ; b=XXX
## Not enough values provided to fill `a` and `b`.
read-0 a b < <(./yq e -0 '.a' test.yml)
assertEquals "$?" "1" ## An error was emitted
assertEquals "foo" "$a" ## First value was correctly parsed
assertEquals "" "$b" ## Second was still reset
## Error from inner command are not catchable !. Use
## `read-0-err`/`p-err` for that.
read-0 a < <(printf "\0"; ./yq e -0 'xxx' test.yml; )
assertEquals "$?" "0"
}
testBasicUsageJson() {
cat >test.yml <<EOL
a:
x: foo
b: bar
EOL
read-0 a b < <(./yq e -0 -o=json '.a, .b' test.yml)
assertEquals '{
"x": "foo"
}' "$a"
assertEquals '"bar"' "$b"
}
testFailWithValueContainingNUL() {
local a b c
## Note that value of field 'a' actually contains a NUL char !
cat >test.yml <<EOL
a: "foo\u0000bar"
b: 1
c: |
wiz
boom
EOL
## We are looking for trouble with asking to separated fields with NUL
## char and requested value `.a` actually contains itself a NUL char !
read-0 a b c < <(./yq e -0 '.a, .b, .c' test.yml)
assertNotEquals "0" "$?" ## read-0 failed to fill all values
## But here, we can request for one value, even if `./yq` fails
read-0 b < <(./yq e -0 '.b, .a' test.yml)
assertEquals "0" "$?" ## read-0 succeeds at feeding the first value
## Note: to catch the failure of `yq`, see in the next tests the usage
## of `read-0-err`.
## using -r=false solves any NUL containing value issues, but keeps
## all in YAML representation:
read-0 a b c < <(./yq e -0 -r=false '.a, .b, .c' test.yml)
assertEquals "0" "$?" ## All goes well despite asking for `a` value
assertEquals '"foo\0bar"' "$a" ## This is a YAML string representation
assertEquals '1' "$b"
assertEquals '|
wiz
boom' "$c"
}
testStandardLoop() {
local E a b res
## Here everything is normal: 4 values, that will be paired
## in key/values.
cat >test.yml <<EOL
- yay
- wiz
- hop
- pow
EOL
res=""
while read-0-err E a b; do
res+="$a: $b;"
done < <(p-err ./yq -0 '.[]' test.yml)
assertEquals "0" "$E" ## errorlevel of internal command
assertEquals "yay: wiz;hop: pow;" "$res" ## expected result
}
testStandardLoopWithoutEnoughValues() {
local E a b res
## Here 5 values, there will be a missing value when reading
## pairs of value.
cat >test.yml <<EOL
- yay
- wiz
- hop
- pow
- kwak
EOL
res=""
## The loop will succeed 2 times then fail
while read-0-err E a b; do
res+="$a: $b;"
done < <(p-err ./yq -0 '.[]' test.yml)
assertEquals "not-enough-values" "$E" ## Not enough value error
assertEquals "yay: wiz;hop: pow;" "$res" ## the 2 full key/value pairs
}
testStandardLoopWithInternalCmdError() {
local E a b res
## Note the third value contains a NUL char !
cat >test.yml <<EOL
- yay
- wiz
- "foo\0bar"
- hop
- pow
EOL
res=""
## It should be only upon the second pass in the loop that
## read-0-err will catch the fact that there is an error !
while read-0-err E a b; do
res+="$a: $b;"
done < <(p-err ./yq -0 '.[]' test.yml)
assertEquals "1" "$E" ## Internal command errorlevel (from `./yq`)
assertEquals "yay: wiz;" "$res" ## first 2 values were ok at least
}
testStandardLoopNotEnoughErrorEatsCmdError() {
local E a b res
## Because of possible edge cases where the internal errorlevel
## reported by `p-err` in the standard output might be mangled
## with the unfinished record, `read-0-err E ...` will NOT report
## the internal command error in the variable E and instead will
## store the value 'not-enough-values'. In real world, anyway, you
## will want to react the same if the internal command failed
## and/or you didn't get as much values as expected while
## reading. Keep in mind also that standard error is not
## swallowed, so you can read reports from the inner command AND
## from `read-0-err`.
## Here, note that the fourth value contains a NUL char !
cat >test.yml <<EOL
- yay
- wiz
- hop
- "foo\0bar"
- pow
EOL
res=""
## It should be only upon the second loop that read-0-err will catch
## the fact that there are not enough data to fill the requested variables
while read-0-err E a b; do
res+="$a: $b;"
done < <(p-err ./yq -0 '.[]' test.yml)
assertEquals "not-enough-values" "$E" ## Not enough values error eats internal error !
assertEquals "yay: wiz;" "$res" ## first 2 values were ok at least
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/output-format.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
}
testOutputJsonDeprecated() {
cat >test.yml <<EOL
a: {b: ["cat"]}
EOL
read -r -d '' expected << EOM
{
"a": {
"b": [
"cat"
]
}
}
EOM
X=$(./yq e -j test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -j test.yml)
assertEquals "$expected" "$X"
}
testOutputJson() {
cat >test.yml <<EOL
a: {b: ["cat"]}
EOL
read -r -d '' expected << EOM
{
"a": {
"b": [
"cat"
]
}
}
EOM
X=$(./yq e --output-format=json test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --output-format=json test.yml)
assertEquals "$expected" "$X"
}
testOutputYamlRawDefault() {
cat >test.yml <<EOL
a: "cat"
EOL
X=$(./yq e '.a' test.yml)
assertEquals "cat" "$X"
X=$(./yq ea '.a' test.yml)
assertEquals "cat" "$X"
}
testOutputYamlRawOff() {
cat >test.yml <<EOL
a: "cat"
EOL
X=$(./yq e -r=false '.a' test.yml)
assertEquals "\"cat\"" "$X"
X=$(./yq ea -r=false '.a' test.yml)
assertEquals "\"cat\"" "$X"
}
testOutputYamlRawOnRoot() {
cat >test.yml <<EOL
'a'
EOL
X=$(./yq e -r '.' test.yml)
assertEquals "a" "$X"
}
testOutputJsonRaw() {
cat >test.yml <<EOL
a: cat
EOL
X=$(./yq e -r --output-format=json '.a' test.yml)
assertEquals "cat" "$X"
X=$(./yq ea -r --output-format=json '.a' test.yml)
assertEquals "cat" "$X"
}
testOutputJsonDefault() {
cat >test.yml <<EOL
a: cat
EOL
X=$(./yq e --output-format=json '.a' test.yml)
assertEquals "\"cat\"" "$X"
X=$(./yq ea --output-format=json '.a' test.yml)
assertEquals "\"cat\"" "$X"
}
testOutputJsonShort() {
cat >test.yml <<EOL
a: {b: ["cat"]}
EOL
read -r -d '' expected << EOM
{
"a": {
"b": [
"cat"
]
}
}
EOM
X=$(./yq e -o=j test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -o=j test.yml)
assertEquals "$expected" "$X"
}
testOutputProperties() {
cat >test.yml <<EOL
a: {b: {c: ["cat cat"]}}
EOL
read -r -d '' expected << EOM
a.b.c.0 = cat cat
EOM
X=$(./yq e --output-format=props test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --output-format=props test.yml)
assertEquals "$expected" "$X"
}
testOutputPropertiesDontUnwrap() {
cat >test.yml <<EOL
a: {b: {c: ["cat cat"]}}
EOL
read -r -d '' expected << EOM
a.b.c.0 = "cat cat"
EOM
X=$(./yq e -r=false --output-format=props test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -r=false --output-format=props test.yml)
assertEquals "$expected" "$X"
}
testOutputPropertiesShort() {
cat >test.yml <<EOL
a: {b: {c: ["cat cat"]}}
EOL
read -r -d '' expected << EOM
a.b.c.0 = cat cat
EOM
X=$(./yq e -o=p test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -o=p test.yml)
assertEquals "$expected" "$X"
}
testOutputCSV() {
cat >test.yml <<EOL
- fruit: apple
yumLevel: 5
- fruit: banana
yumLevel: 4
EOL
read -r -d '' expected << EOM
fruit,yumLevel
apple,5
banana,4
EOM
X=$(./yq -o=c test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -o=csv test.yml)
assertEquals "$expected" "$X"
}
testOutputCSVCustomSeparator() {
cat >test.yml <<EOL
- fruit: apple
yumLevel: 5
- fruit: banana
yumLevel: 4
EOL
read -r -d '' expected << EOM
fruit;yumLevel
apple;5
banana;4
EOM
X=$(./yq -oc --csv-separator ";" test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -o=csv --csv-separator ";" test.yml)
assertEquals "$expected" "$X"
}
testOutputTSV() {
cat >test.yml <<EOL
- fruit: apple
yumLevel: 5
- fruit: banana
yumLevel: 4
EOL
read -r -d '' expected << EOM
fruit yumLevel
apple 5
banana 4
EOM
X=$(./yq -o=t test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -o=tsv test.yml)
assertEquals "$expected" "$X"
}
testOutputXml() {
cat >test.yml <<EOL
a: {b: {c: ["cat"]}}
EOL
read -r -d '' expected << EOM
<a>
<b>
<c>cat</c>
</b>
</a>
EOM
X=$(./yq e --output-format=xml test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --output-format=xml test.yml)
assertEquals "$expected" "$X"
}
testOutputXmlShort() {
cat >test.yml <<EOL
a: {b: {c: ["cat"]}}
EOL
read -r -d '' expected << EOM
<a>
<b>
<c>cat</c>
</b>
</a>
EOM
X=$(./yq e --output-format=x test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --output-format=x test.yml)
assertEquals "$expected" "$X"
}
testOutputKYaml() {
cat >test.yml <<'EOL'
# leading
a: 1 # a line
# head b
b: 2
c:
# head d
- d # d line
EOL
read -r -d '' expected <<'EOM'
# leading
{
a: 1, # a line
# head b
b: 2,
c: [
# head d
"d", # d line
],
}
EOM
X=$(./yq e --output-format=kyaml test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --output-format=kyaml test.yml)
assertEquals "$expected" "$X"
}
testOutputKYamlShort() {
cat >test.yml <<EOL
a: b
EOL
read -r -d '' expected <<'EOM'
{
a: "b",
}
EOM
X=$(./yq e -o=ky test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea -o=ky test.yml)
assertEquals "$expected" "$X"
}
testOutputXmComplex() {
cat >test.yml <<EOL
a: {b: {c: ["cat", "dog"], +@f: meow}}
EOL
read -r -d '' expected << EOM
<a>
<b f="meow">
<c>cat</c>
<c>dog</c>
</b>
</a>
EOM
X=$(./yq e --output-format=x test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --output-format=x test.yml)
assertEquals "$expected" "$X"
}
testLuaOutputPretty() {
cat >test.yml <<EOL
animals:
cat: meow
EOL
read -r -d '' expected << EOM
return {
["animals"] = {
["cat"] = "meow";
};
};
EOM
X=$(./yq e --output-format=lua test.yml)
assertEquals "$expected" "$X"
X=$(./yq e --output-format=lua --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testLuaOutputSubset() {
cat >test.yml <<EOL
animals:
cat: meow
EOL
read -r -d '' expected << EOM
return {
["cat"] = "meow";
};
EOM
X=$(./yq e --output-format=lua '.animals' test.yml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/pipe.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
cat >test.yml <<EOL
a: frog
EOL
}
testPipeViaCatWithParam() {
X=$(cat test.yml | ./yq '.a')
assertEquals "frog" "$X"
}
testPipeViaCatWithParamEval() {
X=$(cat test.yml | ./yq e '.a')
assertEquals "frog" "$X"
}
testPipeViaCatWithParamEvalAll() {
X=$(cat test.yml | ./yq ea '.a')
assertEquals "frog" "$X"
}
testPipeViaCatNoParam() {
X=$(cat test.yml | ./yq)
assertEquals "a: frog" "$X"
}
testPipeViaCatNoParamEval() {
X=$(cat test.yml | ./yq e)
assertEquals "a: frog" "$X"
}
testPipeViaCatNoParamEvalAll() {
X=$(cat test.yml | ./yq ea)
assertEquals "a: frog" "$X"
}
testPipeViaFileishWithParam() {
X=$(./yq '.a' < test.yml)
assertEquals "frog" "$X"
}
testPipeViaFileishWithParamEval() {
X=$(./yq e '.a' < test.yml)
assertEquals "frog" "$X"
}
testPipeViaFileishWithParamEvalAll() {
X=$(./yq ea '.a' < test.yml)
assertEquals "frog" "$X"
}
testPipeViaFileishNoParam() {
X=$(./yq < test.yml)
assertEquals "a: frog" "$X"
}
testPipeViaFileishNoParamEval() {
X=$(./yq e < test.yml)
assertEquals "a: frog" "$X"
}
testPipeViaFileishNoParamEvalAll() {
X=$(./yq ea < test.yml)
assertEquals "a: frog" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/pretty-print.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
}
testPrettyPrintWithBooleans() {
cat >test.yml <<EOL
leaveUnquoted: [yes, no, on, off, y, n, true, false]
leaveQuoted: ["yes", "no", "on", "off", "y", "n", "true", "false"]
EOL
read -r -d '' expected << EOM
leaveUnquoted:
- yes
- no
- on
- off
- y
- n
- true
- false
leaveQuoted:
- "yes"
- "no"
- "on"
- "off"
- "y"
- "n"
- "true"
- "false"
EOM
X=$(./yq e --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testPrettyPrintWithBooleansCapitals() {
cat >test.yml <<EOL
leaveUnquoted: [YES, NO, ON, OFF, Y, N, TRUE, FALSE]
leaveQuoted: ["YES", "NO", "ON", "OFF", "Y", "N", "TRUE", "FALSE"]
EOL
read -r -d '' expected << EOM
leaveUnquoted:
- YES
- NO
- ON
- OFF
- Y
- N
- TRUE
- FALSE
leaveQuoted:
- "YES"
- "NO"
- "ON"
- "OFF"
- "Y"
- "N"
- "TRUE"
- "FALSE"
EOM
X=$(./yq e --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testPrettyPrintOtherStringValues() {
cat >test.yml <<EOL
leaveUnquoted: [yesSir, hellno, bonapite]
makeUnquoted: ["yesSir", "hellno", "bonapite"]
EOL
read -r -d '' expected << EOM
leaveUnquoted:
- yesSir
- hellno
- bonapite
makeUnquoted:
- yesSir
- hellno
- bonapite
EOM
X=$(./yq e --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testPrettyPrintKeys() {
cat >test.yml <<EOL
"removeQuotes": "please"
EOL
read -r -d '' expected << EOM
removeQuotes: please
EOM
X=$(./yq e --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testPrettyPrintOtherStringValues() {
cat >test.yml <<EOL
leaveUnquoted: [yesSir, hellno, bonapite]
makeUnquoted: ["yesSir", "hellno", "bonapite"]
EOL
read -r -d '' expected << EOM
leaveUnquoted:
- yesSir
- hellno
- bonapite
makeUnquoted:
- yesSir
- hellno
- bonapite
EOM
X=$(./yq e --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testPrettyPrintStringBlocks() {
cat >test.yml <<EOL
"removeQuotes": |
"please"
EOL
read -r -d '' expected << EOM
removeQuotes: |
"please"
EOM
X=$(./yq e --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
testPrettyPrintWithExpression() {
cat >test.yml <<EOL
a: {b: {c: ["cat"]}}
EOL
read -r -d '' expected << EOM
b:
c:
- cat
EOM
X=$(./yq e '.a' --prettyPrint test.yml)
assertEquals "$expected" "$X"
X=$(./yq ea '.a' --prettyPrint test.yml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/shebang.sh
================================================
#!/bin/bash
setUp() {
rm test*.yq || true
cat >test.yq <<EOL
#!./yq
.a.b
EOL
chmod +x test.yq
rm test*.yml || true
cat >test.yml <<EOL
a: {b: apple}
EOL
}
testCanExecYqFile() {
read -r -d '' expected << EOM
apple
EOM
X=$(./test.yq test.yml)
assertEquals "$expected" "$X"
}
source ./scripts/shunit2
================================================
FILE: acceptance_tests/split-printer.sh
================================================
#!/bin/bash
setUp() {
rm test*.yml || true
rm -rf test_dir* || true
}
testBasicSplitWithName() {
cat >test.yml <<EOL
a: test_doc1
---
a: test_doc2
EOL
./yq e test.yml -s ".a"
doc1=$(cat test_doc1.yml)
assertEquals "a: test_doc1" "$doc1"
doc2=$(cat test_doc2.yml)
read -r -d '' expectedDoc2 << EOM
---
a: test_doc2
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testBasicSplitWithNameCustomExtension() {
rm test*.yaml || true
cat >test.yml <<EOL
a: test_doc1
---
a: test_doc2
EOL
./yq e test.yml -s '.a + ".yaml"'
doc1=$(cat test_doc1.yaml)
assertEquals "a: test_doc1" "$doc1"
doc2=$(cat test_doc2.yaml)
read -r -d '' expectedDoc2 << EOM
---
a: test_doc2
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testSplitFromFile() {
cat >test.yml <<EOL
a: test_doc1
---
a: test_doc2
EOL
cat >test_splitExp.yml <<EOL
.a
EOL
./yq test.yml --split-exp-file test_splitExp.yml
doc1=$(cat test_doc1.yml)
assertEquals "a: test_doc1" "$doc1"
doc2=$(cat test_doc2.yml)
read -r -d '' expectedDoc2 << EOM
---
a: test_doc2
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testBasicSplitWithNameEvalAll() {
cat >test.yml <<EOL
a: test_doc1
---
a: test_doc2
EOL
./yq ea test.yml -s ".a"
doc1=$(cat test_doc1.yml)
assertEquals "a: test_doc1" "$doc1"
doc2=$(cat test_doc2.yml)
read -r -d '' expectedDoc2 << EOM
---
a: test_doc2
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testBasicSplitWithIndex() {
cat >test.yml <<EOL
a: test_doc1
---
a: test_doc2
EOL
./yq e test.yml -s '"test_" + $index'
doc1=$(cat test_0.yml)
assertEquals "a: test_doc1" "$doc1"
doc2=$(cat test_1.yml)
read -r -d '' expectedDoc2 << EOM
---
a: test_doc2
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testBasicSplitWithIndexEvalAll() {
cat >test.yml <<EOL
a: test_doc1
---
a: test_doc2
EOL
./yq ea test.yml -s '"test_" + $index'
doc1=$(cat test_0.yml)
assertEquals "a: test_doc1" "$doc1"
doc2=$(cat test_1.yml)
read -r -d '' expectedDoc2 << EOM
---
a: test_doc2
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testArraySplitWithNameNoSeparators() {
cat >test.yml <<EOL
- name: test_fred
age: 35
- name: test_catherine
age: 37
EOL
./yq e --no-doc -s ".name" ".[]" test.yml
doc1=$(cat test_fred.yml)
read -r -d '' expectedDoc1 << EOM
name: test_fred
age: 35
EOM
assertEquals "$expectedDoc1" "$doc1"
doc2=$(cat test_catherine.yml)
read -r -d '' expectedDoc2 << EOM
name: test_catherine
age: 37
EOM
assertEquals "$expectedDoc2" "$doc2"
}
testArraySplitWithNameNoSeparatorsEvalAll() {
cat >test.yml <<EOL
- name: test_fred
age: 35
- name: test_catherine
age: 37
EOL
cat >test2.yml <<EOL
- name: test_mike
age: 564
EOL
./yq ea --no-doc -s ".name" ".[]" test.yml test2.yml
doc1=$(cat test_fred.yml)
read -r -d '' expectedDoc1 << EOM
name: test_fred
age: 35
EOM
assertEquals "$expectedDoc1" "$doc1"
doc2=$(cat test_catherine.yml)
read -r -d '' expectedDoc2 << EOM
name: test_catherine
age: 37
EOM
assertEquals "$expectedDoc2" "$doc2"
doc3=$(cat test_mike.yml)
read -r -d '' expectedDoc3 << EOM
name: test_mike
age: 564
EOM
assertEquals "$expectedDoc3" "$doc3"
}
testSplitWithDirectories() {
cat >test.yml <<EOL
f: test_dir1/test_file1
---
f: test_dir2/dir22/test_file2
---
f: test_file3
EOL
./yq e --no-doc -s ".f" test.yml
doc1=$(cat test_dir1/test_file1.yml)
assertEquals "f: test_dir1/test_file1" "$doc1"
doc2=$(cat test_dir2/dir22/test_file2.yml)
assertEquals "f: test_dir2/dir22/test_file2" "$doc2"
doc3=$(cat test_file3.yml)
assertEquals "f: test_file3" "$doc3"
}
source ./scripts/shunit2
================================================
FILE: action.yml
================================================
name: 'yq - portable yaml processor'
description: 'create, read, update, delete, merge, validate and do more with yaml'
branding:
icon: command
color: gray-dark
inputs:
cmd:
description: 'The Command which should be run'
required: true
outputs:
result:
description: "The complete result from the yq command being run"
runs:
using: 'docker'
image: 'docker://mikefarah/yq:4-githubaction'
args:
- ${{ inputs.cmd }}
================================================
FILE: agents.md
================================================
# General rules
✅ **DO:**
- You can use ./yq with the `--debug-node-info` flag to get a deeper understanding of the ast.
- run ./scripts/format.sh to format the code; then ./scripts/check.sh lint and finally ./scripts/spelling.sh to check spelling.
- Add comprehensive tests to cover the changes
- Run test suite to ensure there is no regression
- Use UK english spelling
❌ **DON'T:**
- Git add or commit
- Add comments to functions that are self-explanatory
# Adding a New Encoder/Decoder
This guide explains how to add support for a new format (encoder/decoder) to yq without modifying `candidate_node.go`.
## Overview
The encoder/decoder architecture in yq is based on two main interfaces:
- **Encoder**: Converts a `CandidateNode` to output in a specific format
- **Decoder**: Reads input in a specific format and creates a `CandidateNode`
Each format is registered in `pkg/yqlib/format.go` and made available through factory functions.
## Architecture
### Key Files
- `pkg/yqlib/encoder.go` - Defines the `Encoder` interface
- `pkg/yqlib/decoder.go` - Defines the `Decoder` interface
- `pkg/yqlib/format.go` - Format registry and factory functions
- `pkg/yqlib/operator_encoder_decoder.go` - Encode/decode operators
- `pkg/yqlib/encoder_*.go` - Encoder implementations
- `pkg/yqlib/decoder_*.go` - Decoder implementations
### Interfaces
**Encoder Interface:**
```go
type Encoder interface {
Encode(writer io.Writer, node *CandidateNode) error
PrintDocumentSeparator(writer io.Writer) error
PrintLeadingContent(writer io.Writer, content string) error
CanHandleAliases() bool
}
```
**Decoder Interface:**
```go
type Decoder interface {
Init(reader io.Reader) error
Decode() (*CandidateNode, error)
}
```
## Step-by-Step: Adding a New Encoder/Decoder
### Step 1: Create the Encoder File
Create `pkg/yqlib/encoder_<format>.go` implementing the `Encoder` interface:
- `Encode()` - Convert a `CandidateNode` to your format and write to the output writer
- `PrintDocumentSeparator()` - Handle document separators if your format requires them
- `PrintLeadingContent()` - Handle leading content/comments if supported
- `CanHandleAliases()` - Return whether your format supports YAML aliases
See `encoder_json.go` or `encoder_base64.go` for examples.
### Step 2: Create the Decoder File
Create `pkg/yqlib/decoder_<format>.go` implementing the `Decoder` interface:
- `Init()` - Initialize the decoder with the input reader and set up any needed state
- `Decode()` - Decode one document from the input and return a `CandidateNode`, or `io.EOF` when finished
See `decoder_json.go` or `decoder_base64.go` for examples.
### Step 3: Create Tests (Mandatory)
Create a test file `pkg/yqlib/<format>_test.go` using the `formatScenario` pattern:
- Define test scenarios as `formatScenario` structs with fields: `description`, `input`, `expected`, `scenarioType`
- `scenarioType` can be `"decode"` (test decoding to YAML) or `"roundtrip"` (encode/decode preservation)
- Create a helper function `test<Format>Scenario()` that switches on `scenarioType`
- Create main test function `Test<Format>FormatScenarios()` that iterates over scenarios
- The main test function should use `documentScenarios` to ensure testcase documentation is generated.
Test coverage must include:
- Basic data types (scalars, arrays, objects/maps)
- Nested structures
- Edge cases (empty inputs, special characters, escape sequences)
- Format-specific features or syntax
- Round-trip tests: decode → encode → decode should preserve data
See `hcl_test.go` for a complete example.
### Step 4: Register the Format in format.go
Edit `pkg/yqlib/format.go`:
1. Add a new format variable:
- `"<format>"` is the formal name (e.g., "json", "yaml")
- `[]string{...}` contains short aliases (can be empty)
- The first function creates an encoder (can be nil for encode-only formats)
- The second function creates a decoder (can be nil for decode-only formats)
2. Add the format to the `Formats` slice in the same file
See existing formats in `format.go` for the exact structure.
### Step 5: Handle Encoder Configuration (if needed)
If your format has preferences/configuration options:
1. Create a preferences struct with your configuration fields
2. Update the encoder to accept preferences in its factory function
3. Update `format.go` to pass the configured preferences
4. Update `operator_encoder_decoder.go` if special indent handling is needed (see existing formats like JSON and YAML for the pattern)
This pattern is optional and only needed if your format has user-configurable options.
## Build Tags
Use build tags to allow optional compilation of formats:
- Add `//go:build !yq_no<format>` at the top of your encoder and decoder files
- Create a no-build version in `pkg/yqlib/no_<format>.go` that returns nil for encoder/decoder factories
This allows users to compile yq without certain formats using: `go build -tags yq_no<format>`
## Working with CandidateNode
The `CandidateNode` struct represents a YAML node with:
- `Kind`: The node type (ScalarNode, SequenceNode, MappingNode)
- `Tag`: The YAML tag (e.g., "!!str", "!!int", "!!map")
- `Value`: The scalar value (for ScalarNode only)
- `Content`: Child nodes (for SequenceNode and MappingNode)
Key methods:
- `node.guessTagFromCustomType()` - Infer the tag from Go type
- `node.AsList()` - Convert to a list for processing
- `node.CreateReplacement()` - Create a new replacement node
- `NewCandidate()` - Create a new CandidateNode
## Key Points
✅ **DO:**
- Implement only the `Encoder` and `Decoder` interfaces
- Register your format in `format.go` only
- Keep format-specific logic in your encoder/decoder files
- Use the candidate_node style attribute to store style information for round-trip. Ask if this needs to be updated with new styles.
- Use build tags for optional compilation
- Add comprehensive tests
- Run the specific encoder/decoder test (e.g. <format>_test.go) whenever you make ay changes to the encoder_<format> or decoder_<format>
- Handle errors gracefully
- Add the no build directive, like the xml encoder and decoder, that enables a minimal yq builds. e.g. `//go:build !yq_<format>`. Be sure to also update the build_small-yq.sh and build-tinygo-yq.sh to not include the new format.
❌ **DON'T:**
- Modify `candidate_node.go` to add format-specific logic
- Add format-specific fields to `CandidateNode`
- Create special cases in core navigation or evaluation logic
- Bypass the encoder/decoder interfaces
- Use candidate_node tag attribute for anything other than indicate the data type
## Examples
Refer to existing format implementations for patterns:
- **Simple encoder/decoder**: `encoder_json.go`, `decoder_json.go`
- **Complex with preferences**: `encoder_yaml.go`, `decoder_yaml.go`
- **Encoder-only**: `encoder_sh.go` (ShFormat has nil decoder)
- **String-only operations**: `encoder_base64.go`, `decoder_base64.go`
## Testing Your Implementation (Mandatory)
Tests must be implemented in `<format>_test.go` following the `formatScenario` pattern:
1. **Create test scenarios** using the `formatScenario` struct with fields:
- `description`: Brief description of what's being tested
- `input`: Sample input in your format
- `expected`: Expected output (typically in YAML for decode tests)
- `scenarioType`: Either `"decode"` or `"roundtrip"`
2. **Test coverage must include:**
- Basic data types (scalars, arrays, objects/maps)
- Nested structures
- Edge cases (empty inputs, special characters, escape sequences)
- Format-specific features or syntax
- Round-trip tests: decode → encode → decode should preserve data
3. **Test function pattern:**
- `test<Format>Scenario()`: Helper function that switches on `scenarioType`
- `Test<Format>FormatScenarios()`: Main test function that iterates over scenarios
4. **Example from existing formats:**
- See `hcl_test.go` for a complete example
- See `yaml_test.go` for YAML-specific patterns
- See `json_test.go` for more complex scenarios
## Common Patterns
### Format with Indentation
Use preferences to control output formatting:
```go
type <format>Preferences struct {
Indent int
}
func (prefs *<format>Preferences) Copy() <format>Preferences {
return *prefs
}
```
### Multiple Documents
Decoders should support reading multiple documents:
```go
func (dec *<format>Decoder) Decode() (*CandidateNode, error) {
if dec.finished {
return nil, io.EOF
}
// ... decode next document ...
if noMoreDocuments {
dec.finished = true
}
return candidate, nil
}
```
---
# Adding a New Operator
This guide explains how to add a new operator to yq. Operators are the core of yq's expression language and process `CandidateNode` objects without requiring modifications to `candidate_node.go` itself.
## Overview
Operators transform data by implementing a handler function that processes a `Context` containing `CandidateNode` objects. Each operator is:
1. Defined as an `operationType` in `operation.go`
2. Registered in the lexer in `lexer_participle.go`
3. Implemented in its own `operator_<type>.go` file
4. Tested in `operator_<type>_test.go`
5. Documented in `pkg/yqlib/doc/operators/headers/<type>.md`
## Architecture
### Key Files
- `pkg/yqlib/operation.go` - Defines `operationType` and operator registry
- `pkg/yqlib/lexer_participle.go` - Registers operators with their syntax patterns
- `pkg/yqlib/operator_<type>.go` - Operator implementation
- `pkg/yqlib/operator_<type>_test.go` - Operator tests using `expressionScenario`
- `pkg/yqlib/doc/operators/headers/<type>.md` - Documentation header
### Core Types
**operationType:**
```go
type operationType struct {
Type string // Unique operator name (e.g., "REVERSE")
NumArgs uint // Number of arguments (0 for no args)
Precedence uint // Operator precedence (higher = higher precedence)
Handler operatorHandler // The function that executes the operator
CheckForPostTraverse bool // Whether to apply post-traversal logic
ToString func(*Operation) string // Custom string representation
}
```
**operatorHandler signature:**
```go
type operatorHandler func(*dataTreeNavigator, Context, *ExpressionNode) (Context, error)
```
**expressionScenario for tests:**
```go
type expressionScenario struct {
description string
subdescription string
document string
expression string
expected []string
skipDoc bool
expectedError string
}
```
## Step-by-Step: Adding a New Operator
### Step 1: Create the Operator Implementation File
Create `pkg/yqlib/operator_<type>.go` implementing the operator handler function:
- Implement the `operatorHandler` function signature
- Process nodes from `context.MatchingNodes`
- Return a new `Context` with results using `context.ChildContext()`
- Use `candidate.CreateReplacement()` or `candidate.CreateReplacementWithComments()` to create new nodes
- Handle errors gracefully with meaningful error messages
See `operator_reverse.go` or `operator_keys.go` for examples.
### Step 2: Register the Operator in operation.go
Add the operator type definition to `pkg/yqlib/operation.go`:
```go
var <type>OpType = &operationType{
Type: "<TYPE>", // All caps, matches pattern in lexer
NumArgs: 0, // 0 for no args, 1+ for args
Precedence: 50, // Typical range: 40-55
Handler: <type>Operator, // Reference to handler function
}
```
**Precedence guidelines:**
- 10-20: Logical operators (OR, AND, UNION)
- 30: Pipe operator
- 40: Assignment and comparison operators
- 42: Arithmetic operators (ADD, SUBTRACT, MULTIPLY, DIVIDE)
- 50-52: Most other operators
- 55: High precedence (e.g., GET_VARIABLE)
**Optional fields:**
- `CheckForPostTraverse: true` - If your operator can have another directly after it without the pipe character. Most of the time this is false.
- `ToString: customToString` - Custom string representation (rarely needed)
### Step 3: Register the Operator in lexer_participle.go
Edit `pkg/yqlib/lexer_participle.go` to add the operator to the lexer rules:
- Use `simpleOp()` for simple keyword patterns
- Use object syntax for regex patterns or complex syntax
- Support optional characters with `_?` and aliases with `|`
See existing operators in `lexer_participle.go` for pattern examples.
### Step 4: Create Tests (Mandatory)
Create `pkg/yqlib/operator_<type>_test.go` using the `expressionScenario` pattern:
- Define test scenarios with `description`, `document`, `expression`, and `expected` fields
- `expected` is a slice of strings showing output format: `"D<doc>, P[<path>], (<tag>)::<value>\n"`
- Set `skipDoc: true` for edge cases you don't want in generated documentation
- Include `subdescription` for longer test names
- Set `expectedError` if testing error cases
- Create main test function that iterates over scenarios
- The main test function should use `documentScenarios` to ensure testcase documentation is generated.
Test coverage must include:
- Basic data types and nested structures
- Edge cases (empty inputs, special characters, type errors)
- Multiple outputs if applicable
- Format-specific features
See `operator_reverse_test.go` for a simple example and `operator_keys_test.go` for complex cases.
### Step 5: Create Documentation Header
Create `pkg/yqlib/doc/operators/headers/<type>.md`:
- Use the exact operator name as the title
- Include a concise 1-2 sentence summary
- Add additional context or examples if the operator is complex
See existing headers in `doc/operators/headers/` for examples.
## Working with Context and CandidateNode
### Context Management
- `context.ChildContext(results)` - Create child context with results
- `context.GetVariable("varName")` - Get variables stored in context
- `context.SetVariable("varName", value)` - Set variables in context
### CandidateNode Operations
- `candidate.CreateReplacement(ScalarNode, "!!str", stringValue)` - Create a replacement node
- `candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidate.Style)` - With style preserved
- `candidate.Kind` - The node type (ScalarNode, SequenceNode, MappingNode)
- `candidate.Tag` - The YAML tag (!!str, !!int, etc.)
- `candidate.Value` - The scalar value (for ScalarNode only)
- `candidate.Content` - Child nodes (for SequenceNode and MappingNode)
- `candidate.guessTagFromCustomType()` - Infer the tag from Go type
- `candidate.AsList()` - Convert to a list representation
## Key Points
✅ **DO:**
- Implement the operator handler with the correct signature
- Register in `operation.go` with appropriate precedence
- Add the lexer pattern in `lexer_participle.go`
- Write comprehensive tests covering normal and edge cases
- Create a documentation header in `doc/operators/headers/`
- Use `Context.ChildContext()` for proper context threading
- Handle all node types gracefully
- Return meaningful error messages
❌ **DON'T:**
- Modify `candidate_node.go` (operators shouldn't need this)
- Modify core navigation or evaluation logic
- Bypass the handler function pattern
- Add format-specific or operator-specific fields to `CandidateNode`
- Skip tests or documentation
## Examples
Refer to existing operator implementations for patterns:
- **No-argument operator**: `operator_reverse.go` - Processes arrays/sequences
- **Single-argument operator**: `operator_map.go` - Takes an expression argument
- **Complex multi-output**: `operator_keys.go` - Produces multiple results
- **With preferences**: `operator_to_number.go` - Configuration options
- **Error handling**: `operator_error.go` - Control flow with errors
- **String operations**: `operator_strings.go` - Multiple related operators
## Testing Patterns
Refer to existing test files for specific patterns:
- Basic expression tests in `operator_reverse_test.go`
- Multi-output tests in `operator_keys_test.go`
- Error handling tests in `operator_error_test.go`
- Tests with `skipDoc` flag to exclude from generated documentation
## Common Patterns
Refer to existing operator implementations for these patterns:
- Simple transformation: see `operator_reverse.go`
- Type checking: see `operator_error.go`
- Working with arguments: see `operator_map.go`
- Post-traversal operators: see `operator_with.go`
================================================
FILE: cmd/completion.go
================================================
package cmd
import (
"os"
"github.com/spf13/cobra"
)
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Aliases: []string{"shell-completion"},
Short: "Generate the autocompletion script for the specified shell",
Long: `To load completions:
Bash:
$ source <(yq completion bash)
# To load completions for each session, execute once:
Linux:
$ yq completion bash > /etc/bash_completion.d/yq
MacOS:
$ yq completion bash > /usr/local/etc/bash_completion.d/yq
Zsh:
# If shell completion is not already enabled in your environment you will need
# to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ yq completion zsh > "${fpath[1]}/_yq"
# You will need to start a new shell for this setup to take effect.
Fish:
$ yq completion fish | source
# To load completions for each session, execute once:
$ yq completion fish > ~/.config/fish/completions/yq.fish
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: func(cmd *cobra.Command, args []string) error {
var err error = nil
switch args[0] {
case "bash":
err = cmd.Root().GenBashCompletionV2(os.Stdout, true)
case "zsh":
err = cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
err = cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
err = cmd.Root().GenPowerShellCompletion(os.Stdout)
}
return err
},
}
================================================
FILE: cmd/constant.go
================================================
package cmd
var unwrapScalarFlag = newUnwrapFlag()
var printNodeInfo = false
var unwrapScalar = false
var writeInplace = false
var outputToJSON = false
var outputFormat = ""
var inputFormat = ""
var exitStatus = false
var indent = 2
var noDocSeparators = false
var nullInput = false
var nulSepOutput = false
var verbose = false
var version = false
var prettyPrint = false
var forceColor = false
var forceNoColor = false
var colorsEnabled = false
// can be either "" (off), "extract" or "process"
var frontMatter = ""
var splitFileExp = ""
var splitFileExpFile = ""
var completedSuccessfully = false
var forceExpression = ""
var expressionFile = ""
================================================
FILE: cmd/evaluate_all_command.go
================================================
package cmd
import (
"errors"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
)
func createEvaluateAllCommand() *cobra.Command {
var cmdEvalAll = &cobra.Command{
Use: "eval-all [expression] [yaml_file1]...",
Aliases: []string{"ea"},
Short: "Loads _all_ yaml documents of _all_ yaml files and runs expression once",
ValidArgsFunction: func(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return nil, cobra.ShellCompDirectiveDefault
},
Example: `
# Merge f2.yml into f1.yml (in place)
yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' f1.yml f2.yml
## the same command and expression using shortened names:
yq ea -i 'select(fi == 0) * select(fi == 1)' f1.yml f2.yml
# Merge all given files
yq ea '. as $item ireduce ({}; . * $item )' file1.yml file2.yml ...
# Pipe from STDIN
## use '-' as a filename to pipe from STDIN
cat file2.yml | yq ea '.a.b' file1.yml - file3.yml
`,
Long: `yq is a portable command-line data file processor (https://github.com/mikefarah/yq/)
See https://mikefarah.gitbook.io/yq/ for detailed documentation and examples.
## Evaluate All ##
This command loads _all_ yaml documents of _all_ yaml files and runs expression once
Useful when you need to run an expression across several yaml documents or files (like merge).
Note that it consumes more memory than eval.
`,
RunE: evaluateAll,
}
return cmdEvalAll
}
func evaluateAll(cmd *cobra.Command, args []string) (cmdError error) {
// 0 args, read std in
// 1 arg, null input, process expression
// 1 arg, read file in sequence
// 2+ args, [0] = expression, file the rest
var err error
expression, args, err := initCommand(cmd, args)
if err != nil {
return err
}
out := cmd.OutOrStdout()
if writeInplace {
// only use colours if its forced
colorsEnabled = forceColor
writeInPlaceHandler := yqlib.NewWriteInPlaceHandler(args[0])
out, err = writeInPlaceHandler.CreateTempFile()
if err != nil {
return err
}
// need to indirectly call the function so that completedSuccessfully is
// passed when we finish execution as opposed to now
defer func() {
if cmdError == nil {
cmdError = writeInPlaceHandler.FinishWriteInPlace(completedSuccessfully)
}
}()
}
format, err := yqlib.FormatFromString(outputFormat)
if err != nil {
return err
}
decoder, err := configureDecoder(true)
if err != nil {
return err
}
printerWriter, err := configurePrinterWriter(format, out)
if err != nil {
return err
}
encoder, err := configureEncoder()
if err != nil {
return err
}
printer := yqlib.NewPrinter(encoder, printerWriter)
if nulSepOutput {
printer.SetNulSepOutput(true)
}
if frontMatter != "" {
frontMatterHandler := yqlib.NewFrontMatterHandler(args[0])
err = frontMatterHandler.Split()
if err != nil {
return err
}
args[0] = frontMatterHandler.GetYamlFrontMatterFilename()
if frontMatter == "process" {
reader := frontMatterHandler.GetContentReader()
printer.SetAppendix(reader)
defer yqlib.SafelyCloseReader(reader)
}
defer frontMatterHandler.CleanUp()
}
allAtOnceEvaluator := yqlib.NewAllAtOnceEvaluator()
switch len(args) {
case 0:
if nullInput {
err = yqlib.NewStreamEvaluator().EvaluateNew(processExpression(expression), printer)
} else {
cmd.Println(cmd.UsageString())
return nil
}
default:
err = allAtOnceEvaluator.EvaluateFiles(processExpression(expression), args, printer, decoder)
}
completedSuccessfully = err == nil
if err == nil && exitStatus && !printer.PrintedAnything() {
return errors.New("no matches found")
}
return err
}
================================================
FILE: cmd/evaluate_all_command_test.go
================================================
package cmd
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
)
func TestCreateEvaluateAllCommand(t *testing.T) {
cmd := createEvaluateAllCommand()
if cmd == nil {
t.Fatal("createEvaluateAllCommand returned nil")
}
// Test basic command properties
if cmd.Use != "eval-all [expression] [yaml_file1]..." {
t.Errorf("Expected Use to be 'eval-all [expression] [yaml_file1]...', got %q", cmd.Use)
}
if cmd.Short == "" {
t.Error("Expected Short description to be non-empty")
}
if cmd.Long == "" {
t.Error("Expected Long description to be non-empty")
}
// Test aliases
expectedAliases := []string{"ea"}
if len(cmd.Aliases) != len(expectedAliases) {
t.Errorf("Expected %d aliases, got %d", len(expectedAliases), len(cmd.Aliases))
}
for i, expected := range expectedAliases {
if i >= len(cmd.Aliases) || cmd.Aliases[i] != expected {
t.Errorf("Expected alias %d to be %q, got %q", i, expected, cmd.Aliases[i])
}
}
}
func TestEvaluateAll_NoArgs(t *testing.T) {
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with no arguments and no null input
nullInput = false
defer func() { nullInput = false }()
err := evaluateAll(cmd, []string{})
// Should not error, but should print usage
if err != nil {
t.Errorf("evaluateAll with no args should not error, got: %v", err)
}
// Should have printed usage information
if output.Len() == 0 {
t.Error("Expected usage information to be printed")
}
}
func TestEvaluateAll_NullInput(t *testing.T) {
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with null input
nullInput = true
defer func() { nullInput = false }()
err := evaluateAll(cmd, []string{})
// Should not error when using null input
if err != nil {
t.Errorf("evaluateAll with null input should not error, got: %v", err)
}
}
func TestEvaluateAll_WithSingleFile(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with a single file
err = evaluateAll(cmd, []string{yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateAll with single file should not error, got: %v", err)
}
// Should have some output
if output.Len() == 0 {
t.Error("Expected output from evaluateAll with single file")
}
}
func TestEvaluateAll_WithMultipleFiles(t *testing.T) {
// Create temporary YAML files
tempDir := t.TempDir()
yamlFile1 := filepath.Join(tempDir, "test1.yaml")
yamlContent1 := []byte("name: test1\nage: 25\n")
err := os.WriteFile(yamlFile1, yamlContent1, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file 1: %v", err)
}
yamlFile2 := filepath.Join(tempDir, "test2.yaml")
yamlContent2 := []byte("name: test2\nage: 30\n")
err = os.WriteFile(yamlFile2, yamlContent2, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file 2: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with multiple files
err = evaluateAll(cmd, []string{yamlFile1, yamlFile2})
// Should not error
if err != nil {
t.Errorf("evaluateAll with multiple files should not error, got: %v", err)
}
// Should have output
if output.Len() == 0 {
t.Error("Expected output from evaluateAll with multiple files")
}
}
func TestEvaluateAll_WithExpression(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with expression
err = evaluateAll(cmd, []string{".name", yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateAll with expression should not error, got: %v", err)
}
// Should have output
if output.Len() == 0 {
t.Error("Expected output from evaluateAll with expression")
}
}
func TestEvaluateAll_WriteInPlace(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Enable write in place
originalWriteInplace := writeInplace
writeInplace = true
defer func() { writeInplace = originalWriteInplace }()
// Test with write in place
err = evaluateAll(cmd, []string{".name = \"updated\"", yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateAll with write in place should not error, got: %v", err)
}
// Verify the file was updated
updatedContent, err := os.ReadFile(yamlFile)
if err != nil {
t.Fatalf("Failed to read updated file: %v", err)
}
// Should contain the updated content
if !strings.Contains(string(updatedContent), "updated") {
t.Errorf("Expected file to contain 'updated', got: %s", string(updatedContent))
}
}
func TestEvaluateAll_ExitStatus(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Enable exit status
originalExitStatus := exitStatus
exitStatus = true
defer func() { exitStatus = originalExitStatus }()
// Test with expression that should find no matches
err = evaluateAll(cmd, []string{".nonexistent", yamlFile})
// Should error when no matches found and exit status is enabled
if err == nil {
t.Error("Expected error when no matches found and exit status is enabled")
}
}
func TestEvaluateAll_WithMultipleDocuments(t *testing.T) {
// Create a temporary YAML file with multiple documents
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("---\nname: doc1\nage: 25\n---\nname: doc2\nage: 30\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with multiple documents
err = evaluateAll(cmd, []string{".", yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateAll with multiple documents should not error, got: %v", err)
}
// Should have output
if output.Len() == 0 {
t.Error("Expected output from evaluateAll with multiple documents")
}
}
func TestEvaluateAll_NulSepOutput(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateAllCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Enable nul separator output
originalNulSepOutput := nulSepOutput
nulSepOutput = true
defer func() { nulSepOutput = originalNulSepOutput }()
// Test with nul separator output
err = evaluateAll(cmd, []string{".name", yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateAll with nul separator output should not error, got: %v", err)
}
// Should have output
if output.Len() == 0 {
t.Error("Expected output from evaluateAll with nul separator output")
}
}
================================================
FILE: cmd/evaluate_sequence_command.go
================================================
package cmd
import (
"errors"
"fmt"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
)
func createEvaluateSequenceCommand() *cobra.Command {
var cmdEvalSequence = &cobra.Command{
Use: "eval [expression] [yaml_file1]...",
Aliases: []string{"e"},
Short: "(default) Apply the expression to each document in each yaml file in sequence",
ValidArgsFunction: func(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return nil, cobra.ShellCompDirectiveDefault
},
Example: `
# Reads field under the given path for each file
yq e '.a.b' f1.yml f2.yml
# Prints out the file
yq e sample.yaml
# Pipe from STDIN
## use '-' as a filename to pipe from STDIN
cat file2.yml | yq e '.a.b' file1.yml - file3.yml
# Creates a new yaml document
## Note that editing an empty file does not work.
yq e -n '.a.b.c = "cat"'
# Update a file in place
yq e '.a.b = "cool"' -i file.yaml
`,
Long: `yq is a portable command-line data file processor (https://github.com/mikefarah/yq/)
See https://mikefarah.gitbook.io/yq/ for detailed documentation and examples.
## Evaluate Sequence ##
This command iterates over each yaml document from each given file, applies the
expression and prints the result in sequence.`,
RunE: evaluateSequence,
}
return cmdEvalSequence
}
func processExpression(expression string) string {
if prettyPrint && expression == "" {
return yqlib.PrettyPrintExp
} else if prettyPrint {
return fmt.Sprintf("%v | %v", expression, yqlib.PrettyPrintExp)
}
return expression
}
func evaluateSequence(cmd *cobra.Command, args []string) (cmdError error) {
// 0 args, read std in
// 1 arg, null input, process expression
// 1 arg, read file in sequence
// 2+ args, [0] = expression, file the rest
out := cmd.OutOrStdout()
var err error
expression, args, err := initCommand(cmd, args)
if err != nil {
return err
}
if writeInplace {
// only use colours if its forced
colorsEnabled = forceColor
writeInPlaceHandler := yqlib.NewWriteInPlaceHandler(args[0])
out, err = writeInPlaceHandler.CreateTempFile()
if err != nil {
return err
}
// need to indirectly call the function so that completedSuccessfully is
// passed when we finish execution as opposed to now
defer func() {
if cmdError == nil {
cmdError = writeInPlaceHandler.FinishWriteInPlace(completedSuccessfully)
}
}()
}
format, err := yqlib.FormatFromString(outputFormat)
if err != nil {
return err
}
printerWriter, err := configurePrinterWriter(format, out)
if err != nil {
return err
}
encoder, err := configureEncoder()
if err != nil {
return err
}
printer := yqlib.NewPrinter(encoder, printerWriter)
if printNodeInfo {
printer = yqlib.NewNodeInfoPrinter(printerWriter)
}
if nulSepOutput {
printer.SetNulSepOutput(true)
}
decoder, err := configureDecoder(false)
if err != nil {
return err
}
streamEvaluator := yqlib.NewStreamEvaluator()
if frontMatter != "" {
yqlib.GetLogger().Debug("using front matter handler")
frontMatterHandler := yqlib.NewFrontMatterHandler(args[0])
err = frontMatterHandler.Split()
if err != nil {
return err
}
args[0] = frontMatterHandler.GetYamlFrontMatterFilename()
if frontMatter == "process" {
reader := frontMatterHandler.GetContentReader()
printer.SetAppendix(reader)
defer yqlib.SafelyCloseReader(reader)
}
defer frontMatterHandler.CleanUp()
}
switch len(args) {
case 0:
if nullInput {
err = streamEvaluator.EvaluateNew(processExpression(expression), printer)
} else {
cmd.Println(cmd.UsageString())
return nil
}
default:
err = streamEvaluator.EvaluateFiles(processExpression(expression), args, printer, decoder)
}
completedSuccessfully = err == nil
if err == nil && exitStatus && !printer.PrintedAnything() {
return errors.New("no matches found")
}
return err
}
================================================
FILE: cmd/evaluate_sequence_command_test.go
================================================
package cmd
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
)
func TestCreateEvaluateSequenceCommand(t *testing.T) {
cmd := createEvaluateSequenceCommand()
if cmd == nil {
t.Fatal("createEvaluateSequenceCommand returned nil")
}
// Test basic command properties
if cmd.Use != "eval [expression] [yaml_file1]..." {
t.Errorf("Expected Use to be 'eval [expression] [yaml_file1]...', got %q", cmd.Use)
}
if cmd.Short == "" {
t.Error("Expected Short description to be non-empty")
}
if cmd.Long == "" {
t.Error("Expected Long description to be non-empty")
}
// Test aliases
expectedAliases := []string{"e"}
if len(cmd.Aliases) != len(expectedAliases) {
t.Errorf("Expected %d aliases, got %d", len(expectedAliases), len(cmd.Aliases))
}
for i, expected := range expectedAliases {
if i >= len(cmd.Aliases) || cmd.Aliases[i] != expected {
t.Errorf("Expected alias %d to be %q, got %q", i, expected, cmd.Aliases[i])
}
}
}
func TestProcessExpression(t *testing.T) {
// Reset global variables
originalPrettyPrint := prettyPrint
defer func() { prettyPrint = originalPrettyPrint }()
tests := []struct {
name string
prettyPrint bool
expression string
expected string
}{
{
name: "empty expression without pretty print",
prettyPrint: false,
expression: "",
expected: "",
},
{
name: "empty expression with pretty print",
prettyPrint: true,
expression: "",
expected: `(... | (select(tag != "!!str"), select(tag == "!!str") | select(test("(?i)^(y|yes|n|no|on|off)$") | not)) ) style=""`,
},
{
name: "simple expression without pretty print",
prettyPrint: false,
expression: ".a.b",
expected: ".a.b",
},
{
name: "simple expression with pretty print",
prettyPrint: true,
expression: ".a.b",
expected: `.a.b | (... | (select(tag != "!!str"), select(tag == "!!str") | select(test("(?i)^(y|yes|n|no|on|off)$") | not)) ) style=""`,
},
{
name: "complex expression with pretty print",
prettyPrint: true,
expression: ".items[] | select(.active == true)",
expected: `.items[] | select(.active == true) | (... | (select(tag != "!!str"), select(tag == "!!str") | select(test("(?i)^(y|yes|n|no|on|off)$") | not)) ) style=""`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
prettyPrint = tt.prettyPrint
result := processExpression(tt.expression)
if result != tt.expected {
t.Errorf("processExpression(%q) = %q, want %q", tt.expression, result, tt.expected)
}
})
}
}
func TestEvaluateSequence_NoArgs(t *testing.T) {
// Create a temporary command
cmd := createEvaluateSequenceCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with no arguments and no null input
nullInput = false
defer func() { nullInput = false }()
err := evaluateSequence(cmd, []string{})
// Should not error, but should print usage
if err != nil {
t.Errorf("evaluateSequence with no args should not error, got: %v", err)
}
// Should have printed usage information
if output.Len() == 0 {
t.Error("Expected usage information to be printed")
}
}
func TestEvaluateSequence_NullInput(t *testing.T) {
// Create a temporary command
cmd := createEvaluateSequenceCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with null input
nullInput = true
defer func() { nullInput = false }()
err := evaluateSequence(cmd, []string{})
// Should not error when using null input
if err != nil {
t.Errorf("evaluateSequence with null input should not error, got: %v", err)
}
}
func TestEvaluateSequence_WithFile(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateSequenceCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with a file
err = evaluateSequence(cmd, []string{yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateSequence with file should not error, got: %v", err)
}
// Should have some output
if output.Len() == 0 {
t.Error("Expected output from evaluateSequence with file")
}
}
func TestEvaluateSequence_WithExpressionAndFile(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateSequenceCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Test with expression and file
err = evaluateSequence(cmd, []string{".name", yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateSequence with expression and file should not error, got: %v", err)
}
// Should have output
if output.Len() == 0 {
t.Error("Expected output from evaluateSequence with expression and file")
}
}
func TestEvaluateSequence_WriteInPlace(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateSequenceCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Enable write in place
originalWriteInplace := writeInplace
writeInplace = true
defer func() { writeInplace = originalWriteInplace }()
// Test with write in place
err = evaluateSequence(cmd, []string{".name = \"updated\"", yamlFile})
// Should not error
if err != nil {
t.Errorf("evaluateSequence with write in place should not error, got: %v", err)
}
// Verify the file was updated
updatedContent, err := os.ReadFile(yamlFile)
if err != nil {
t.Fatalf("Failed to read updated file: %v", err)
}
// Should contain the updated content
if !strings.Contains(string(updatedContent), "updated") {
t.Errorf("Expected file to contain 'updated', got: %s", string(updatedContent))
}
}
func TestEvaluateSequence_ExitStatus(t *testing.T) {
// Create a temporary YAML file
tempDir := t.TempDir()
yamlFile := filepath.Join(tempDir, "test.yaml")
yamlContent := []byte("name: test\nage: 25\n")
err := os.WriteFile(yamlFile, yamlContent, 0600)
if err != nil {
t.Fatalf("Failed to create test YAML file: %v", err)
}
// Create a temporary command
cmd := createEvaluateSequenceCommand()
// Set up command to capture output
var output bytes.Buffer
cmd.SetOut(&output)
// Enable exit status
originalExitStatus := exitStatus
exitStatus = true
defer func() { exitStatus = originalExitStatus }()
// Test with expression that should find no matches
err = evaluateSequence(cmd, []string{".nonexistent", yamlFile})
// Should error when no matches found and exit status is enabled
if err == nil {
t.Error("Expected error when no matches found and exit status is enabled")
}
}
================================================
FILE: cmd/root.go
================================================
package cmd
import (
"fmt"
"os"
"strings"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
logging "gopkg.in/op/go-logging.v1"
)
type runeValue rune
func newRuneVar(p *rune) *runeValue {
return (*runeValue)(p)
}
func (r *runeValue) String() string {
return string(*r)
}
func (r *runeValue) Set(rawVal string) error {
val := strings.ReplaceAll(rawVal, "\\n", "\n")
val = strings.ReplaceAll(val, "\\t", "\t")
val = strings.ReplaceAll(val, "\\r", "\r")
val = strings.ReplaceAll(val, "\\f", "\f")
val = strings.ReplaceAll(val, "\\v", "\v")
if len(val) != 1 {
return fmt.Errorf("[%v] is not a valid character. Must be length 1 was %v", val, len(val))
}
*r = runeValue(rune(val[0]))
return nil
}
func (r *runeValue) Type() string {
return "char"
}
func New() *cobra.Command {
var rootCmd = &cobra.Command{
Use: "yq",
Short: "yq is a lightweight and portable command-line data file processor.",
Long: `yq is a portable command-line data file processor (https://github.com/mikefarah/yq/)
See https://mikefarah.gitbook.io/yq/ for detailed documentation and examples.`,
Example: `
# yq tries to auto-detect the file format based off the extension, and defaults to YAML if it's unknown (or piping through STDIN)
# Use the '-p/--input-format' flag to specify a format type.
cat file.xml | yq -p xml
# read the "stuff" node from "myfile.yml"
yq '.stuff' < myfile.yml
# update myfile.yml in place
yq -i '.stuff = "foo"' myfile.yml
# print contents of sample.json as idiomatic YAML
yq -P -oy sample.json
`,
RunE: func(cmd *cobra.Command, args []string) error {
if version {
cmd.Print(GetVersionDisplay())
return nil
}
return evaluateSequence(cmd, args)
},
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
cmd.SetOut(cmd.OutOrStdout())
level := logging.WARNING
stringFormat := `[%{level}] %{color}%{time:15:04:05}%{color:reset} %{message}`
// when NO_COLOR environment variable presents and not an empty string the coloured output should be disabled;
// refer to no-color.org
forceNoColor = forceNoColor || os.Getenv("NO_COLOR") != ""
if verbose && forceNoColor {
level = logging.DEBUG
stringFormat = `[%{level:5.5s}] %{time:15:04:05} %{shortfile:-33s} %{shortfunc:-25s} %{message}`
} else if verbose {
level = logging.DEBUG
stringFormat = `[%{level:5.5s}] %{color}%{time:15:04:05}%{color:bold} %{shortfile:-33s} %{shortfunc:-25s}%{color:reset} %{message}`
} else if forceNoColor {
stringFormat = `[%{level}] %{time:15:04:05} %{message}`
}
var format = logging.MustStringFormatter(stringFormat)
var backend = logging.AddModuleLevel(
logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), format))
backend.SetLevel(level, "")
logging.SetBackend(backend)
yqlib.InitExpressionParser()
return nil
},
}
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose mode")
rootCmd.PersistentFlags().BoolVarP(&printNodeInfo, "debug-node-info", "", false, "debug node info")
rootCmd.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "(deprecated) output as json. Set indent to 0 to print json in one line.")
err := rootCmd.PersistentFlags().MarkDeprecated("tojson", "please use -o=json instead")
if err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "auto", fmt.Sprintf("[auto|a|%v] output format type.", yqlib.GetAvailableOutputFormatString()))
var outputCompletions = []string{"auto"}
for _, formats := range yqlib.GetAvailableOutputFormats() {
outputCompletions = append(outputCompletions, formats.FormalName)
}
if err = rootCmd.RegisterFlagCompletionFunc("output-format", cobra.FixedCompletions(outputCompletions, cobra.ShellCompDirectiveNoFileComp)); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&inputFormat, "input-format", "p", "auto", fmt.Sprintf("[auto|a|%v] parse format for input.", yqlib.GetAvailableInputFormatString()))
var inputCompletions = []string{"auto"}
for _, formats := range yqlib.GetAvailableInputFormats() {
inputCompletions = append(inputCompletions, formats.FormalName)
}
if err = rootCmd.RegisterFlagCompletionFunc("input-format", cobra.FixedCompletions(inputCompletions, cobra.ShellCompDirectiveNoFileComp)); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.AttributePrefix, "xml-attribute-prefix", yqlib.ConfiguredXMLPreferences.AttributePrefix, "prefix for xml attributes")
if err = rootCmd.RegisterFlagCompletionFunc("xml-attribute-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ContentName, "xml-content-name", yqlib.ConfiguredXMLPreferences.ContentName, "name for xml content (if no attribute name is present).")
if err = rootCmd.RegisterFlagCompletionFunc("xml-content-name", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.StrictMode, "xml-strict-mode", yqlib.ConfiguredXMLPreferences.StrictMode, "enables strict parsing of XML. See https://pkg.go.dev/encoding/xml for more details.")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.KeepNamespace, "xml-keep-namespace", yqlib.ConfiguredXMLPreferences.KeepNamespace, "enables keeping namespace after parsing attributes")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.UseRawToken, "xml-raw-token", yqlib.ConfiguredXMLPreferences.UseRawToken, "enables using RawToken method instead Token. Commonly disables namespace translations. See https://pkg.go.dev/encoding/xml#Decoder.RawToken for details.")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ProcInstPrefix, "xml-proc-inst-prefix", yqlib.ConfiguredXMLPreferences.ProcInstPrefix, "prefix for xml processing instructions (e.g. <?xml version=\"1\"?>)")
if err = rootCmd.RegisterFlagCompletionFunc("xml-proc-inst-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.DirectiveName, "xml-directive-name", yqlib.ConfiguredXMLPreferences.DirectiveName, "name for xml directives (e.g. <!DOCTYPE thing cat>)")
if err = rootCmd.RegisterFlagCompletionFunc("xml-directive-name", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipProcInst, "xml-skip-proc-inst", yqlib.ConfiguredXMLPreferences.SkipProcInst, "skip over process instructions (e.g. <?xml version=\"1\"?>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipDirectives, "xml-skip-directives", yqlib.ConfiguredXMLPreferences.SkipDirectives, "skip over directives (e.g. <!DOCTYPE thing cat>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredCsvPreferences.AutoParse, "csv-auto-parse", yqlib.ConfiguredCsvPreferences.AutoParse, "parse CSV YAML/JSON values")
rootCmd.PersistentFlags().Var(newRuneVar(&yqlib.ConfiguredCsvPreferences.Separator), "csv-separator", "CSV Separator character")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredTsvPreferences.AutoParse, "tsv-auto-parse", yqlib.ConfiguredTsvPreferences.AutoParse, "parse TSV YAML/JSON values")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocPrefix, "lua-prefix", yqlib.ConfiguredLuaPreferences.DocPrefix, "prefix")
if err = rootCmd.RegisterFlagCompletionFunc("lua-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocSuffix, "lua-suffix", yqlib.ConfiguredLuaPreferences.DocSuffix, "suffix")
if err = rootCmd.RegisterFlagCompletionFunc("lua-suffix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.UnquotedKeys, "lua-unquoted", yqlib.ConfiguredLuaPreferences.UnquotedKeys, "output unquoted string keys (e.g. {foo=\"bar\"})")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.Globals, "lua-globals", yqlib.ConfiguredLuaPreferences.Globals, "output keys as top-level global variables")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "properties-separator", yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "separator to use between keys and values")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "properties-array-brackets", yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "use [x] in array paths (e.g. for SpringBoot)")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredShellVariablesPreferences.KeySeparator, "shell-key-separator", yqlib.ConfiguredShellVariablesPreferences.KeySeparator, "separator for shell variable key paths")
if err = rootCmd.RegisterFlagCompletionFunc("shell-key-separator", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&yqlib.StringInterpolationEnabled, "string-interpolation", yqlib.StringInterpolationEnabled, "Toggles strings interpolation of \\(exp)")
rootCmd.PersistentFlags().BoolVarP(&nullInput, "null-input", "n", false, "Don't read input, simply evaluate the expression given. Useful for creating docs from scratch.")
rootCmd.PersistentFlags().BoolVarP(&noDocSeparators, "no-doc", "N", false, "Don't print document separators (---)")
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
if err = rootCmd.RegisterFlagCompletionFunc("indent", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
rootCmd.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the file in place of first file given.")
rootCmd.PersistentFlags().VarP(unwrapScalarFlag, "unwrapScalar", "r", "unwrap scalar, print the value with no quotes, colours or comments. Defaults to true for yaml")
rootCmd.PersistentFlags().Lookup("unwrapScalar").NoOptDefVal = "true"
rootCmd.PersistentFlags().BoolVarP(&nulSepOutput, "nul-output", "0", false, "Use NUL char to separate values. If unwrap scalar is also set, fail if unwrapped scalar contains NUL char.")
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print, shorthand for '... style = \"\"'")
rootCmd.PersistentFlags().BoolVarP(&exitStatus, "exit-status", "e", false, "set exit status if there are no matches or null or false is returned")
rootCmd.PersistentFlags().BoolVarP(&forceColor, "colors", "C", false, "force print with colors")
rootCmd.PersistentFlags().BoolVarP(&forceNoColor, "no-colors", "M", forceNoColor, "force print with no colors")
rootCmd.PersistentFlags().StringVarP(&frontMatter, "front-matter", "f", "", "(extract|process) first input as yaml front-matter. Extract will pull out the yaml content, process will run the expression against the yaml content, leaving the remaining data intact")
if err = rootCmd.RegisterFlagCompletionFunc("front-matter", cobra.FixedCompletions([]string{"extract", "process"}, cobra.ShellCompDirectiveNoFileComp)); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&forceExpression, "expression", "", "", "forcibly set the expression argument. Useful when yq argument detection thinks your expression is a file.")
if err = rootCmd.RegisterFlagCompletionFunc("expression", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredYamlPreferences.LeadingContentPreProcessing, "header-preprocess", "", true, "Slurp any header comments and separators before processing expression.")
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredYamlPreferences.FixMergeAnchorToSpec, "yaml-fix-merge-anchor-to-spec", "", false, "Fix merge anchor to match YAML spec. Will default to true in late 2025")
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredYamlPreferences.CompactSequenceIndent, "yaml-compact-seq-indent", "c", false, "Use compact sequence indentation where '- ' is considered part of the indentation.")
rootCmd.PersistentFlags().StringVarP(&splitFileExp, "split-exp", "s", "", "print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter. The necessary directories will be created.")
if err = rootCmd.RegisterFlagCompletionFunc("split-exp", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&splitFileExpFile, "split-exp-file", "", "", "Use a file to specify the split-exp expression.")
if err = rootCmd.MarkPersistentFlagFilename("split-exp-file"); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&expressionFile, "from-file", "", "", "Load expression from specified file.")
if err = rootCmd.MarkPersistentFlagFilename("from-file"); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableEnvOps, "security-disable-env-ops", "", false, "Disable env related operations.")
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableFileOps, "security-disable-file-ops", "", false, "Disable file related operations (e.g. load)")
rootCmd.AddCommand(
createEvaluateSequenceCommand(),
createEvaluateAllCommand(),
completionCmd,
)
return rootCmd
}
================================================
FILE: cmd/root_test.go
================================================
package cmd
import (
"strings"
"testing"
)
func TestNewRuneVar(t *testing.T) {
var r rune
runeVar := newRuneVar(&r)
if runeVar == nil {
t.Fatal("newRuneVar returned nil")
}
}
func TestRuneValue_String(t *testing.T) {
tests := []struct {
name string
runeVal rune
expected string
}{
{
name: "simple character",
runeVal: 'a',
expected: "a",
},
{
name: "special character",
runeVal: '\n',
expected: "\n",
},
{
name: "unicode character",
runeVal: 'ñ',
expected: "ñ",
},
{
name: "zero rune",
runeVal: 0,
expected: string(rune(0)),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
runeVal := runeValue(tt.runeVal)
result := runeVal.String()
if result != tt.expected {
t.Errorf("runeValue.String() = %q, want %q", result, tt.expected)
}
})
}
}
func TestRuneValue_Set(t *testing.T) {
tests := []struct {
name string
input string
expected rune
expectError bool
}{
{
name: "simple character",
input: "a",
expected: 'a',
expectError: false,
},
{
name: "newline escape",
input: "\\n",
expected: '\n',
expectError: false,
},
{
name: "tab escape",
input: "\\t",
expected: '\t',
expectError: false,
},
{
name: "carriage return escape",
input: "\\r",
expected: '\r',
expectError: false,
},
{
name: "form feed escape",
input: "\\f",
expected: '\f',
expectError: false,
},
{
name: "vertical tab escape",
input: "\\v",
expected: '\v',
expectError: false,
},
{
name: "empty string",
input: "",
expected: 0,
expectError: true,
},
{
name: "multiple characters",
input: "ab",
expected: 0,
expectError: true,
},
{
name: "special character",
input: "ñ",
expected: 'ñ',
expectError: true, // This will fail because the Set function checks len(val) != 1
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var r rune
runeVal := newRuneVar(&r)
err := runeVal.Set(tt.input)
if tt.expectError {
if err == nil {
t.Errorf("Expected error for input %q, but got none", tt.input)
}
} else {
if err != nil {
t.Errorf("Unexpected error for input %q: %v", tt.input, err)
}
if r != tt.expected {
t.Errorf("Expected rune %q (%d), got %q (%d)",
string(tt.expected), tt.expected, string(r), r)
}
}
})
}
}
func TestRuneValue_Set_ErrorMessages(t *testing.T) {
tests := []struct {
name string
input string
expectedError string
}{
{
name: "empty string error",
input: "",
expectedError: "[] is not a valid character. Must be length 1 was 0",
},
{
name: "multiple characters error",
input: "abc",
expectedError: "[abc] is not a valid character. Must be length 1 was 3",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var r rune
runeVal := newRuneVar(&r)
err := runeVal.Set(tt.input)
if err == nil {
t.Errorf("Expected error for input %q, but got none", tt.input)
return
}
if !strings.Contains(err.Error(), tt.expectedError) {
t.Errorf("Expected error message to contain %q, got %q",
tt.expectedError, err.Error())
}
})
}
}
func TestRuneValue_Type(t *testing.T) {
var r rune
runeVal := newRuneVar(&r)
result := runeVal.Type()
expected := "char"
if result != expected {
t.Errorf("runeValue.Type() = %q, want %q", result, expected)
}
}
func TestNew(t *testing.T) {
rootCmd := New()
if rootCmd == nil {
t.Fatal("New() returned nil")
}
// Test basic command properties
if rootCmd.Use != "yq" {
t.Errorf("Expected Use to be 'yq', got %q", rootCmd.Use)
}
if rootCmd.Short == "" {
t.Error("Expected Short description to be non-empty")
}
if rootCmd.Long == "" {
t.Error("Expected Long description to be non-empty")
}
// Test that the command has the expected subcommands
expectedCommands := []string{"eval", "eval-all", "completion"}
actualCommands := make([]string, 0, len(rootCmd.Commands()))
for _, cmd := range rootCmd.Commands() {
actualCommands = append(actualCommands, cmd.Name())
}
for _, expected := range expectedCommands {
found := false
for _, actual := range actualCommands {
if actual == expected {
found = true
break
}
}
if !found {
t.Errorf("Expected command %q not found in actual commands: %v",
expected, actualCommands)
}
}
}
func TestNew_FlagCompletions(t *testing.T) {
rootCmd := New()
// Test that flag completion functions are registered
// This is a basic smoke test - we can't easily test the actual completion logic
// without more complex setup
flags := []string{
"output-format",
"input-format",
"xml-attribute-prefix",
"xml-content-name",
"xml-proc-inst-prefix",
"xml-directive-name",
"lua-prefix",
"lua-suffix",
"properties-separator",
"indent",
"front-matter",
"expression",
"split-exp",
}
for _, flagName := range flags {
flag := rootCmd.PersistentFlags().Lookup(flagName)
if flag == nil {
t.Errorf("Expected flag %q to exist", flagName)
}
}
}
================================================
FILE: cmd/unwrap_flag.go
================================================
package cmd
import (
"strconv"
"github.com/spf13/pflag"
)
type boolFlag interface {
pflag.Value
IsExplicitlySet() bool
IsSet() bool
}
type unwrapScalarFlagStrc struct {
explicitlySet bool
value bool
}
func newUnwrapFlag() boolFlag {
return &unwrapScalarFlagStrc{value: true}
}
func (f *unwrapScalarFlagStrc) IsExplicitlySet() bool {
return f.explicitlySet
}
func (f *unwrapScalarFlagStrc) IsSet() bool {
return f.value
}
func (f *unwrapScalarFlagStrc) String() string {
return strconv.FormatBool(f.value)
}
func (f *unwrapScalarFlagStrc) Set(value string) error {
v, err := strconv.ParseBool(value)
f.value = v
f.explicitlySet = true
return err
}
func (*unwrapScalarFlagStrc) Type() string {
return "bool"
}
================================================
FILE: cmd/utils.go
================================================
package cmd
import (
"fmt"
"io"
"os"
"strings"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
"gopkg.in/op/go-logging.v1"
)
func isAutomaticOutputFormat() bool {
return outputFormat == "" || outputFormat == "auto" || outputFormat == "a"
}
func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
cmd.SilenceUsage = true
setupColors()
expression, args, err := processArgs(args)
if err != nil {
return "", nil, err
}
if err := loadSplitFileExpression(); err != nil {
return "", nil, err
}
handleBackwardsCompatibility()
if err := validateCommandFlags(args); err != nil {
return "", nil, err
}
if err := configureFormats(args); err != nil {
return "", nil, err
}
configureUnwrapScalar()
return expression, args, nil
}
func setupColors() {
fileInfo, _ := os.Stdout.Stat()
if forceColor || (!forceNoColor && (fileInfo.Mode()&os.ModeCharDevice) != 0) {
colorsEnabled = true
}
}
func loadSplitFileExpression() error {
if splitFileExpFile != "" {
splitExpressionBytes, err := os.ReadFile(splitFileExpFile)
if err != nil {
return err
}
splitFileExp = string(splitExpressionBytes)
}
return nil
}
func handleBackwardsCompatibility() {
// backwards compatibility
if outputToJSON {
outputFormat = "json"
}
}
func validateCommandFlags(args []string) error {
if writeInplace && (len(args) == 0 || args[0] == "-") {
return fmt.Errorf("write in place flag only applicable when giving an expression and at least one file")
}
if frontMatter != "" && len(args) == 0 {
return fmt.Errorf("front matter flag only applicable when giving an expression and at least one file")
}
if writeInplace && splitFileExp != "" {
return fmt.Errorf("write in place cannot be used with split file")
}
if nullInput && len(args) > 0 {
return fmt.Errorf("cannot pass files in when using null-input flag")
}
return nil
}
func configureFormats(args []string) error {
inputFilename := ""
if len(args) > 0 {
inputFilename = args[0]
}
if err := configureInputFormat(inputFilename); err != nil {
return err
}
if err := configureOutputFormat(); err != nil {
return err
}
yqlib.GetLogger().Debug("Using input format %v", inputFormat)
yqlib.GetLogger().Debug("Using output format %v", outputFormat)
return nil
}
func configureInputFormat(inputFilename string) error {
if inputFormat == "" || inputFormat == "auto" || inputFormat == "a" {
inputFormat = yqlib.FormatStringFromFilename(inputFilename)
_, err := yqlib.FormatFromString(inputFormat)
if err != nil {
// unknown file type, default to yaml
yqlib.GetLogger().Debug("Unknown file format extension '%v', defaulting to yaml", inputFormat)
inputFormat = "yaml"
if isAutomaticOutputFormat() {
outputFormat = "yaml"
}
} else if isAutomaticOutputFormat() {
outputFormat = inputFormat
}
} else if isAutomaticOutputFormat() {
// backwards compatibility -
// before this was introduced, `yq -pcsv things.csv`
// would produce *yaml* output.
//
outputFormat = yqlib.FormatStringFromFilename(inputFilename)
if inputFilename != "-" {
yqlib.GetLogger().Warning("yq default output is now 'auto' (based on the filename extension). Normally yq would output '%v', but for backwards compatibility 'yaml' has been set. Please use -oy to specify yaml, or drop the -p flag.", outputFormat)
}
outputFormat = "yaml"
}
return nil
}
func configureOutputFormat() error {
outputFormatType, err := yqlib.FormatFromString(outputFormat)
if err != nil {
return err
}
if outputFormatType == yqlib.YamlFormat ||
outputFormatType == yqlib.PropertiesFormat {
unwrapScalar = true
}
return nil
}
func configureUnwrapScalar() {
if unwrapScalarFlag.IsExplicitlySet() {
unwrapScalar = unwrapScalarFlag.IsSet()
}
}
func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) {
format, err := yqlib.FormatFromString(inputFormat)
if err != nil {
return nil, err
}
yqlib.ConfiguredYamlPreferences.EvaluateTogether = evaluateTogether
if format.DecoderFactory == nil {
return nil, fmt.Errorf("no support for %s input format", inputFormat)
}
yqlibDecoder := format.DecoderFactory()
if yqlibDecoder == nil {
return nil, fmt.Errorf("no support for %s input format", inputFormat)
}
return yqlibDecoder, nil
}
func configurePrinterWriter(format *yqlib.Format, out io.Writer) (yqlib.PrinterWriter, error) {
var printerWriter yqlib.PrinterWriter
if splitFileExp != "" {
colorsEnabled = forceColor
splitExp, err := yqlib.ExpressionParser.ParseExpression(splitFileExp)
if err != nil {
return nil, fmt.Errorf("bad split document expression: %w", err)
}
printerWriter = yqlib.NewMultiPrinterWriter(splitExp, format)
} else {
printerWriter = yqlib.NewSinglePrinterWriter(out)
}
return printerWriter, nil
}
func configureEncoder() (yqlib.Encoder, error) {
yqlibOutputFormat, err := yqlib.FormatFromString(outputFormat)
if err != nil {
return nil, err
}
yqlib.ConfiguredXMLPreferences.Indent = indent
yqlib.ConfiguredYamlPreferences.Indent = indent
yqlib.ConfiguredKYamlPreferences.Indent = indent
yqlib.ConfiguredJSONPreferences.Indent = indent
yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredKYamlPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredPropertiesPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredJSONPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredShellVariablesPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredYamlPreferences.ColorsEnabled = colorsEnabled
yqlib.ConfiguredKYamlPreferences.ColorsEnabled = colorsEnabled
yqlib.ConfiguredJSONPreferences.ColorsEnabled = colorsEnabled
yqlib.ConfiguredHclPreferences.ColorsEnabled = colorsEnabled
yqlib.ConfiguredTomlPreferences.ColorsEnabled = colorsEnabled
yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators
yqlib.ConfiguredKYamlPreferences.PrintDocSeparators = !noDocSeparators
encoder := yqlibOutputFormat.EncoderFactory()
if encoder == nil {
return nil, fmt.Errorf("no support for %s output format", outputFormat)
}
return encoder, err
}
// this is a hack to enable backwards compatibility with githubactions (which pipe /dev/null into everything)
// and being able to call yq with the filename as a single parameter
//
// without this - yq detects there is stdin (thanks githubactions),
// then tries to parse the filename as an expression
func maybeFile(str string) bool {
yqlib.GetLogger().Debugf("checking '%v' is a file", str)
stat, err := os.Stat(str) // #nosec
result := err == nil && !stat.IsDir()
if yqlib.GetLogger().IsEnabledFor(logging.DEBUG) {
if err != nil {
yqlib.GetLogger().Debugf("error: %v", err)
} else {
yqlib.GetLogger().Debugf("error: %v, dir: %v", err, stat.IsDir())
}
yqlib.GetLogger().Debugf("result: %v", result)
}
return result
}
func processStdInArgs(args []string) []string {
stat, err := os.Stdin.Stat()
if err != nil {
yqlib.GetLogger().Debugf("error getting stdin: %v", err)
}
pipingStdin := stat != nil && (stat.Mode()&os.ModeCharDevice) == 0
// if we've been given a file, don't automatically
// read from stdin.
// this happens if there is more than one argument
// or only one argument and its a file
if nullInput || !pipingStdin || len(args) > 1 || (len(args) > 0 && maybeFile(args[0])) {
return args
}
for _, arg := range args {
if arg == "-" {
return args
}
}
yqlib.GetLogger().Debugf("missing '-', adding it to the end")
// we're piping from stdin, but there's no '-' arg
// lets add one to the end
return append(args, "-")
}
func processArgs(originalArgs []string) (string, []string, error) {
expression := forceExpression
args := processStdInArgs(originalArgs)
maybeFirstArgIsAFile := len(args) > 0 && maybeFile(args[0])
if expressionFile == "" && maybeFirstArgIsAFile && strings.HasSuffix(args[0], ".yq") {
// lets check if an expression file was given
yqlib.GetLogger().Debug("Assuming arg %v is an expression file", args[0])
expressionFile = args[0]
args = args[1:]
}
if expressionFile != "" {
expressionBytes, err := os.ReadFile(expressionFile)
if err != nil {
return "", nil, err
}
//replace \r\n (windows) with good ol' unix file endings.
expression = strings.ReplaceAll(string(expressionBytes), "\r\n", "\n")
}
yqlib.GetLogger().Debugf("processed args: %v", args)
if expression == "" && len(args) > 0 && args[0] != "-" && !maybeFile(args[0]) {
yqlib.GetLogger().Debug("assuming expression is '%v'", args[0])
expression = args[0]
args = args[1:]
}
return expression, args, nil
}
================================================
FILE: cmd/utils_test.go
================================================
package cmd
import (
"fmt"
"os"
"strings"
"testing"
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
)
func TestIsAutomaticOutputFormat(t *testing.T) {
tests := []struct {
name string
format string
expected bool
}{
{"empty format", "", true},
{"auto format", "auto", true},
{"short auto format", "a", true},
{"json format", "json", false},
{"yaml format", "yaml", false},
{"xml format", "xml", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original value
originalFormat := outputFormat
defer func() { outputFormat = originalFormat }()
outputFormat = tt.format
result := isAutomaticOutputFormat()
if result != tt.expected {
t.Errorf("isAutomaticOutputFormat() = %v, want %v", result, tt.expected)
}
})
}
}
func TestMaybeFile(t *testing.T) {
// Create a temporary file for testing
tempFile, err := os.CreateTemp("", "test")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tempFile.Name())
tempFile.Close()
// Create a temporary directory for testing
tempDir, err := os.MkdirTemp("", "test")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
tests := []struct {
name string
path string
expected bool
}{
{"existing file", tempFile.Name(), true},
{"existing directory", tempDir, false},
{"non-existent path", "/path/that/does/not/exist", false},
{"empty string", "", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := maybeFile(tt.path)
if result != tt.expected {
t.Errorf("maybeFile(%q) = %v, want %v", tt.path, result, tt.expected)
}
})
}
}
func TestProcessArgs(t *testing.T) {
// Create a temporary file for testing
tempFile, err := os.CreateTemp("", "test")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tempFile.Name())
tempFile.Close()
// Create a temporary .yq file for testing
tempYqFile, err := os.Create("test.yq")
if err != nil {
t.Fatalf("Failed to create temp yq file: %v", err)
}
defer os.Remove(tempYqFile.Name())
if _, err = tempYqFile.WriteString(".a.b"); err != nil {
t.Fatalf("Failed to write to temp yq file: %v", err)
}
tempYqFile.Close()
tests := []struct {
name string
args []string
forceExpression string
expressionFile string
expectedExpr string
expectedArgs []string
expectError bool
}{
{
name: "empty args",
args: []string{},
forceExpression: "",
expressionFile: "",
expectedExpr: "",
expectedArgs: []string{},
expectError: false,
},
{
name: "force expression",
args: []string{"file1"},
forceExpression: ".a.b",
expressionFile: "",
expectedExpr: ".a.b",
expectedArgs: []string{"file1"},
expectError: false,
},
{
name: "expression as first arg",
args: []string{".a.b", "file1"},
forceExpression: "",
expressionFile: "",
expectedExpr: ".a.b",
expectedArgs: []string{"file1"},
expectError: false,
},
{
name: "file as first arg",
args: []string{tempFile.Name()},
forceExpression: "",
expressionFile: "",
expectedExpr: "",
expectedArgs: []string{tempFile.Name()},
expectError: false,
},
{
name: "yq file as first arg",
args: []string{tempYqFile.Name(), "things"},
forceExpression: "",
expressionFile: "",
expectedExpr: ".a.b",
expectedArgs: []string{"things"},
expectError: false,
},
{
name: "dash as first arg",
args: []string{"-"},
forceExpression: "",
expressionFile: "",
expectedExpr: "",
expectedArgs: []string{"-"},
expectError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original values
originalForceExpression := forceExpression
originalExpressionFile := expressionFile
defer func() {
forceExpression = originalForceExpression
expressionFile = originalExpressionFile
}()
forceExpression = tt.forceExpression
expressionFile = tt.expressionFile
expr, args, err := processArgs(tt.args)
if tt.expectError {
if err == nil {
t.Errorf("processArgs() expected error but got none")
}
return
}
if err != nil {
t.Errorf("processArgs() unexpected error: %v", err)
return
}
if expr != tt.expectedExpr {
t.Errorf("processArgs() expression = %v, want %v", expr, tt.expectedExpr)
}
if !stringsEqual(args, tt.expectedArgs) {
t.Errorf("processArgs() args = %v, want %v", args, tt.expectedArgs)
}
})
}
}
func TestConfigureDecoder(t *testing.T) {
tests := []struct {
name string
inputFormat string
evaluateTogether bool
expectError bool
expectType string
}{
{
name: "yaml format",
inputFormat: "yaml",
evaluateTogether: false,
expectError: false,
expectType: "yamlDecoder",
},
{
name: "json format",
inputFormat: "json",
evaluateTogether: true,
expectError: false,
expectType: "jsonDecoder",
},
{
name: "xml format",
inputFormat: "xml",
evaluateTogether: false,
expectError: false,
expectType: "xmlDecoder",
},
{
name: "invalid format",
inputFormat: "invalid",
evaluateTogether: false,
expectError: true,
expectType: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original value
originalInputFormat := inputFormat
defer func() { inputFormat = originalInputFormat }()
inputFormat = tt.inputFormat
decoder, err := configureDecoder(tt.evaluateTogether)
if tt.expectError {
if err == nil {
t.Errorf("configureDecoder() expected error but got none")
}
if decoder != nil {
t.Errorf("configureDecoder() expected nil decoder but got %v", decoder)
}
return
}
if err != nil {
t.Errorf("configureDecoder() unexpected error: %v", err)
return
}
if decoder == nil {
t.Errorf("configureDecoder() expected decoder but got nil")
return
}
typeStr := fmt.Sprintf("%T", decoder)
if !strings.Contains(typeStr, tt.expectType) {
t.Errorf("configureDecoder() expected type to contain %q but got %q", tt.expectType, typeStr)
}
})
}
}
func TestConfigurePrinterWriter(t *testing.T) {
yqlib.InitExpressionParser()
tests := []struct {
name string
splitFileExp string
format *yqlib.Format
forceColor bool
expectError bool
expectMulti bool
expectColorsEnabled bool
}{
{
name: "single printer writer",
splitFileExp: "",
format: &yqlib.Format{},
forceColor: false,
expectError: false,
expectMulti: false,
expectColorsEnabled: false,
},
{
name: "multi printer writer with valid expression",
splitFileExp: ".a.b",
format: &yqlib.Format{},
forceColor: true,
expectError: false,
expectMulti: true,
expectColorsEnabled: true,
},
{
name: "multi printer writer with invalid expression",
splitFileExp: "[invalid",
format: &yqlib.Format{},
forceColor: false,
expectError: true,
expectMulti: false,
expectColorsEnabled: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original values
originalSplitFileExp := splitFileExp
originalForceColor := forceColor
originalColorsEnabled := colorsEnabled
defer func() {
splitFileExp = originalSplitFileExp
forceColor = originalForceColor
colorsEnabled = originalColorsEnabled
}()
splitFileExp = tt.splitFileExp
forceColor = tt.forceColor
colorsEnabled = false // Reset to test the setting
writer, err := configurePrinterWriter(tt.format, os.Stdout)
if tt.expectError {
if err == nil {
t.Errorf("configurePrinterWriter() expected error but got none")
}
if writer != nil {
t.Errorf("configurePrinterWriter() expected nil writer but got %v", writer)
}
return
}
if err != nil {
t.Errorf("configurePrinterWriter() unexpected error: %v", err)
return
}
if writer == nil {
t.Errorf("configurePrinterWriter() expected writer but got nil")
return
}
// Explicitly check colorsEnabled
if colorsEnabled != tt.expectColorsEnabled {
t.Errorf("configurePrinterWriter() colorsEnabled = %v, want %v", colorsEnabled, tt.expectColorsEnabled)
}
// Check the type of the returned writer
writerType := fmt.Sprintf("%T", writer)
if tt.expectMulti {
if !strings.Contains(writerType, "multiPrintWriter") {
t.Errorf("configurePrinterWriter() expected multiPrintWriter but got %s", writerType)
}
} else {
if !strings.Contains(writerType, "singlePrinterWriter") {
t.Errorf("configurePrinterWriter() expected singlePrinterWriter but got %s", writerType)
}
}
})
}
}
func TestConfigureEncoder(t *testing.T) {
tests := []struct {
name string
outputFormat string
expectError bool
expectType string
}{
{
name: "yaml format",
outputFormat: "yaml",
expectError: false,
expectType: "yamlEncoder",
},
{
name: "json format",
outputFormat: "json",
expectError: false,
expectType: "jsonEncoder",
},
{
name: "xml format",
outputFormat: "xml",
expectError: false,
expectType: "xmlEncoder",
},
{
name: "properties format",
outputFormat: "properties",
expectError: false,
expectType: "propertiesEncoder",
},
{
name: "invalid format",
outputFormat: "invalid",
expectError: true,
expectType: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original values
originalOutputFormat := outputFormat
originalIndent := indent
originalUnwrapScalar := unwrapScalar
originalColorsEnabled := colorsEnabled
originalNoDocSeparators := noDocSeparators
defer func() {
outputFormat = originalOutputFormat
indent = originalIndent
unwrapScalar = originalUnwrapScalar
colorsEnabled = originalColorsEnabled
noDocSeparators = originalNoDocSeparators
}()
outputFormat = tt.outputFormat
indent = 2
unwrapScalar = false
colorsEnabled = false
noDocSeparators = false
encoder, err := configureEncoder()
if tt.expectError {
if err == nil {
t.Errorf("configureEncoder() expected error but got none")
}
if encoder != nil {
t.Errorf("configureEncoder() expected nil encoder but got %v", encoder)
}
return
}
if err != nil {
t.Errorf("configureEncoder() unexpected error: %v", err)
return
}
if encoder == nil {
t.Errorf("configureEncoder() expected encoder but got nil")
return
}
typeStr := fmt.Sprintf("%T", encoder)
if !strings.Contains(typeStr, tt.expectType) {
t.Errorf("configureEncoder() expected type to contain %q but got %q", tt.expectType, typeStr)
}
})
}
}
func TestInitCommand(t *testing.T) {
// Create a temporary file for testing
tempFile, err := os.CreateTemp("", "test")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tempFile.Name())
tempFile.Close()
// Create a temporary split file
tempSplitFile, err := os.CreateTemp("", "split")
if err != nil {
t.Fatalf("Failed to create temp split file: %v", err)
}
defer os.Remove(tempSplitFile.Name())
if _, err = tempSplitFile.WriteString(".a.b"); err != nil {
t.Fatalf("Failed to write to temp split file: %v", err)
}
tempSplitFile.Close()
tests := []struct {
name string
args []string
writeInplace bool
frontMatter string
nullInput bool
splitFileExpFile string
splitFileExp string
outputToJSON bool
expectError bool
errorContains string
expectExpr string
expectArgs []string
}{
{
name: "basic command",
args: []string{tempFile.Name()},
writeInplace: false,
frontMatter: "",
nullInput: false,
expectError: false,
expectExpr: "",
expectArgs: []string{tempFile.Name()},
},
{
name: "write inplace with no args",
args: []string{},
writeInplace: true,
frontMatter: "",
nullInput: false,
expectError: true,
errorContains: "write in place flag only applicable when giving an expression and at least one file",
},
{
name: "split file expression from file",
args: []string{tempFile.Name()},
writeInplace: false,
frontMatter: "",
nullInput: false,
splitFileExpFile: tempSplitFile.Name(),
expectError: false,
expectExpr: "",
expectArgs: []string{tempFile.Name()},
},
{
name: "output to JSON",
args: []string{tempFile.Name()},
writeInplace: false,
frontMatter: "",
nullInput: false,
outputToJSON: true,
expectError: false,
expectExpr: "",
expectArgs: []string{tempFile.Name()},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original values
originalWriteInplace := writeInplace
originalFrontMatter := frontMatter
originalNullInput := nullInput
originalSplitFileExpFile := splitFileExpFile
originalSplitFileExp := splitFileExp
originalOutputToJSON := outputToJSON
originalInputFormat := inputFormat
originalOutputFormat := outputFormat
originalForceColor := forceColor
originalForceNoColor := forceNoColor
originalColorsEnabled := colorsEnabled
defer func() {
writeInplace = originalWriteInplace
frontMatter = originalFrontMatter
nullInput = originalNullInput
splitFileExpFile = originalSplitFileExpFile
splitFileExp = originalSplitFileExp
outputToJSON = originalOutputToJSON
inputFormat = originalInputFormat
outputFormat = originalOutputFormat
forceColor = originalForceColor
forceNoColor = originalForceNoColor
colorsEnabled = originalColorsEnabled
}()
writeInplace = tt.writeInplace
frontMatter = tt.frontMatter
nullInput = tt.nullInput
splitFileExpFile = tt.splitFileExpFile
splitFileExp = tt.splitFileExp
outputToJSON = tt.outputToJSON
inputFormat = "auto"
outputFormat = "auto"
forceColor = false
forceNoColor = false
colorsEnabled = false
cmd := &cobra.Command{}
expr, args, err := initCommand(cmd, tt.args)
if tt.expectError {
if err == nil {
t.Errorf("initCommand() expected error but got none")
return
}
if tt.errorContains != "" && !strings.Contains(err.Error(), tt.errorContains) {
t.Errorf("initCommand() error '%v' does not contain '%v'", err.Error(), tt.errorContains)
}
return
}
if err != nil {
t.Errorf("initCommand() unexpected error: %v", err)
return
}
if expr != tt.expectExpr {
t.Errorf("initCommand() expr = %v, want %v", expr, tt.expectExpr)
}
if !stringsEqual(args, tt.expectArgs) {
t.Errorf("initCommand() args = %v, want %v", args, tt.expectArgs)
}
})
}
}
func TestProcessArgsWithExpressionFile(t *testing.T) {
// Create a temporary .yq file with Windows line endings
tempYqFile, err := os.CreateTemp("", "test.yq")
if err != nil {
t.Fatalf("Failed to create temp yq file: %v", err)
}
defer os.Remove(tempYqFile.Name())
if _, err = tempYqFile.WriteString(".a.b\r\n.c.d"); err != nil {
t.Fatalf("Failed to write to temp yq file: %v", err)
}
tempYqFile.Close()
// Save original values
originalExpressionFile := expressionFile
defer func() { expressionFile = originalExpressionFile }()
expressionFile = tempYqFile.Name()
expr, args, err := processArgs([]string{"file1"})
if err != nil {
t.Errorf("processArgs() unexpected error: %v", err)
return
}
expectedExpr := ".a.b\n.c.d" // Should convert \r\n to \n
if expr != expectedExpr {
t.Errorf("processArgs() expression = %v, want %v", expr, expectedExpr)
}
expectedArgs := []string{"file1"}
if !stringsEqual(args, expectedArgs) {
t.Errorf("processArgs() args = %v, want %v", args, expectedArgs)
}
}
func TestProcessArgsWithNonExistentExpressionFile(t *testing.T) {
// Save original values
originalExpressionFile := expressionFile
defer func() { expressionFile = originalExpressionFile }()
expressionFile = "/path/that/does/not/exist"
expr, args, err := processArgs([]string{"file1"})
if err == nil {
t.Errorf("processArgs() expected error but got none")
}
if expr != "" {
t.Errorf("processArgs() expected empty expression but got %v", expr)
}
if args != nil {
t.Errorf("processArgs() expected nil args but got %v", args)
}
}
func TestInitCommandWithInvalidOutputFormat(t *testing.T) {
// Create a temporary file for testing
tempFile, err := os.CreateTemp("", "test")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tempFile.Name())
tempFile.Close()
// Save original values
originalInputFormat := inputFormat
originalOutputFormat := outputFormat
defer func() {
inputFormat = originalInputFormat
outputFormat = originalOutputFormat
}()
inputFormat = "auto"
outputFormat = "invalid"
cmd := &cobra.Command{}
expr, args, err := initCommand(cmd, []string{tempFile.Name()})
if err == nil {
t.Errorf("initCommand() expected error but got none")
}
if expr != "" {
t.Errorf("initCommand() expected empty expression but got %v", expr)
}
if args != nil {
t.Errorf("initCommand() expected nil args but got %v", args)
}
}
func TestInitCommandWithUnknownInputFormat(t *testing.T) {
// Create a temporary file with unknown extension
tempFile, err := os.CreateTemp("", "test.unknown")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(tempFile.Name())
tempFile.Close()
// Save origi
gitextract_0o7jw5o7/ ├── .dockerignore ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report_v4.md │ │ └── feature_request.md │ ├── dependabot.yml │ ├── instructions/ │ │ └── instructions.md │ └── workflows/ │ ├── codeql.yml │ ├── docker-release.yml │ ├── go.yml │ ├── release.yml │ └── snap-release.yml ├── .gitignore ├── .golangci.bck.yml ├── .golangci.yml ├── .goreleaser.yaml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── Dockerfile.dev ├── LICENSE ├── Makefile ├── Makefile.variables ├── README.md ├── acceptance_tests/ │ ├── bad_args.sh │ ├── basic.sh │ ├── completion.sh │ ├── empty.sh │ ├── flags.sh │ ├── front-matter.sh │ ├── header-processing-off.sh │ ├── inputs-format-auto.sh │ ├── inputs-format.sh │ ├── leading-separator.sh │ ├── load-file.sh │ ├── nul-separator.sh │ ├── output-format.sh │ ├── pipe.sh │ ├── pretty-print.sh │ ├── shebang.sh │ └── split-printer.sh ├── action.yml ├── agents.md ├── cmd/ │ ├── completion.go │ ├── constant.go │ ├── evaluate_all_command.go │ ├── evaluate_all_command_test.go │ ├── evaluate_sequence_command.go │ ├── evaluate_sequence_command_test.go │ ├── root.go │ ├── root_test.go │ ├── unwrap_flag.go │ ├── utils.go │ ├── utils_test.go │ ├── version.go │ └── version_test.go ├── cspell.config.yaml ├── examples/ │ ├── array.yaml │ ├── bad.yaml │ ├── base64.txt │ ├── data.lua │ ├── data1-no-comments.yaml │ ├── data1.yaml │ ├── data2.yaml │ ├── data3.yaml │ ├── empty-no-comment.yaml │ ├── empty.yaml │ ├── environment.yq │ ├── example.properties │ ├── front-matter.yaml │ ├── instruction_sample.yaml │ ├── kyaml.yml │ ├── leading-separator.yaml │ ├── merge-anchor.yaml │ ├── mike.xml │ ├── mike2.xml │ ├── multiline-text.yaml │ ├── multiple_docs.yaml │ ├── multiple_docs_small.yaml │ ├── numbered_keys.yml │ ├── order.yaml │ ├── order.yml │ ├── sample.hcl │ ├── sample.ini │ ├── sample.json │ ├── sample.tf │ ├── sample.toml │ ├── sample.yaml │ ├── sample2.hcl │ ├── sample_array.yaml │ ├── sample_array_2.yaml │ ├── sample_no_sections.ini │ ├── sample_objects.csv │ ├── sample_text.yaml │ ├── simple-anchor-exploded.yaml │ ├── simple-anchor.yaml │ ├── small.properties │ ├── small.xml │ ├── small.yaml │ └── thing.yml ├── github-action/ │ ├── Dockerfile │ └── entrypoint.sh ├── go.mod ├── go.sum ├── go_install_test.go ├── how-it-works.md ├── mkdocs.yml ├── pkg/ │ └── yqlib/ │ ├── all_at_once_evaluator.go │ ├── all_at_once_evaluator_test.go │ ├── base64_test.go │ ├── candidate_node.go │ ├── candidate_node_goccy_yaml.go │ ├── candidate_node_test.go │ ├── candidate_node_yaml.go │ ├── candidiate_node_json.go │ ├── chown_linux.go │ ├── chown_linux_test.go │ ├── chown_not_linux_os.go │ ├── color_print.go │ ├── color_print_test.go │ ├── context.go │ ├── context_test.go │ ├── csv.go │ ├── csv_test.go │ ├── data_tree_navigator.go │ ├── data_tree_navigator_test.go │ ├── decoder.go │ ├── decoder_base64.go │ ├── decoder_csv_object.go │ ├── decoder_goccy_yaml.go │ ├── decoder_hcl.go │ ├── decoder_ini.go │ ├── decoder_json.go │ ├── decoder_lua.go │ ├── decoder_properties.go │ ├── decoder_test.go │ ├── decoder_toml.go │ ├── decoder_uri.go │ ├── decoder_uri_test.go │ ├── decoder_xml.go │ ├── decoder_yaml.go │ ├── doc/ │ │ ├── .gitignore │ │ ├── notification-snippet.md │ │ ├── operators/ │ │ │ ├── add.md │ │ │ ├── alternative-default-value.md │ │ │ ├── anchor-and-alias-operators.md │ │ │ ├── array-to-map.md │ │ │ ├── assign-update.md │ │ │ ├── boolean-operators.md │ │ │ ├── collect-into-array.md │ │ │ ├── column.md │ │ │ ├── comment-operators.md │ │ │ ├── compare.md │ │ │ ├── contains.md │ │ │ ├── create-collect-into-object.md │ │ │ ├── datetime.md │ │ │ ├── delete.md │ │ │ ├── divide.md │ │ │ ├── document-index.md │ │ │ ├── encode-decode.md │ │ │ ├── entries.md │ │ │ ├── env-variable-operators.md │ │ │ ├── equals.md │ │ │ ├── error.md │ │ │ ├── eval.md │ │ │ ├── file-operators.md │ │ │ ├── filter.md │ │ │ ├── first.md │ │ │ ├── flatten.md │ │ │ ├── group-by.md │ │ │ ├── has.md │ │ │ ├── headers/ │ │ │ │ ├── Main.md │ │ │ │ ├── add.md │ │ │ │ ├── alternative-default-value.md │ │ │ │ ├── anchor-and-alias-operators.md │ │ │ │ ├── array-to-map.md │ │ │ │ ├── assign-update.md │ │ │ │ ├── boolean-operators.md │ │ │ │ ├── collect-into-array.md │ │ │ │ ├── column.md │ │ │ │ ├── comment-operators.md │ │ │ │ ├── compare.md │ │ │ │ ├── contains.md │ │ │ │ ├── create-collect-into-object.md │ │ │ │ ├── datetime.md │ │ │ │ ├── delete.md │ │ │ │ ├── divide.md │ │ │ │ ├── document-index.md │ │ │ │ ├── encode-decode.md │ │ │ │ ├── entries.md │ │ │ │ ├── env-variable-operators.md │ │ │ │ ├── equals.md │ │ │ │ ├── error.md │ │ │ │ ├── eval.md │ │ │ │ ├── file-operators.md │ │ │ │ ├── filter.md │ │ │ │ ├── first.md │ │ │ │ ├── flatten.md │ │ │ │ ├── group-by.md │ │ │ │ ├── has.md │ │ │ │ ├── keys.md │ │ │ │ ├── kind.md │ │ │ │ ├── length.md │ │ │ │ ├── line.md │ │ │ │ ├── load.md │ │ │ │ ├── map.md │ │ │ │ ├── max.md │ │ │ │ ├── min.md │ │ │ │ ├── modulo.md │ │ │ │ ├── multiply-merge.md │ │ │ │ ├── omit.md │ │ │ │ ├── parent.md │ │ │ │ ├── path.md │ │ │ │ ├── pick.md │ │ │ │ ├── pipe.md │ │ │ │ ├── pivot.md │ │ │ │ ├── recursive-descent-glob.md │ │ │ │ ├── reduce.md │ │ │ │ ├── reverse.md │ │ │ │ ├── select.md │ │ │ │ ├── shuffle.md │ │ │ │ ├── slice-array.md │ │ │ │ ├── sort-keys.md │ │ │ │ ├── sort.md │ │ │ │ ├── split-into-documents.md │ │ │ │ ├── string-operators.md │ │ │ │ ├── style.md │ │ │ │ ├── subtract.md │ │ │ │ ├── tag.md │ │ │ │ ├── to_number.md │ │ │ │ ├── traverse-read.md │ │ │ │ ├── union.md │ │ │ │ ├── unique.md │ │ │ │ ├── variable-operators.md │ │ │ │ └── with.md │ │ │ ├── keys.md │ │ │ ├── kind.md │ │ │ ├── length.md │ │ │ ├── line.md │ │ │ ├── load.md │ │ │ ├── map.md │ │ │ ├── max.md │ │ │ ├── min.md │ │ │ ├── modulo.md │ │ │ ├── multiply-merge.md │ │ │ ├── omit.md │ │ │ ├── parent.md │ │ │ ├── path.md │ │ │ ├── pick.md │ │ │ ├── pipe.md │ │ │ ├── pivot.md │ │ │ ├── recursive-descent-glob.md │ │ │ ├── reduce.md │ │ │ ├── reverse.md │ │ │ ├── select.md │ │ │ ├── shuffle.md │ │ │ ├── slice-array.md │ │ │ ├── sort-keys.md │ │ │ ├── sort.md │ │ │ ├── split-into-documents.md │ │ │ ├── string-operators.md │ │ │ ├── style.md │ │ │ ├── subtract.md │ │ │ ├── tag.md │ │ │ ├── to_number.md │ │ │ ├── traverse-read.md │ │ │ ├── union.md │ │ │ ├── unique.md │ │ │ ├── variable-operators.md │ │ │ └── with.md │ │ └── usage/ │ │ ├── base64.md │ │ ├── convert.md │ │ ├── csv-tsv.md │ │ ├── formatting-expressions.md │ │ ├── hcl.md │ │ ├── headers/ │ │ │ ├── base64.md │ │ │ ├── convert.md │ │ │ ├── csv-tsv.md │ │ │ ├── formatting-expressions.md │ │ │ ├── hcl.md │ │ │ ├── kyaml.md │ │ │ ├── properties.md │ │ │ ├── recipes.md │ │ │ ├── toml.md │ │ │ └── xml.md │ │ ├── kyaml.md │ │ ├── lua.md │ │ ├── properties.md │ │ ├── recipes.md │ │ ├── shellvariables.md │ │ ├── toml.md │ │ └── xml.md │ ├── encoder.go │ ├── encoder_base64.go │ ├── encoder_csv.go │ ├── encoder_hcl.go │ ├── encoder_ini.go │ ├── encoder_json.go │ ├── encoder_kyaml.go │ ├── encoder_lua.go │ ├── encoder_properties.go │ ├── encoder_properties_test.go │ ├── encoder_sh.go │ ├── encoder_shellvariables.go │ ├── encoder_shellvariables_test.go │ ├── encoder_test.go │ ├── encoder_toml.go │ ├── encoder_uri.go │ ├── encoder_xml.go │ ├── encoder_yaml.go │ ├── expression_parser.go │ ├── expression_parser_test.go │ ├── expression_postfix.go │ ├── expression_processing_test.go │ ├── file_utils.go │ ├── format.go │ ├── format_test.go │ ├── formatting_expressions_test.go │ ├── front_matter.go │ ├── front_matter_test.go │ ├── goccy_yaml_test.go │ ├── hcl.go │ ├── hcl_test.go │ ├── ini.go │ ├── ini_test.go │ ├── json.go │ ├── json_test.go │ ├── kyaml.go │ ├── kyaml_test.go │ ├── lexer.go │ ├── lexer_participle.go │ ├── lexer_participle_test.go │ ├── lib.go │ ├── lib_test.go │ ├── lua.go │ ├── lua_test.go │ ├── matchKeyString.go │ ├── matchKeyString_test.go │ ├── no_base64.go │ ├── no_csv.go │ ├── no_hcl.go │ ├── no_ini.go │ ├── no_json.go │ ├── no_kyaml.go │ ├── no_lua.go │ ├── no_props.go │ ├── no_sh.go │ ├── no_shellvariables.go │ ├── no_toml.go │ ├── no_uri.go │ ├── no_xml.go │ ├── operation.go │ ├── operator_add.go │ ├── operator_add_test.go │ ├── operator_alternative.go │ ├── operator_alternative_test.go │ ├── operator_anchors_aliases.go │ ├── operator_anchors_aliases_test.go │ ├── operator_array_to_map_test.go │ ├── operator_assign.go │ ├── operator_assign_test.go │ ├── operator_booleans.go │ ├── operator_booleans_test.go │ ├── operator_collect.go │ ├── operator_collect_object.go │ ├── operator_collect_object_test.go │ ├── operator_collect_test.go │ ├── operator_column.go │ ├── operator_column_test.go │ ├── operator_comments.go │ ├── operator_comments_test.go │ ├── operator_compare.go │ ├── operator_contains.go │ ├── operator_contains_test.go │ ├── operator_create_map.go │ ├── operator_create_map_test.go │ ├── operator_datetime.go │ ├── operator_datetime_test.go │ ├── operator_delete.go │ ├── operator_delete_test.go │ ├── operator_divide.go │ ├── operator_divide_test.go │ ├── operator_document_index.go │ ├── operator_document_index_test.go │ ├── operator_encoder_decoder.go │ ├── operator_encoder_decoder_test.go │ ├── operator_entries.go │ ├── operator_entries_test.go │ ├── operator_env.go │ ├── operator_env_test.go │ ├── operator_equals.go │ ├── operator_equals_test.go │ ├── operator_error.go │ ├── operator_error_test.go │ ├── operator_eval.go │ ├── operator_eval_test.go │ ├── operator_expression.go │ ├── operator_file.go │ ├── operator_file_test.go │ ├── operator_filter.go │ ├── operator_filter_test.go │ ├── operator_first.go │ ├── operator_first_test.go │ ├── operator_flatten.go │ ├── operator_flatten_test.go │ ├── operator_group_by.go │ ├── operator_group_by_test.go │ ├── operator_has.go │ ├── operator_has_test.go │ ├── operator_keys.go │ ├── operator_keys_test.go │ ├── operator_kind.go │ ├── operator_kind_test.go │ ├── operator_length.go │ ├── operator_length_test.go │ ├── operator_line.go │ ├── operator_line_test.go │ ├── operator_load.go │ ├── operator_load_test.go │ ├── operator_map.go │ ├── operator_map_test.go │ ├── operator_modulo.go │ ├── operator_modulo_test.go │ ├── operator_multiply.go │ ├── operator_multiply_test.go │ ├── operator_omit.go │ ├── operator_omit_test.go │ ├── operator_parent.go │ ├── operator_parent_test.go │ ├── operator_path.go │ ├── operator_path_test.go │ ├── operator_pick.go │ ├── operator_pick_test.go │ ├── operator_pipe.go │ ├── operator_pipe_test.go │ ├── operator_pivot.go │ ├── operator_pivot_test.go │ ├── operator_recursive_descent.go │ ├── operator_recursive_descent_test.go │ ├── operator_reduce.go │ ├── operator_reduce_test.go │ ├── operator_reverse.go │ ├── operator_reverse_test.go │ ├── operator_select.go │ ├── operator_select_test.go │ ├── operator_self.go │ ├── operator_shuffle.go │ ├── operator_shuffle_test.go │ ├── operator_slice.go │ ├── operator_slice_test.go │ ├── operator_sort.go │ ├── operator_sort_keys.go │ ├── operator_sort_keys_test.go │ ├── operator_sort_test.go │ ├── operator_split_document.go │ ├── operator_split_document_test.go │ ├── operator_strings.go │ ├── operator_strings_test.go │ ├── operator_style.go │ ├── operator_style_test.go │ ├── operator_subtract.go │ ├── operator_subtract_test.go │ ├── operator_tag.go │ ├── operator_tag_test.go │ ├── operator_to_number.go │ ├── operator_to_number_test.go │ ├── operator_traverse_path.go │ ├── operator_traverse_path_test.go │ ├── operator_union.go │ ├── operator_union_test.go │ ├── operator_unique.go │ ├── operator_unique_test.go │ ├── operator_value.go │ ├── operator_value_test.go │ ├── operator_variables.go │ ├── operator_variables_test.go │ ├── operator_with.go │ ├── operator_with_test.go │ ├── operators.go │ ├── operators_compare_test.go │ ├── operators_test.go │ ├── printer.go │ ├── printer_node_info.go │ ├── printer_node_info_test.go │ ├── printer_test.go │ ├── printer_writer.go │ ├── properties.go │ ├── properties_test.go │ ├── recipes_test.go │ ├── security_prefs.go │ ├── shellvariables.go │ ├── shellvariables_test.go │ ├── stream_evaluator.go │ ├── string_evaluator.go │ ├── string_evaluator_test.go │ ├── toml.go │ ├── toml_test.go │ ├── utils.go │ ├── write_in_place_handler.go │ ├── write_in_place_handler_test.go │ ├── xml.go │ ├── xml_test.go │ ├── yaml.go │ └── yaml_test.go ├── project-words.txt ├── release_instructions.txt ├── release_notes.txt ├── scripts/ │ ├── acceptance.sh │ ├── build-small-yq.sh │ ├── build-tinygo-yq.sh │ ├── bump-version.sh │ ├── check.sh │ ├── compare-jq.sh │ ├── compare-versions-output.sh │ ├── copy-docs.sh │ ├── coverage.sh │ ├── devtools.sh │ ├── extract-checksum.sh │ ├── format.sh │ ├── generate-man-page-md.sh │ ├── generate-man-page.sh │ ├── install-man-page.sh │ ├── release-deb.sh │ ├── secure.sh │ ├── setup.sh │ ├── shunit2 │ ├── spelling.sh │ ├── test-docker.sh │ ├── test.sh │ └── xcompile.sh ├── snap/ │ └── snapcraft.yaml ├── test/ │ ├── format_test.go │ └── utils.go ├── test.yq ├── utf8.csv ├── yq.go └── yq_test.go
SYMBOL INDEX (1406 symbols across 262 files)
FILE: cmd/evaluate_all_command.go
function createEvaluateAllCommand (line 10) | func createEvaluateAllCommand() *cobra.Command {
function evaluateAll (line 47) | func evaluateAll(cmd *cobra.Command, args []string) (cmdError error) {
FILE: cmd/evaluate_all_command_test.go
function TestCreateEvaluateAllCommand (line 11) | func TestCreateEvaluateAllCommand(t *testing.T) {
function TestEvaluateAll_NoArgs (line 44) | func TestEvaluateAll_NoArgs(t *testing.T) {
function TestEvaluateAll_NullInput (line 69) | func TestEvaluateAll_NullInput(t *testing.T) {
function TestEvaluateAll_WithSingleFile (line 89) | func TestEvaluateAll_WithSingleFile(t *testing.T) {
function TestEvaluateAll_WithMultipleFiles (line 120) | func TestEvaluateAll_WithMultipleFiles(t *testing.T) {
function TestEvaluateAll_WithExpression (line 159) | func TestEvaluateAll_WithExpression(t *testing.T) {
function TestEvaluateAll_WriteInPlace (line 190) | func TestEvaluateAll_WriteInPlace(t *testing.T) {
function TestEvaluateAll_ExitStatus (line 232) | func TestEvaluateAll_ExitStatus(t *testing.T) {
function TestEvaluateAll_WithMultipleDocuments (line 263) | func TestEvaluateAll_WithMultipleDocuments(t *testing.T) {
function TestEvaluateAll_NulSepOutput (line 294) | func TestEvaluateAll_NulSepOutput(t *testing.T) {
FILE: cmd/evaluate_sequence_command.go
function createEvaluateSequenceCommand (line 11) | func createEvaluateSequenceCommand() *cobra.Command {
function processExpression (line 51) | func processExpression(expression string) string {
function evaluateSequence (line 61) | func evaluateSequence(cmd *cobra.Command, args []string) (cmdError error) {
FILE: cmd/evaluate_sequence_command_test.go
function TestCreateEvaluateSequenceCommand (line 11) | func TestCreateEvaluateSequenceCommand(t *testing.T) {
function TestProcessExpression (line 44) | func TestProcessExpression(t *testing.T) {
function TestEvaluateSequence_NoArgs (line 98) | func TestEvaluateSequence_NoArgs(t *testing.T) {
function TestEvaluateSequence_NullInput (line 123) | func TestEvaluateSequence_NullInput(t *testing.T) {
function TestEvaluateSequence_WithFile (line 143) | func TestEvaluateSequence_WithFile(t *testing.T) {
function TestEvaluateSequence_WithExpressionAndFile (line 174) | func TestEvaluateSequence_WithExpressionAndFile(t *testing.T) {
function TestEvaluateSequence_WriteInPlace (line 205) | func TestEvaluateSequence_WriteInPlace(t *testing.T) {
function TestEvaluateSequence_ExitStatus (line 247) | func TestEvaluateSequence_ExitStatus(t *testing.T) {
FILE: cmd/root.go
type runeValue (line 13) | type runeValue
method String (line 19) | func (r *runeValue) String() string {
method Set (line 23) | func (r *runeValue) Set(rawVal string) error {
method Type (line 36) | func (r *runeValue) Type() string {
function newRuneVar (line 15) | func newRuneVar(p *rune) *runeValue {
function New (line 40) | func New() *cobra.Command {
FILE: cmd/root_test.go
function TestNewRuneVar (line 8) | func TestNewRuneVar(t *testing.T) {
function TestRuneValue_String (line 17) | func TestRuneValue_String(t *testing.T) {
function TestRuneValue_Set (line 56) | func TestRuneValue_Set(t *testing.T) {
function TestRuneValue_Set_ErrorMessages (line 143) | func TestRuneValue_Set_ErrorMessages(t *testing.T) {
function TestRuneValue_Type (line 181) | func TestRuneValue_Type(t *testing.T) {
function TestNew (line 193) | func TestNew(t *testing.T) {
function TestNew_FlagCompletions (line 236) | func TestNew_FlagCompletions(t *testing.T) {
FILE: cmd/unwrap_flag.go
type boolFlag (line 9) | type boolFlag interface
type unwrapScalarFlagStrc (line 15) | type unwrapScalarFlagStrc struct
method IsExplicitlySet (line 24) | func (f *unwrapScalarFlagStrc) IsExplicitlySet() bool {
method IsSet (line 28) | func (f *unwrapScalarFlagStrc) IsSet() bool {
method String (line 32) | func (f *unwrapScalarFlagStrc) String() string {
method Set (line 36) | func (f *unwrapScalarFlagStrc) Set(value string) error {
method Type (line 44) | func (*unwrapScalarFlagStrc) Type() string {
function newUnwrapFlag (line 20) | func newUnwrapFlag() boolFlag {
FILE: cmd/utils.go
function isAutomaticOutputFormat (line 14) | func isAutomaticOutputFormat() bool {
function initCommand (line 18) | func initCommand(cmd *cobra.Command, args []string) (string, []string, e...
function setupColors (line 47) | func setupColors() {
function loadSplitFileExpression (line 55) | func loadSplitFileExpression() error {
function handleBackwardsCompatibility (line 66) | func handleBackwardsCompatibility() {
function validateCommandFlags (line 73) | func validateCommandFlags(args []string) error {
function configureFormats (line 93) | func configureFormats(args []string) error {
function configureInputFormat (line 113) | func configureInputFormat(inputFilename string) error {
function configureOutputFormat (line 142) | func configureOutputFormat() error {
function configureUnwrapScalar (line 156) | func configureUnwrapScalar() {
function configureDecoder (line 162) | func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) {
function configurePrinterWriter (line 179) | func configurePrinterWriter(format *yqlib.Format, out io.Writer) (yqlib....
function configureEncoder (line 196) | func configureEncoder() (yqlib.Encoder, error) {
function maybeFile (line 234) | func maybeFile(str string) bool {
function processStdInArgs (line 249) | func processStdInArgs(args []string) []string {
function processArgs (line 276) | func processArgs(originalArgs []string) (string, []string, error) {
FILE: cmd/utils_test.go
function TestIsAutomaticOutputFormat (line 13) | func TestIsAutomaticOutputFormat(t *testing.T) {
function TestMaybeFile (line 42) | func TestMaybeFile(t *testing.T) {
function TestProcessArgs (line 79) | func TestProcessArgs(t *testing.T) {
function TestConfigureDecoder (line 201) | func TestConfigureDecoder(t *testing.T) {
function TestConfigurePrinterWriter (line 276) | func TestConfigurePrinterWriter(t *testing.T) {
function TestConfigureEncoder (line 374) | func TestConfigureEncoder(t *testing.T) {
function TestInitCommand (line 464) | func TestInitCommand(t *testing.T) {
function TestProcessArgsWithExpressionFile (line 609) | func TestProcessArgsWithExpressionFile(t *testing.T) {
function TestProcessArgsWithNonExistentExpressionFile (line 644) | func TestProcessArgsWithNonExistentExpressionFile(t *testing.T) {
function TestInitCommandWithInvalidOutputFormat (line 663) | func TestInitCommandWithInvalidOutputFormat(t *testing.T) {
function TestInitCommandWithUnknownInputFormat (line 696) | func TestInitCommandWithUnknownInputFormat(t *testing.T) {
function TestConfigurePrinterWriterWithInvalidSplitExpression (line 730) | func TestConfigurePrinterWriterWithInvalidSplitExpression(t *testing.T) {
function TestMaybeFileWithDirectory (line 749) | func TestMaybeFileWithDirectory(t *testing.T) {
function TestProcessStdInArgsWithDash (line 763) | func TestProcessStdInArgsWithDash(t *testing.T) {
function TestProcessArgsWithYqFileExtension (line 771) | func TestProcessArgsWithYqFileExtension(t *testing.T) {
function TestConfigureEncoderWithYamlFormat (line 818) | func TestConfigureEncoderWithYamlFormat(t *testing.T) {
function TestConfigureEncoderWithPropertiesFormat (line 850) | func TestConfigureEncoderWithPropertiesFormat(t *testing.T) {
type mockBoolFlag (line 883) | type mockBoolFlag struct
method IsExplicitlySet (line 888) | func (f *mockBoolFlag) IsExplicitlySet() bool {
method IsSet (line 892) | func (f *mockBoolFlag) IsSet() bool {
method String (line 896) | func (f *mockBoolFlag) String() string {
method Set (line 900) | func (f *mockBoolFlag) Set(_ string) error {
method Type (line 904) | func (f *mockBoolFlag) Type() string {
function stringsEqual (line 909) | func stringsEqual(a, b []string) bool {
function TestSetupColors (line 921) | func TestSetupColors(t *testing.T) {
function TestLoadSplitFileExpression (line 967) | func TestLoadSplitFileExpression(t *testing.T) {
function TestHandleBackwardsCompatibility (line 1038) | func TestHandleBackwardsCompatibility(t *testing.T) {
function TestValidateCommandFlags (line 1081) | func TestValidateCommandFlags(t *testing.T) {
function TestConfigureFormats (line 1191) | func TestConfigureFormats(t *testing.T) {
function TestConfigureInputFormat (line 1243) | func TestConfigureInputFormat(t *testing.T) {
function TestConfigureOutputFormat (line 1315) | func TestConfigureOutputFormat(t *testing.T) {
function TestConfigureUnwrapScalar (line 1381) | func TestConfigureUnwrapScalar(t *testing.T) {
FILE: cmd/version.go
constant ProductName (line 23) | ProductName = "yq"
function GetVersionDisplay (line 27) | func GetVersionDisplay() string {
function getHumanVersion (line 31) | func getHumanVersion() string {
FILE: cmd/version_test.go
function TestGetVersionDisplay (line 8) | func TestGetVersionDisplay(t *testing.T) {
function Test_getHumanVersion (line 30) | func Test_getHumanVersion(t *testing.T) {
function Test_getHumanVersion_NoGitDescribe (line 68) | func Test_getHumanVersion_NoGitDescribe(t *testing.T) {
function Test_getHumanVersion_WithPrerelease (line 91) | func Test_getHumanVersion_WithPrerelease(t *testing.T) {
function Test_getHumanVersion_PrereleaseInVersion (line 115) | func Test_getHumanVersion_PrereleaseInVersion(t *testing.T) {
function Test_getHumanVersion_StripSingleQuotes (line 140) | func Test_getHumanVersion_StripSingleQuotes(t *testing.T) {
function TestProductName (line 168) | func TestProductName(t *testing.T) {
function TestVersionIsSet (line 174) | func TestVersionIsSet(t *testing.T) {
FILE: go_install_test.go
function TestGoInstallCompatibility (line 15) | func TestGoInstallCompatibility(t *testing.T) {
FILE: pkg/yqlib/all_at_once_evaluator.go
type Evaluator (line 8) | type Evaluator interface
type allAtOnceEvaluator (line 18) | type allAtOnceEvaluator struct
method EvaluateNodes (line 27) | func (e *allAtOnceEvaluator) EvaluateNodes(expression string, nodes .....
method EvaluateCandidateNodes (line 35) | func (e *allAtOnceEvaluator) EvaluateCandidateNodes(expression string,...
method EvaluateFiles (line 47) | func (e *allAtOnceEvaluator) EvaluateFiles(expression string, filename...
function NewAllAtOnceEvaluator (line 22) | func NewAllAtOnceEvaluator() Evaluator {
FILE: pkg/yqlib/all_at_once_evaluator_test.go
function TestAllAtOnceEvaluateNodes (line 35) | func TestAllAtOnceEvaluateNodes(t *testing.T) {
FILE: pkg/yqlib/base64_test.go
constant base64EncodedSimple (line 13) | base64EncodedSimple = "YSBzcGVjaWFsIHN0cmluZw=="
constant base64DecodedSimpleExtraSpaces (line 14) | base64DecodedSimpleExtraSpaces = "\n " + base64EncodedSimple + " \n"
constant base64DecodedSimple (line 15) | base64DecodedSimple = "a special string"
constant base64EncodedUTF8 (line 17) | base64EncodedUTF8 = "V29ya3Mgd2l0aCBVVEYtMTYg8J+Yig=="
constant base64DecodedUTF8 (line 18) | base64DecodedUTF8 = "Works with UTF-16 😊"
constant base64EncodedYaml (line 20) | base64EncodedYaml = "YTogYXBwbGUK"
constant base64DecodedYaml (line 21) | base64DecodedYaml = "a: apple\n"
constant base64EncodedEmpty (line 23) | base64EncodedEmpty = ""
constant base64DecodedEmpty (line 24) | base64DecodedEmpty = ""
constant base64MissingPadding (line 26) | base64MissingPadding = "Y2F0cw"
constant base64DecodedMissingPadding (line 27) | base64DecodedMissingPadding = "cats"
constant base64EncodedCats (line 29) | base64EncodedCats = "Y2F0cw=="
constant base64DecodedCats (line 30) | base64DecodedCats = "cats"
function testBase64Scenario (line 176) | func testBase64Scenario(t *testing.T, s formatScenario) {
function documentBase64Scenario (line 199) | func documentBase64Scenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function documentBase64DecodeScenario (line 216) | func documentBase64DecodeScenario(w *bufio.Writer, s formatScenario) {
function documentBase64EncodeScenario (line 238) | func documentBase64EncodeScenario(w *bufio.Writer, s formatScenario) {
function TestBase64Scenarios (line 260) | func TestBase64Scenarios(t *testing.T) {
FILE: pkg/yqlib/candidate_node.go
type Kind (line 10) | type Kind
constant SequenceNode (line 13) | SequenceNode Kind = 1 << iota
constant MappingNode (line 14) | MappingNode
constant ScalarNode (line 15) | ScalarNode
constant AliasNode (line 16) | AliasNode
type Style (line 19) | type Style
constant TaggedStyle (line 22) | TaggedStyle Style = 1 << iota
constant DoubleQuotedStyle (line 23) | DoubleQuotedStyle
constant SingleQuotedStyle (line 24) | SingleQuotedStyle
constant LiteralStyle (line 25) | LiteralStyle
constant FoldedStyle (line 26) | FoldedStyle
constant FlowStyle (line 27) | FlowStyle
function createStringScalarNode (line 30) | func createStringScalarNode(stringValue string) *CandidateNode {
function createScalarNode (line 37) | func createScalarNode(value interface{}, stringValue string) *CandidateN...
type NodeInfo (line 56) | type NodeInfo struct
type CandidateNode (line 70) | type CandidateNode struct
method CreateChild (line 105) | func (n *CandidateNode) CreateChild() *CandidateNode {
method SetDocument (line 111) | func (n *CandidateNode) SetDocument(idx uint) {
method GetDocument (line 115) | func (n *CandidateNode) GetDocument() uint {
method SetFilename (line 123) | func (n *CandidateNode) SetFilename(name string) {
method GetFilename (line 127) | func (n *CandidateNode) GetFilename() string {
method SetFileIndex (line 134) | func (n *CandidateNode) SetFileIndex(idx int) {
method GetFileIndex (line 138) | func (n *CandidateNode) GetFileIndex() int {
method GetKey (line 145) | func (n *CandidateNode) GetKey() string {
method getParsedKey (line 157) | func (n *CandidateNode) getParsedKey() interface{} {
method FilterMapContentByKey (line 175) | func (n *CandidateNode) FilterMapContentByKey(keyPredicate func(*Candi...
method GetPath (line 187) | func (n *CandidateNode) GetPath() []interface{} {
method GetNicePath (line 199) | func (n *CandidateNode) GetNicePath() string {
method AsList (line 220) | func (n *CandidateNode) AsList() *list.List {
method SetParent (line 226) | func (n *CandidateNode) SetParent(parent *CandidateNode) {
method VisitValues (line 232) | func (n *CandidateNode) VisitValues(visitor ValueVisitor) error {
method CanVisitValues (line 250) | func (n *CandidateNode) CanVisitValues() bool {
method AddKeyValueChild (line 254) | func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawVal...
method AddChild (line 268) | func (n *CandidateNode) AddChild(rawChild *CandidateNode) {
method AddChildren (line 281) | func (n *CandidateNode) AddChildren(children []*CandidateNode) {
method GetValueRep (line 296) | func (n *CandidateNode) GetValueRep() (interface{}, error) {
method guessTagFromCustomType (line 316) | func (n *CandidateNode) guessTagFromCustomType() string {
method CreateReplacement (line 334) | func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value...
method CopyAsReplacement (line 343) | func (n *CandidateNode) CopyAsReplacement(replacement *CandidateNode) ...
method CreateReplacementWithComments (line 356) | func (n *CandidateNode) CreateReplacementWithComments(kind Kind, tag s...
method Copy (line 366) | func (n *CandidateNode) Copy() *CandidateNode {
method CopyWithoutContent (line 370) | func (n *CandidateNode) CopyWithoutContent() *CandidateNode {
method doCopy (line 374) | func (n *CandidateNode) doCopy(cloneContent bool) *CandidateNode {
method UpdateFrom (line 425) | func (n *CandidateNode) UpdateFrom(other *CandidateNode, prefs assignP...
method UpdateAttributesFrom (line 447) | func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, pre...
method ConvertToNodeInfo (line 489) | func (n *CandidateNode) ConvertToNodeInfo() *NodeInfo {
type ValueVisitor (line 230) | type ValueVisitor
function kindToString (line 512) | func kindToString(k Kind) string {
function styleToString (line 527) | func styleToString(s Style) string {
FILE: pkg/yqlib/candidate_node_goccy_yaml.go
method goccyDecodeIntoChild (line 12) | func (o *CandidateNode) goccyDecodeIntoChild(childNode ast.Node, cm yaml...
method UnmarshalGoccyYAML (line 19) | func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.Commen...
method goccyProcessMappingValueNode (line 189) | func (o *CandidateNode) goccyProcessMappingValueNode(mappingEntry *ast.M...
FILE: pkg/yqlib/candidate_node_test.go
type valueRepScenario (line 10) | type valueRepScenario struct
function TestCandidateNodeGetValueRepScenarios (line 44) | func TestCandidateNodeGetValueRepScenarios(t *testing.T) {
function TestCandidateNodeChildWhenParentUpdated (line 56) | func TestCandidateNodeChildWhenParentUpdated(t *testing.T) {
type createScalarNodeScenario (line 67) | type createScalarNodeScenario struct
function TestCreateScalarNodeScenarios (line 101) | func TestCreateScalarNodeScenarios(t *testing.T) {
function TestGetKeyForMapValue (line 109) | func TestGetKeyForMapValue(t *testing.T) {
function TestGetKeyForMapKey (line 115) | func TestGetKeyForMapKey(t *testing.T) {
function TestGetKeyForValue (line 122) | func TestGetKeyForValue(t *testing.T) {
function TestGetParsedKeyForMapKey (line 127) | func TestGetParsedKeyForMapKey(t *testing.T) {
function TestGetParsedKeyForLooseValue (line 134) | func TestGetParsedKeyForLooseValue(t *testing.T) {
function TestGetParsedKeyForMapValue (line 139) | func TestGetParsedKeyForMapValue(t *testing.T) {
function TestGetParsedKeyForArrayValue (line 145) | func TestGetParsedKeyForArrayValue(t *testing.T) {
function TestCandidateNodeAddKeyValueChild (line 151) | func TestCandidateNodeAddKeyValueChild(t *testing.T) {
function TestConvertToNodeInfo (line 162) | func TestConvertToNodeInfo(t *testing.T) {
function TestCandidateNodeGetPath (line 206) | func TestCandidateNodeGetPath(t *testing.T) {
function TestCandidateNodeGetNicePath (line 230) | func TestCandidateNodeGetNicePath(t *testing.T) {
function TestCandidateNodeFilterMapContentByKey (line 257) | func TestCandidateNodeFilterMapContentByKey(t *testing.T) {
function TestCandidateNodeVisitValues (line 284) | func TestCandidateNodeVisitValues(t *testing.T) {
function TestCandidateNodeCanVisitValues (line 343) | func TestCandidateNodeCanVisitValues(t *testing.T) {
function TestCandidateNodeAddChild (line 353) | func TestCandidateNodeAddChild(t *testing.T) {
function TestCandidateNodeAddChildren (line 368) | func TestCandidateNodeAddChildren(t *testing.T) {
FILE: pkg/yqlib/candidate_node_yaml.go
function MapYamlStyle (line 9) | func MapYamlStyle(original yaml.Style) Style {
function MapToYamlStyle (line 29) | func MapToYamlStyle(original Style) yaml.Style {
method copyFromYamlNode (line 49) | func (o *CandidateNode) copyFromYamlNode(node *yaml.Node, anchorMap map[...
method copyToYamlNode (line 74) | func (o *CandidateNode) copyToYamlNode(node *yaml.Node) {
method decodeIntoChild (line 90) | func (o *CandidateNode) decodeIntoChild(childNode *yaml.Node, anchorMap ...
method UnmarshalYAML (line 105) | func (o *CandidateNode) UnmarshalYAML(node *yaml.Node, anchorMap map[str...
method MarshalYAML (line 178) | func (o *CandidateNode) MarshalYAML() (*yaml.Node, error) {
FILE: pkg/yqlib/candidiate_node_json.go
method setScalarFromJson (line 14) | func (o *CandidateNode) setScalarFromJson(value interface{}) error {
method UnmarshalJSON (line 44) | func (o *CandidateNode) UnmarshalJSON(data []byte) error {
method MarshalJSON (line 129) | func (o *CandidateNode) MarshalJSON() ([]byte, error) {
FILE: pkg/yqlib/chown_linux.go
function changeOwner (line 11) | func changeOwner(info fs.FileInfo, file *os.File) error {
FILE: pkg/yqlib/chown_linux_test.go
function TestChangeOwner (line 12) | func TestChangeOwner(t *testing.T) {
function TestChangeOwnerWithInvalidFileInfo (line 58) | func TestChangeOwnerWithInvalidFileInfo(t *testing.T) {
function TestChangeOwnerWithNonExistentFile (line 81) | func TestChangeOwnerWithNonExistentFile(t *testing.T) {
type mockFileInfo (line 107) | type mockFileInfo struct
method Name (line 113) | func (m *mockFileInfo) Name() string { return m.name }
method Size (line 114) | func (m *mockFileInfo) Size() int64 { return m.size }
method Mode (line 115) | func (m *mockFileInfo) Mode() os.FileMode { return m.mode }
method ModTime (line 116) | func (m *mockFileInfo) ModTime() time.Time { return time.Time{} }
method IsDir (line 117) | func (m *mockFileInfo) IsDir() bool { return false }
method Sys (line 118) | func (m *mockFileInfo) Sys() interface{} { return nil }
function TestChangeOwnerWithSyscallStatT (line 120) | func TestChangeOwnerWithSyscallStatT(t *testing.T) {
FILE: pkg/yqlib/chown_not_linux_os.go
function changeOwner (line 10) | func changeOwner(_ fs.FileInfo, _ *os.File) error {
FILE: pkg/yqlib/color_print.go
constant escape (line 14) | escape = "\x1b"
function format (line 16) | func format(attr color.Attribute) string {
function colorizeAndPrint (line 20) | func colorizeAndPrint(yamlBytes []byte, writer io.Writer) error {
FILE: pkg/yqlib/color_print_test.go
function TestFormat (line 11) | func TestFormat(t *testing.T) {
function TestColorizeAndPrint (line 44) | func TestColorizeAndPrint(t *testing.T) {
function TestColorizeAndPrintWithDifferentYamlTypes (line 100) | func TestColorizeAndPrintWithDifferentYamlTypes(t *testing.T) {
FILE: pkg/yqlib/context.go
type Context (line 11) | type Context struct
method SingleReadonlyChildContext (line 18) | func (n *Context) SingleReadonlyChildContext(candidate *CandidateNode)...
method SingleChildContext (line 26) | func (n *Context) SingleChildContext(candidate *CandidateNode) Context {
method SetDateTimeLayout (line 32) | func (n *Context) SetDateTimeLayout(newDateTimeLayout string) {
method GetDateTimeLayout (line 36) | func (n *Context) GetDateTimeLayout() string {
method GetVariable (line 43) | func (n *Context) GetVariable(name string) *list.List {
method SetVariable (line 50) | func (n *Context) SetVariable(name string, value *list.List) {
method ChildContext (line 57) | func (n *Context) ChildContext(results *list.List) Context {
method ToString (line 77) | func (n *Context) ToString() string {
method DeepClone (line 85) | func (n *Context) DeepClone() Context {
method Clone (line 96) | func (n *Context) Clone() Context {
method ReadOnlyClone (line 100) | func (n *Context) ReadOnlyClone() Context {
method WritableClone (line 106) | func (n *Context) WritableClone() Context {
FILE: pkg/yqlib/context_test.go
function TestChildContext (line 12) | func TestChildContext(t *testing.T) {
function TestChildContextNoVariables (line 40) | func TestChildContextNoVariables(t *testing.T) {
function TestSingleReadonlyChildContext (line 55) | func TestSingleReadonlyChildContext(t *testing.T) {
function TestSingleChildContext (line 72) | func TestSingleChildContext(t *testing.T) {
function TestSetDateTimeLayout (line 89) | func TestSetDateTimeLayout(t *testing.T) {
function TestGetDateTimeLayout (line 97) | func TestGetDateTimeLayout(t *testing.T) {
function TestGetVariable (line 109) | func TestGetVariable(t *testing.T) {
function TestSetVariable (line 129) | func TestSetVariable(t *testing.T) {
function TestToString (line 143) | func TestToString(t *testing.T) {
function TestDeepClone (line 167) | func TestDeepClone(t *testing.T) {
function TestClone (line 202) | func TestClone(t *testing.T) {
function TestReadOnlyClone (line 223) | func TestReadOnlyClone(t *testing.T) {
function TestWritableClone (line 243) | func TestWritableClone(t *testing.T) {
FILE: pkg/yqlib/csv.go
type CsvPreferences (line 3) | type CsvPreferences struct
function NewDefaultCsvPreferences (line 8) | func NewDefaultCsvPreferences() CsvPreferences {
function NewDefaultTsvPreferences (line 15) | func NewDefaultTsvPreferences() CsvPreferences {
FILE: pkg/yqlib/csv_test.go
constant csvSimple (line 11) | csvSimple = `name,numberOfCats,likesApples,height
constant csvSimpleWithObject (line 16) | csvSimpleWithObject = `name,numberOfCats,likesApples,height,facts
constant csvMissing (line 20) | csvMissing = `name,numberOfCats,likesApples,height
constant expectedUpdatedSimpleCsv (line 23) | expectedUpdatedSimpleCsv = `name,numberOfCats,likesApples,height
constant csvSimpleShort (line 28) | csvSimpleShort = `Name,Number of Cats
constant tsvSimple (line 33) | tsvSimple = `name numberOfCats likesApples height
constant expectedYamlFromCSV (line 38) | expectedYamlFromCSV = `- name: Gary
constant expectedYamlFromCSVWithObject (line 47) | expectedYamlFromCSVWithObject = `- name: Gary
constant expectedYamlFromCSVNoParsing (line 61) | expectedYamlFromCSVNoParsing = `- name: Gary
constant expectedYamlFromCSVMissingData (line 73) | expectedYamlFromCSVMissingData = `- name: Gary
constant csvSimpleMissingData (line 81) | csvSimpleMissingData = `name,numberOfCats,height
constant csvTestSimpleYaml (line 86) | csvTestSimpleYaml = `- [i, like, csv]
constant expectedSimpleCsv (line 89) | expectedSimpleCsv = `i,like,csv
constant tsvTestExpectedSimpleCsv (line 93) | tsvTestExpectedSimpleCsv = `i like csv
function testCSVScenario (line 227) | func testCSVScenario(t *testing.T, s formatScenario) {
function documentCSVDecodeObjectScenario (line 246) | func documentCSVDecodeObjectScenario(w *bufio.Writer, s formatScenario, ...
function documentCSVDecodeObjectNoAutoScenario (line 271) | func documentCSVDecodeObjectNoAutoScenario(w *bufio.Writer, s formatScen...
function documentCSVEncodeScenario (line 296) | func documentCSVEncodeScenario(w *bufio.Writer, s formatScenario, format...
function documentCSVRoundTripScenario (line 329) | func documentCSVRoundTripScenario(w *bufio.Writer, s formatScenario, for...
function documentCSVScenario (line 364) | func documentCSVScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function TestCSVScenarios (line 388) | func TestCSVScenarios(t *testing.T) {
FILE: pkg/yqlib/data_tree_navigator.go
type DataTreeNavigator (line 9) | type DataTreeNavigator interface
type dataTreeNavigator (line 18) | type dataTreeNavigator struct
method DeeplyAssign (line 25) | func (d *dataTreeNavigator) DeeplyAssign(context Context, path []inter...
method GetMatchingNodes (line 52) | func (d *dataTreeNavigator) GetMatchingNodes(context Context, expressi...
function NewDataTreeNavigator (line 21) | func NewDataTreeNavigator() DataTreeNavigator {
FILE: pkg/yqlib/data_tree_navigator_test.go
function TestGetMatchingNodes_NilExpressionNode (line 10) | func TestGetMatchingNodes_NilExpressionNode(t *testing.T) {
function TestGetMatchingNodes_UnknownOperator (line 22) | func TestGetMatchingNodes_UnknownOperator(t *testing.T) {
function TestGetMatchingNodes_ValidOperator (line 40) | func TestGetMatchingNodes_ValidOperator(t *testing.T) {
function TestDeeplyAssign_ScalarNode (line 69) | func TestDeeplyAssign_ScalarNode(t *testing.T) {
function TestDeeplyAssign_MappingNode (line 116) | func TestDeeplyAssign_MappingNode(t *testing.T) {
function TestDeeplyAssign_DeepPath (line 172) | func TestDeeplyAssign_DeepPath(t *testing.T) {
function TestDeeplyAssign_ArrayPath (line 217) | func TestDeeplyAssign_ArrayPath(t *testing.T) {
function TestDeeplyAssign_OverwriteExisting (line 255) | func TestDeeplyAssign_OverwriteExisting(t *testing.T) {
function TestDeeplyAssign_ErrorHandling (line 294) | func TestDeeplyAssign_ErrorHandling(t *testing.T) {
function TestGetMatchingNodes_WithVariables (line 326) | func TestGetMatchingNodes_WithVariables(t *testing.T) {
function TestGetMatchingNodes_EmptyContext (line 355) | func TestGetMatchingNodes_EmptyContext(t *testing.T) {
function TestDeeplyAssign_ComplexMappingMerge (line 374) | func TestDeeplyAssign_ComplexMappingMerge(t *testing.T) {
FILE: pkg/yqlib/decoder.go
type Decoder (line 7) | type Decoder interface
FILE: pkg/yqlib/decoder_base64.go
type base64Decoder (line 12) | type base64Decoder struct
method Init (line 23) | func (dec *base64Decoder) Init(reader io.Reader) error {
method Decode (line 48) | func (dec *base64Decoder) Decode() (*CandidateNode, error) {
function NewBase64Decoder (line 19) | func NewBase64Decoder() Decoder {
FILE: pkg/yqlib/decoder_csv_object.go
type csvObjectDecoder (line 13) | type csvObjectDecoder struct
method Init (line 23) | func (dec *csvObjectDecoder) Init(reader io.Reader) error {
method convertToNode (line 32) | func (dec *csvObjectDecoder) convertToNode(content string) *CandidateN...
method createObject (line 42) | func (dec *csvObjectDecoder) createObject(headerRow []string, contentR...
method Decode (line 51) | func (dec *csvObjectDecoder) Decode() (*CandidateNode, error) {
function NewCSVObjectDecoder (line 19) | func NewCSVObjectDecoder(prefs CsvPreferences) Decoder {
FILE: pkg/yqlib/decoder_goccy_yaml.go
type goccyYamlDecoder (line 16) | type goccyYamlDecoder struct
method Init (line 27) | func (dec *goccyYamlDecoder) Init(reader io.Reader) error {
method Decode (line 34) | func (dec *goccyYamlDecoder) Decode() (*CandidateNode, error) {
function NewGoccyYAMLDecoder (line 23) | func NewGoccyYAMLDecoder() Decoder {
FILE: pkg/yqlib/decoder_hcl.go
type hclDecoder (line 18) | type hclDecoder struct
method Init (line 111) | func (dec *hclDecoder) Init(reader io.Reader) error {
method Decode (line 127) | func (dec *hclDecoder) Decode() (*CandidateNode, error) {
function NewHclDecoder (line 25) | func NewHclDecoder() Decoder {
function sortedAttributes (line 30) | func sortedAttributes(attrs hclsyntax.Attributes) []*attributeWithName {
type attributeWithName (line 41) | type attributeWithName struct
function extractLineComment (line 47) | func extractLineComment(src []byte, endPos int) string {
function extractHeadComment (line 68) | func extractHeadComment(src []byte, startPos int) string {
function hclBodyToNode (line 179) | func hclBodyToNode(body *hclsyntax.Body, src []byte) *CandidateNode {
function addBlockToMapping (line 212) | func addBlockToMapping(parent *CandidateNode, block *hclsyntax.Block, sr...
function convertHclExprToNode (line 255) | func convertHclExprToNode(expr hclsyntax.Expression, src []byte) *Candid...
function convertCtyValueToNode (line 429) | func convertCtyValueToNode(v cty.Value) *CandidateNode {
FILE: pkg/yqlib/decoder_ini.go
type iniDecoder (line 12) | type iniDecoder struct
method Init (line 23) | func (dec *iniDecoder) Init(reader io.Reader) error {
method Decode (line 29) | func (dec *iniDecoder) Decode() (*CandidateNode, error) {
function NewINIDecoder (line 17) | func NewINIDecoder() Decoder {
FILE: pkg/yqlib/decoder_json.go
type jsonDecoder (line 11) | type jsonDecoder struct
method Init (line 19) | func (dec *jsonDecoder) Init(reader io.Reader) error {
method Decode (line 24) | func (dec *jsonDecoder) Decode() (*CandidateNode, error) {
function NewJSONDecoder (line 15) | func NewJSONDecoder() Decoder {
FILE: pkg/yqlib/decoder_lua.go
type luaDecoder (line 13) | type luaDecoder struct
method Init (line 25) | func (dec *luaDecoder) Init(reader io.Reader) error {
method convertToYamlNode (line 30) | func (dec *luaDecoder) convertToYamlNode(ls *lua.LState, lv lua.LValue...
method decideTopLevelNode (line 139) | func (dec *luaDecoder) decideTopLevelNode(ls *lua.LState) *CandidateNo...
method Decode (line 147) | func (dec *luaDecoder) Decode() (*CandidateNode, error) {
function NewLuaDecoder (line 19) | func NewLuaDecoder(prefs LuaPreferences) Decoder {
FILE: pkg/yqlib/decoder_properties.go
type propertiesDecoder (line 15) | type propertiesDecoder struct
method Init (line 25) | func (dec *propertiesDecoder) Init(reader io.Reader) error {
method processComment (line 45) | func (dec *propertiesDecoder) processComment(c string) string {
method applyPropertyComments (line 52) | func (dec *propertiesDecoder) applyPropertyComments(context Context, p...
method applyProperty (line 76) | func (dec *propertiesDecoder) applyProperty(context Context, propertie...
method Decode (line 94) | func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {
function NewPropertiesDecoder (line 21) | func NewPropertiesDecoder() Decoder {
function parsePropKey (line 31) | func parsePropKey(key string) []interface{} {
FILE: pkg/yqlib/decoder_test.go
type formatScenario (line 10) | type formatScenario struct
function processFormatScenario (line 22) | func processFormatScenario(s formatScenario, decoder Decoder, encoder En...
function mustProcessFormatScenario (line 67) | func mustProcessFormatScenario(s formatScenario, decoder Decoder, encode...
FILE: pkg/yqlib/decoder_toml.go
type tomlDecoder (line 17) | type tomlDecoder struct
method Init (line 33) | func (dec *tomlDecoder) Init(reader io.Reader) error {
method attachOrphanedCommentsToNode (line 50) | func (dec *tomlDecoder) attachOrphanedCommentsToNode(tableNodeValue *C...
method getFullPath (line 62) | func (dec *tomlDecoder) getFullPath(tomlNode *toml.Node) []interface{} {
method processKeyValueIntoMap (line 73) | func (dec *tomlDecoder) processKeyValueIntoMap(rootMap *CandidateNode,...
method decodeKeyValuesIntoMap (line 100) | func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode,...
method createInlineTableMap (line 128) | func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*Ca...
method createArray (line 158) | func (dec *tomlDecoder) createArray(tomlNode *toml.Node) (*CandidateNo...
method createStringScalar (line 195) | func (dec *tomlDecoder) createStringScalar(tomlNode *toml.Node) (*Cand...
method createBoolScalar (line 200) | func (dec *tomlDecoder) createBoolScalar(tomlNode *toml.Node) (*Candid...
method createIntegerScalar (line 205) | func (dec *tomlDecoder) createIntegerScalar(tomlNode *toml.Node) (*Can...
method createDateTimeScalar (line 211) | func (dec *tomlDecoder) createDateTimeScalar(tomlNode *toml.Node) (*Ca...
method createFloatScalar (line 217) | func (dec *tomlDecoder) createFloatScalar(tomlNode *toml.Node) (*Candi...
method decodeNode (line 223) | func (dec *tomlDecoder) decodeNode(tomlNode *toml.Node) (*CandidateNod...
method Decode (line 245) | func (dec *tomlDecoder) Decode() (*CandidateNode, error) {
method processTopLevelNode (line 297) | func (dec *tomlDecoder) processTopLevelNode(currentNode *toml.Node) (b...
method processTable (line 332) | func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, er...
method arrayAppend (line 403) | func (dec *tomlDecoder) arrayAppend(context Context, path []interface{...
method processArrayTable (line 425) | func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (boo...
function NewTomlDecoder (line 26) | func NewTomlDecoder() Decoder {
function getPathToUse (line 513) | func getPathToUse(fullPath []interface{}, dec *tomlDecoder, c Context) (...
FILE: pkg/yqlib/decoder_uri.go
type uriDecoder (line 11) | type uriDecoder struct
method Init (line 21) | func (dec *uriDecoder) Init(reader io.Reader) error {
method Decode (line 28) | func (dec *uriDecoder) Decode() (*CandidateNode, error) {
function NewUriDecoder (line 17) | func NewUriDecoder() Decoder {
FILE: pkg/yqlib/decoder_uri_test.go
function TestUriDecoder_Init (line 13) | func TestUriDecoder_Init(t *testing.T) {
function TestUriDecoder_DecodeSimpleString (line 20) | func TestUriDecoder_DecodeSimpleString(t *testing.T) {
function TestUriDecoder_DecodeSpecialCharacters (line 32) | func TestUriDecoder_DecodeSpecialCharacters(t *testing.T) {
function TestUriDecoder_DecodeUTF8 (line 43) | func TestUriDecoder_DecodeUTF8(t *testing.T) {
function TestUriDecoder_DecodePlusSign (line 54) | func TestUriDecoder_DecodePlusSign(t *testing.T) {
function TestUriDecoder_DecodeEmptyString (line 67) | func TestUriDecoder_DecodeEmptyString(t *testing.T) {
function TestUriDecoder_DecodeMultipleCalls (line 83) | func TestUriDecoder_DecodeMultipleCalls(t *testing.T) {
function TestUriDecoder_DecodeInvalidEscape (line 100) | func TestUriDecoder_DecodeInvalidEscape(t *testing.T) {
function TestUriDecoder_DecodeSlashAndQuery (line 113) | func TestUriDecoder_DecodeSlashAndQuery(t *testing.T) {
function TestUriDecoder_DecodePercent (line 124) | func TestUriDecoder_DecodePercent(t *testing.T) {
function TestUriDecoder_DecodeNoEscaping (line 135) | func TestUriDecoder_DecodeNoEscaping(t *testing.T) {
type errorReader (line 147) | type errorReader struct
method Read (line 149) | func (e *errorReader) Read(_ []byte) (n int, err error) {
function TestUriDecoder_DecodeReadError (line 153) | func TestUriDecoder_DecodeReadError(t *testing.T) {
FILE: pkg/yqlib/decoder_xml.go
type xmlDecoder (line 17) | type xmlDecoder struct
method Init (line 31) | func (dec *xmlDecoder) Init(reader io.Reader) error {
method createSequence (line 38) | func (dec *xmlDecoder) createSequence(nodes []*xmlNode) (*CandidateNod...
method processComment (line 53) | func (dec *xmlDecoder) processComment(c string) string {
method createMap (line 66) | func (dec *xmlDecoder) createMap(n *xmlNode) (*CandidateNode, error) {
method createValueNodeFromData (line 128) | func (dec *xmlDecoder) createValueNodeFromData(values []string) *Candi...
method convertToYamlNode (line 147) | func (dec *xmlDecoder) convertToYamlNode(n *xmlNode) (*CandidateNode, ...
method Decode (line 167) | func (dec *xmlDecoder) Decode() (*CandidateNode, error) {
method decodeXML (line 238) | func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
function NewXMLDecoder (line 24) | func NewXMLDecoder(prefs XmlPreferences) Decoder {
type xmlNode (line 194) | type xmlNode struct
method AddChild (line 209) | func (n *xmlNode) AddChild(s string, c *xmlNode) {
type xmlChildrenKv (line 202) | type xmlChildrenKv struct
type element (line 228) | type element struct
function applyFootComment (line 351) | func applyFootComment(elem *element, commentStr string) {
function joinComments (line 371) | func joinComments(rawStrings []string, joinStr string) string {
function trimNonGraphic (line 387) | func trimNonGraphic(s string) string {
FILE: pkg/yqlib/decoder_yaml.go
type yamlDecoder (line 21) | type yamlDecoder struct
method processReadStream (line 42) | func (dec *yamlDecoder) processReadStream(reader *bufio.Reader) (io.Re...
method Init (line 112) | func (dec *yamlDecoder) Init(reader io.Reader) error {
method Decode (line 141) | func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
method blankNodeWithComment (line 183) | func (dec *yamlDecoder) blankNodeWithComment() *CandidateNode {
function NewYamlDecoder (line 38) | func NewYamlDecoder(prefs YamlPreferences) Decoder {
FILE: pkg/yqlib/encoder.go
type Encoder (line 12) | type Encoder interface
function mapKeysToStrings (line 19) | func mapKeysToStrings(node *CandidateNode) {
function PrintYAMLDocumentSeparator (line 35) | func PrintYAMLDocumentSeparator(writer io.Writer, PrintDocSeparators boo...
function PrintYAMLLeadingContent (line 44) | func PrintYAMLLeadingContent(writer io.Writer, content string, PrintDocS...
FILE: pkg/yqlib/encoder_base64.go
type base64Encoder (line 11) | type base64Encoder struct
method CanHandleAliases (line 19) | func (e *base64Encoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 23) | func (e *base64Encoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 27) | func (e *base64Encoder) PrintLeadingContent(_ io.Writer, _ string) err...
method Encode (line 31) | func (e *base64Encoder) Encode(writer io.Writer, node *CandidateNode) ...
function NewBase64Encoder (line 15) | func NewBase64Encoder() Encoder {
FILE: pkg/yqlib/encoder_csv.go
type csvEncoder (line 11) | type csvEncoder struct
method CanHandleAliases (line 19) | func (e *csvEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 23) | func (e *csvEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 27) | func (e *csvEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method encodeRow (line 31) | func (e *csvEncoder) encodeRow(csvWriter *csv.Writer, contents []*Cand...
method encodeArrays (line 44) | func (e *csvEncoder) encodeArrays(csvWriter *csv.Writer, content []*Ca...
method extractHeader (line 58) | func (e *csvEncoder) extractHeader(child *CandidateNode) ([]*Candidate...
method createChildRow (line 66) | func (e *csvEncoder) createChildRow(child *CandidateNode, headers []*C...
method encodeObjects (line 80) | func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*C...
method Encode (line 105) | func (e *csvEncoder) Encode(writer io.Writer, node *CandidateNode) err...
function NewCsvEncoder (line 15) | func NewCsvEncoder(prefs CsvPreferences) Encoder {
FILE: pkg/yqlib/encoder_hcl.go
type hclEncoder (line 18) | type hclEncoder struct
method CanHandleAliases (line 32) | func (he *hclEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 36) | func (he *hclEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 40) | func (he *hclEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method Encode (line 44) | func (he *hclEncoder) Encode(writer io.Writer, node *CandidateNode) er...
method compactSpacing (line 79) | func (he *hclEncoder) compactSpacing(input []byte) []byte {
method collectComments (line 86) | func (he *hclEncoder) collectComments(node *CandidateNode, prefix stri...
method injectComments (line 135) | func (he *hclEncoder) injectComments(output []byte, commentMap map[str...
method colorizeHcl (line 176) | func (he *hclEncoder) colorizeHcl(input []byte) []byte {
method encodeAttribute (line 357) | func (he *hclEncoder) encodeAttribute(body *hclwrite.Body, key string,...
method encodeTemplateAttribute (line 399) | func (he *hclEncoder) encodeTemplateAttribute(body *hclwrite.Body, key...
method encodeBlockIfMapping (line 447) | func (he *hclEncoder) encodeBlockIfMapping(body *hclwrite.Body, key st...
method encodeNode (line 493) | func (he *hclEncoder) encodeNode(body *hclwrite.Body, node *CandidateN...
method encodeMappingChildrenAsBlocks (line 535) | func (he *hclEncoder) encodeMappingChildrenAsBlocks(body *hclwrite.Bod...
method encodeNodeAttributes (line 587) | func (he *hclEncoder) encodeNodeAttributes(body *hclwrite.Body, node *...
constant commentPathSep (line 25) | commentPathSep = "\x1e"
function NewHclEncoder (line 28) | func NewHclEncoder(prefs HclPreferences) Encoder {
function joinCommentPath (line 127) | func joinCommentPath(prefix, segment string) string {
function isHCLIdentifierStart (line 278) | func isHCLIdentifierStart(r rune) bool {
function isHCLIdentifierPart (line 282) | func isHCLIdentifierPart(r rune) bool {
function isValidHCLIdentifier (line 286) | func isValidHCLIdentifier(s string) bool {
function tokensForRawHCLExpr (line 308) | func tokensForRawHCLExpr(expr string) (hclwrite.Tokens, error) {
function mappingChildrenAllMappings (line 517) | func mappingChildrenAllMappings(node *CandidateNode) bool {
function extractBlockLabels (line 613) | func extractBlockLabels(node *CandidateNode) ([]string, *CandidateNode, ...
function nodeToCtyValue (line 635) | func nodeToCtyValue(node *CandidateNode) (cty.Value, error) {
FILE: pkg/yqlib/encoder_ini.go
type iniEncoder (line 13) | type iniEncoder struct
method CanHandleAliases (line 24) | func (ie *iniEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 29) | func (ie *iniEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 34) | func (ie *iniEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method Encode (line 39) | func (ie *iniEncoder) Encode(writer io.Writer, node *CandidateNode) er...
function NewINIEncoder (line 18) | func NewINIEncoder() Encoder {
function writeStringINI (line 110) | func writeStringINI(writer io.Writer, content string) error {
FILE: pkg/yqlib/encoder_json.go
type jsonEncoder (line 12) | type jsonEncoder struct
method CanHandleAliases (line 27) | func (je *jsonEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 31) | func (je *jsonEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 35) | func (je *jsonEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method Encode (line 39) | func (je *jsonEncoder) Encode(writer io.Writer, node *CandidateNode) e...
function NewJSONEncoder (line 17) | func NewJSONEncoder(prefs JsonPreferences) Encoder {
FILE: pkg/yqlib/encoder_kyaml.go
type kyamlEncoder (line 13) | type kyamlEncoder struct
method CanHandleAliases (line 21) | func (ke *kyamlEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 26) | func (ke *kyamlEncoder) PrintDocumentSeparator(writer io.Writer) error {
method PrintLeadingContent (line 30) | func (ke *kyamlEncoder) PrintLeadingContent(writer io.Writer, content ...
method Encode (line 34) | func (ke *kyamlEncoder) Encode(writer io.Writer, node *CandidateNode) ...
method writeNode (line 72) | func (ke *kyamlEncoder) writeNode(writer io.Writer, node *CandidateNod...
method writeMapping (line 91) | func (ke *kyamlEncoder) writeMapping(writer io.Writer, node *Candidate...
method writeSequence (line 157) | func (ke *kyamlEncoder) writeSequence(writer io.Writer, node *Candidat...
method writeIndent (line 196) | func (ke *kyamlEncoder) writeIndent(writer io.Writer, indent int) error {
method formatKey (line 203) | func (ke *kyamlEncoder) formatKey(keyNode *CandidateNode) string {
method formatScalar (line 212) | func (ke *kyamlEncoder) formatScalar(node *CandidateNode) string {
method writeCommentBlock (line 268) | func (ke *kyamlEncoder) writeCommentBlock(writer io.Writer, comment st...
method writeInlineComment (line 298) | func (ke *kyamlEncoder) writeInlineComment(writer io.Writer, comment s...
function NewKYamlEncoder (line 17) | func NewKYamlEncoder(prefs KYamlPreferences) Encoder {
function isValidKYamlBareKey (line 230) | func isValidKYamlBareKey(s string) bool {
function escapeDoubleQuotedString (line 238) | func escapeDoubleQuotedString(s string) string {
FILE: pkg/yqlib/encoder_lua.go
type luaEncoder (line 11) | type luaEncoder struct
method CanHandleAliases (line 21) | func (le *luaEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 75) | func (le *luaEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 79) | func (le *luaEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method encodeString (line 83) | func (le *luaEncoder) encodeString(writer io.Writer, node *CandidateNo...
method writeIndent (line 108) | func (le *luaEncoder) writeIndent(writer io.Writer) error {
method encodeArray (line 119) | func (le *luaEncoder) encodeArray(writer io.Writer, node *CandidateNod...
method encodeMap (line 186) | func (le *luaEncoder) encodeMap(writer io.Writer, node *CandidateNode,...
method encodeAny (line 268) | func (le *luaEncoder) encodeAny(writer io.Writer, node *CandidateNode)...
method encodeTopLevel (line 313) | func (le *luaEncoder) encodeTopLevel(writer io.Writer, node *Candidate...
method Encode (line 325) | func (le *luaEncoder) Encode(writer io.Writer, node *CandidateNode) er...
function NewLuaEncoder (line 25) | func NewLuaEncoder(prefs LuaPreferences) Encoder {
function needsQuoting (line 156) | func needsQuoting(s string) bool {
FILE: pkg/yqlib/encoder_properties.go
type propertiesEncoder (line 15) | type propertiesEncoder struct
method CanHandleAliases (line 25) | func (pe *propertiesEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 29) | func (pe *propertiesEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 33) | func (pe *propertiesEncoder) PrintLeadingContent(writer io.Writer, con...
method Encode (line 66) | func (pe *propertiesEncoder) Encode(writer io.Writer, node *CandidateN...
method doEncode (line 84) | func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *...
method appendPath (line 116) | func (pe *propertiesEncoder) appendPath(path string, key interface{}) ...
method encodeArray (line 130) | func (pe *propertiesEncoder) encodeArray(p *properties.Properties, kid...
method encodeMap (line 140) | func (pe *propertiesEncoder) encodeMap(p *properties.Properties, kids ...
function NewPropertiesEncoder (line 19) | func NewPropertiesEncoder(prefs PropertiesPreferences) Encoder {
FILE: pkg/yqlib/encoder_properties_test.go
type keyValuePair (line 12) | type keyValuePair struct
method String (line 18) | func (kv *keyValuePair) String(unwrap bool, sep string) string {
type testProperties (line 40) | type testProperties struct
method String (line 44) | func (tp *testProperties) String(unwrap bool, sep string) string {
function yamlToProps (line 54) | func yamlToProps(sampleYaml string, unwrapScalar bool, separator string)...
function doTest (line 73) | func doTest(t *testing.T, sampleYaml string, props testProperties, testU...
function TestPropertiesEncoderSimple (line 90) | func TestPropertiesEncoderSimple(t *testing.T) {
function TestPropertiesEncoderSimpleWithComments (line 107) | func TestPropertiesEncoderSimpleWithComments(t *testing.T) {
function TestPropertiesEncoderDeep (line 125) | func TestPropertiesEncoderDeep(t *testing.T) {
function TestPropertiesEncoderDeepWithComments (line 144) | func TestPropertiesEncoderDeepWithComments(t *testing.T) {
function TestPropertiesEncoderArray_Unwrapped (line 164) | func TestPropertiesEncoderArray_Unwrapped(t *testing.T) {
function TestPropertiesEncoderArray_Wrapped (line 187) | func TestPropertiesEncoderArray_Wrapped(t *testing.T) {
FILE: pkg/yqlib/encoder_sh.go
type shEncoder (line 14) | type shEncoder struct
method CanHandleAliases (line 22) | func (e *shEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 26) | func (e *shEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 30) | func (e *shEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method Encode (line 34) | func (e *shEncoder) Encode(writer io.Writer, node *CandidateNode) error {
method encode (line 43) | func (e *shEncoder) encode(input string) string {
method shouldQuote (line 76) | func (e *shEncoder) shouldQuote(ir rune) bool {
function NewShEncoder (line 18) | func NewShEncoder() Encoder {
FILE: pkg/yqlib/encoder_shellvariables.go
type shellVariablesEncoder (line 14) | type shellVariablesEncoder struct
method CanHandleAliases (line 24) | func (pe *shellVariablesEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 28) | func (pe *shellVariablesEncoder) PrintDocumentSeparator(_ io.Writer) e...
method PrintLeadingContent (line 32) | func (pe *shellVariablesEncoder) PrintLeadingContent(_ io.Writer, _ st...
method Encode (line 36) | func (pe *shellVariablesEncoder) Encode(writer io.Writer, node *Candid...
method doEncode (line 47) | func (pe *shellVariablesEncoder) doEncode(w *io.Writer, node *Candidat...
method appendPath (line 93) | func (pe *shellVariablesEncoder) appendPath(cookedPath string, rawKey ...
function NewShellVariablesEncoder (line 18) | func NewShellVariablesEncoder() Encoder {
function quoteValue (line 141) | func quoteValue(value string) string {
function isAlphaOrUnderscore (line 155) | func isAlphaOrUnderscore(r rune) bool {
function isAlphaNumericOrUnderscore (line 159) | func isAlphaNumericOrUnderscore(r rune) bool {
FILE: pkg/yqlib/encoder_shellvariables_test.go
function assertEncodesTo (line 12) | func assertEncodesTo(t *testing.T, yaml string, shellvars string) {
function TestShellVariablesEncoderNonquoting (line 31) | func TestShellVariablesEncoderNonquoting(t *testing.T) {
function TestShellVariablesEncoderQuoting (line 35) | func TestShellVariablesEncoderQuoting(t *testing.T) {
function TestShellVariablesEncoderQuotesQuoting (line 39) | func TestShellVariablesEncoderQuotesQuoting(t *testing.T) {
function TestShellVariablesEncoderStripComments (line 43) | func TestShellVariablesEncoderStripComments(t *testing.T) {
function TestShellVariablesEncoderMap (line 47) | func TestShellVariablesEncoderMap(t *testing.T) {
function TestShellVariablesEncoderArray_Unwrapped (line 51) | func TestShellVariablesEncoderArray_Unwrapped(t *testing.T) {
function TestShellVariablesEncoderKeyNonPrintable (line 55) | func TestShellVariablesEncoderKeyNonPrintable(t *testing.T) {
function TestShellVariablesEncoderKeyPrintableNonAlphaNumeric (line 59) | func TestShellVariablesEncoderKeyPrintableNonAlphaNumeric(t *testing.T) {
function TestShellVariablesEncoderKeyPrintableNonAscii (line 63) | func TestShellVariablesEncoderKeyPrintableNonAscii(t *testing.T) {
function TestShellVariablesEncoderRootKeyStartingWithDigit (line 67) | func TestShellVariablesEncoderRootKeyStartingWithDigit(t *testing.T) {
function TestShellVariablesEncoderRootKeyStartingWithUnderscore (line 71) | func TestShellVariablesEncoderRootKeyStartingWithUnderscore(t *testing.T) {
function TestShellVariablesEncoderChildStartingWithUnderscore (line 75) | func TestShellVariablesEncoderChildStartingWithUnderscore(t *testing.T) {
function TestShellVariablesEncoderEmptyValue (line 79) | func TestShellVariablesEncoderEmptyValue(t *testing.T) {
function TestShellVariablesEncoderEmptyArray (line 83) | func TestShellVariablesEncoderEmptyArray(t *testing.T) {
function TestShellVariablesEncoderEmptyMap (line 87) | func TestShellVariablesEncoderEmptyMap(t *testing.T) {
function TestShellVariablesEncoderScalarNode (line 91) | func TestShellVariablesEncoderScalarNode(t *testing.T) {
function assertEncodesToWithSeparator (line 95) | func assertEncodesToWithSeparator(t *testing.T, yaml string, shellvars s...
function TestShellVariablesEncoderCustomSeparator (line 123) | func TestShellVariablesEncoderCustomSeparator(t *testing.T) {
function TestShellVariablesEncoderCustomSeparatorNested (line 127) | func TestShellVariablesEncoderCustomSeparatorNested(t *testing.T) {
function TestShellVariablesEncoderCustomSeparatorArray (line 131) | func TestShellVariablesEncoderCustomSeparatorArray(t *testing.T) {
function TestShellVariablesEncoderCustomSeparatorSingleChar (line 135) | func TestShellVariablesEncoderCustomSeparatorSingleChar(t *testing.T) {
function assertEncodesToUnwrapped (line 139) | func assertEncodesToUnwrapped(t *testing.T, yaml string, shellvars strin...
function TestShellVariablesEncoderUnwrapScalar (line 165) | func TestShellVariablesEncoderUnwrapScalar(t *testing.T) {
FILE: pkg/yqlib/encoder_test.go
function yamlToJSON (line 14) | func yamlToJSON(t *testing.T, sampleYaml string, indent int) string {
function TestJSONEncoderPreservesObjectOrder (line 40) | func TestJSONEncoderPreservesObjectOrder(t *testing.T) {
function TestJsonNullInArray (line 60) | func TestJsonNullInArray(t *testing.T) {
function TestJsonNull (line 66) | func TestJsonNull(t *testing.T) {
function TestJsonNullInObject (line 72) | func TestJsonNullInObject(t *testing.T) {
function TestJsonEncoderDoesNotEscapeHTMLChars (line 78) | func TestJsonEncoderDoesNotEscapeHTMLChars(t *testing.T) {
FILE: pkg/yqlib/encoder_toml.go
type tomlEncoder (line 14) | type tomlEncoder struct
method Encode (line 27) | func (te *tomlEncoder) Encode(writer io.Writer, node *CandidateNode) e...
method PrintDocumentSeparator (line 58) | func (te *tomlEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 62) | func (te *tomlEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method CanHandleAliases (line 66) | func (te *tomlEncoder) CanHandleAliases() bool {
method writeComment (line 72) | func (te *tomlEncoder) writeComment(w io.Writer, comment string) error {
method formatScalar (line 89) | func (te *tomlEncoder) formatScalar(node *CandidateNode) string {
method encodeRootMapping (line 104) | func (te *tomlEncoder) encodeRootMapping(w io.Writer, node *CandidateN...
method encodeTopLevelEntry (line 126) | func (te *tomlEncoder) encodeTopLevelEntry(w io.Writer, path []string,...
method writeAttribute (line 179) | func (te *tomlEncoder) writeAttribute(w io.Writer, key string, value *...
method writeArrayAttribute (line 203) | func (te *tomlEncoder) writeArrayAttribute(w io.Writer, key string, se...
method sequenceToInlineArray (line 342) | func (te *tomlEncoder) sequenceToInlineArray(seq *CandidateNode) (stri...
method mappingToInlineTable (line 367) | func (te *tomlEncoder) mappingToInlineTable(m *CandidateNode) (string,...
method writeInlineTableAttribute (line 397) | func (te *tomlEncoder) writeInlineTableAttribute(w io.Writer, key stri...
method writeTableHeader (line 406) | func (te *tomlEncoder) writeTableHeader(w io.Writer, path []string, m ...
method encodeSeparateMapping (line 431) | func (te *tomlEncoder) encodeSeparateMapping(w io.Writer, path []strin...
method hasEncodeSeparateChild (line 516) | func (te *tomlEncoder) hasEncodeSeparateChild(m *CandidateNode) bool {
method hasStructuralChildren (line 526) | func (te *tomlEncoder) hasStructuralChildren(m *CandidateNode) bool {
method encodeMappingBodyWithPath (line 550) | func (te *tomlEncoder) encodeMappingBodyWithPath(w io.Writer, path []s...
method colorizeToml (line 616) | func (te *tomlEncoder) colorizeToml(input []byte) []byte {
function NewTomlEncoder (line 19) | func NewTomlEncoder() Encoder {
function NewTomlEncoderWithPrefs (line 23) | func NewTomlEncoderWithPrefs(prefs TomlPreferences) Encoder {
FILE: pkg/yqlib/encoder_uri.go
type uriEncoder (line 11) | type uriEncoder struct
method CanHandleAliases (line 18) | func (e *uriEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 22) | func (e *uriEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 26) | func (e *uriEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
method Encode (line 30) | func (e *uriEncoder) Encode(writer io.Writer, node *CandidateNode) err...
function NewUriEncoder (line 14) | func NewUriEncoder() Encoder {
FILE: pkg/yqlib/encoder_xml.go
type xmlEncoder (line 13) | type xmlEncoder struct
method CanHandleAliases (line 29) | func (e *xmlEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 33) | func (e *xmlEncoder) PrintDocumentSeparator(_ io.Writer) error {
method PrintLeadingContent (line 37) | func (e *xmlEncoder) PrintLeadingContent(_ io.Writer, content string) ...
method Encode (line 42) | func (e *xmlEncoder) Encode(writer io.Writer, node *CandidateNode) err...
method encodeTopLevelMap (line 102) | func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *Can...
method encodeStart (line 161) | func (e *xmlEncoder) encodeStart(encoder *xml.Encoder, node *Candidate...
method encodeEnd (line 169) | func (e *xmlEncoder) encodeEnd(encoder *xml.Encoder, node *CandidateNo...
method doEncode (line 177) | func (e *xmlEncoder) doEncode(encoder *xml.Encoder, node *CandidateNod...
method encodeComment (line 208) | func (e *xmlEncoder) encodeComment(encoder *xml.Encoder, commentStr st...
method encodeArray (line 241) | func (e *xmlEncoder) encodeArray(encoder *xml.Encoder, node *Candidate...
method isAttribute (line 256) | func (e *xmlEncoder) isAttribute(name string) bool {
method encodeMap (line 263) | func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *CandidateNo...
function NewXMLEncoder (line 20) | func NewXMLEncoder(prefs XmlPreferences) Encoder {
FILE: pkg/yqlib/encoder_yaml.go
type yamlEncoder (line 11) | type yamlEncoder struct
method CanHandleAliases (line 19) | func (ye *yamlEncoder) CanHandleAliases() bool {
method PrintDocumentSeparator (line 23) | func (ye *yamlEncoder) PrintDocumentSeparator(writer io.Writer) error {
method PrintLeadingContent (line 27) | func (ye *yamlEncoder) PrintLeadingContent(writer io.Writer, content s...
method Encode (line 31) | func (ye *yamlEncoder) Encode(writer io.Writer, node *CandidateNode) e...
function NewYamlEncoder (line 15) | func NewYamlEncoder(prefs YamlPreferences) Encoder {
FILE: pkg/yqlib/expression_parser.go
type ExpressionNode (line 8) | type ExpressionNode struct
type ExpressionParserInterface (line 15) | type ExpressionParserInterface interface
type expressionParserImpl (line 19) | type expressionParserImpl struct
method ParseExpression (line 28) | func (p *expressionParserImpl) ParseExpression(expression string) (*Ex...
method createExpressionTree (line 42) | func (p *expressionParserImpl) createExpressionTree(postFixPath []*Ope...
function newExpressionParser (line 24) | func newExpressionParser() ExpressionParserInterface {
FILE: pkg/yqlib/expression_parser_test.go
function getExpressionParser (line 9) | func getExpressionParser() ExpressionParserInterface {
function TestParserCreateMapColonOnItsOwn (line 14) | func TestParserCreateMapColonOnItsOwn(t *testing.T) {
function TestParserNoMatchingCloseBracket (line 19) | func TestParserNoMatchingCloseBracket(t *testing.T) {
function TestParserNoMatchingCloseCollect (line 24) | func TestParserNoMatchingCloseCollect(t *testing.T) {
function TestParserNoMatchingCloseObjectInCollect (line 28) | func TestParserNoMatchingCloseObjectInCollect(t *testing.T) {
function TestParserNoMatchingCloseInCollect (line 33) | func TestParserNoMatchingCloseInCollect(t *testing.T) {
function TestParserNoMatchingCloseCollectObject (line 38) | func TestParserNoMatchingCloseCollectObject(t *testing.T) {
function TestParserNoMatchingCloseCollectInCollectObject (line 43) | func TestParserNoMatchingCloseCollectInCollectObject(t *testing.T) {
function TestParserNoMatchingCloseBracketInCollectObject (line 48) | func TestParserNoMatchingCloseBracketInCollectObject(t *testing.T) {
function TestParserNoArgsForTwoArgOp (line 53) | func TestParserNoArgsForTwoArgOp(t *testing.T) {
function TestParserOneLhsArgsForTwoArgOp (line 58) | func TestParserOneLhsArgsForTwoArgOp(t *testing.T) {
function TestParserOneRhsArgsForTwoArgOp (line 63) | func TestParserOneRhsArgsForTwoArgOp(t *testing.T) {
function TestParserTwoArgsForTwoArgOp (line 68) | func TestParserTwoArgsForTwoArgOp(t *testing.T) {
function TestParserNoArgsForOneArgOp (line 73) | func TestParserNoArgsForOneArgOp(t *testing.T) {
function TestParserOneArgForOneArgOp (line 78) | func TestParserOneArgForOneArgOp(t *testing.T) {
function TestParserExtraArgs (line 83) | func TestParserExtraArgs(t *testing.T) {
function TestParserEmptyExpression (line 88) | func TestParserEmptyExpression(t *testing.T) {
function TestParserSingleOperation (line 93) | func TestParserSingleOperation(t *testing.T) {
function TestParserFirstOpWithZeroArgs (line 104) | func TestParserFirstOpWithZeroArgs(t *testing.T) {
function TestParserInvalidExpressionTree (line 113) | func TestParserInvalidExpressionTree(t *testing.T) {
FILE: pkg/yqlib/expression_postfix.go
type expressionPostFixer (line 10) | type expressionPostFixer interface
type expressionPostFixerImpl (line 14) | type expressionPostFixerImpl struct
method ConvertToPostfix (line 40) | func (p *expressionPostFixerImpl) ConvertToPostfix(infixTokens []*toke...
function newExpressionPostFixer (line 17) | func newExpressionPostFixer() expressionPostFixer {
function popOpToResult (line 21) | func popOpToResult(opStack []*token, result []*Operation) ([]*token, []*...
function validateNoOpenTokens (line 28) | func validateNoOpenTokens(token *token) error {
FILE: pkg/yqlib/expression_processing_test.go
function TestPathParsing (line 318) | func TestPathParsing(t *testing.T) {
FILE: pkg/yqlib/file_utils.go
function tryRenameFile (line 9) | func tryRenameFile(from string, to string) error {
function tryRemoveTempFile (line 32) | func tryRemoveTempFile(filename string) {
function copyFileContents (line 41) | func copyFileContents(src, dst string) (err error) {
function SafelyCloseReader (line 61) | func SafelyCloseReader(reader io.Reader) {
function safelyCloseFile (line 68) | func safelyCloseFile(file *os.File) {
function createTempFile (line 76) | func createTempFile() (*os.File, error) {
FILE: pkg/yqlib/format.go
type EncoderFactoryFunction (line 10) | type EncoderFactoryFunction
type DecoderFactoryFunction (line 11) | type DecoderFactoryFunction
type Format (line 13) | type Format struct
method MatchesName (line 114) | func (f *Format) MatchesName(name string) bool {
method GetConfiguredEncoder (line 121) | func (f *Format) GetConfiguredEncoder() Encoder {
function FormatStringFromFilename (line 125) | func FormatStringFromFilename(filename string) string {
function FormatFromString (line 140) | func FormatFromString(format string) (*Format, error) {
function GetAvailableOutputFormats (line 151) | func GetAvailableOutputFormats() []*Format {
function GetAvailableOutputFormatString (line 161) | func GetAvailableOutputFormatString() string {
function GetAvailableInputFormats (line 175) | func GetAvailableInputFormats() []*Format {
function GetAvailableInputFormatString (line 185) | func GetAvailableInputFormatString() string {
FILE: pkg/yqlib/format_test.go
type formatStringScenario (line 11) | type formatStringScenario struct
function TestFormatFromString (line 36) | func TestFormatFromString(t *testing.T) {
function TestFormatStringFromFilename (line 54) | func TestFormatStringFromFilename(t *testing.T) {
FILE: pkg/yqlib/formatting_expressions_test.go
function documentExpressionScenario (line 45) | func documentExpressionScenario(_ *testing.T, w *bufio.Writer, i interfa...
function TestExpressionCommentScenarios (line 80) | func TestExpressionCommentScenarios(t *testing.T) {
FILE: pkg/yqlib/front_matter.go
type frontMatterHandler (line 10) | type frontMatterHandler interface
type frontMatterHandlerImpl (line 17) | type frontMatterHandlerImpl struct
method GetYamlFrontMatterFilename (line 27) | func (f *frontMatterHandlerImpl) GetYamlFrontMatterFilename() string {
method GetContentReader (line 31) | func (f *frontMatterHandlerImpl) GetContentReader() io.Reader {
method CleanUp (line 35) | func (f *frontMatterHandlerImpl) CleanUp() {
method Split (line 42) | func (f *frontMatterHandlerImpl) Split() error {
function NewFrontMatterHandler (line 23) | func NewFrontMatterHandler(originalFilename string) frontMatterHandler {
FILE: pkg/yqlib/front_matter_test.go
function createTestFile (line 11) | func createTestFile(content string) string {
function readFile (line 27) | func readFile(filename string) string {
function TestFrontMatterSplitWithLeadingSep (line 35) | func TestFrontMatterSplitWithLeadingSep(t *testing.T) {
function TestFrontMatterSplitWithNoLeadingSep (line 74) | func TestFrontMatterSplitWithNoLeadingSep(t *testing.T) {
function TestFrontMatterSplitWithArray (line 111) | func TestFrontMatterSplitWithArray(t *testing.T) {
FILE: pkg/yqlib/goccy_yaml_test.go
function testGoccyYamlScenario (line 274) | func testGoccyYamlScenario(t *testing.T, s formatScenario) {
function TestGoccyYmlFormatScenarios (line 278) | func TestGoccyYmlFormatScenarios(t *testing.T) {
FILE: pkg/yqlib/hcl.go
type HclPreferences (line 3) | type HclPreferences struct
method Copy (line 11) | func (p *HclPreferences) Copy() HclPreferences {
function NewDefaultHclPreferences (line 7) | func NewDefaultHclPreferences() HclPreferences {
FILE: pkg/yqlib/hcl_test.go
function testHclScenario (line 477) | func testHclScenario(t *testing.T, s formatScenario) {
function documentHclScenario (line 487) | func documentHclScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function documentHclDecodeScenario (line 503) | func documentHclDecodeScenario(w *bufio.Writer, s formatScenario) {
function documentHclRoundTripScenario (line 525) | func documentHclRoundTripScenario(w *bufio.Writer, s formatScenario) {
function TestHclEncoderPrintDocumentSeparator (line 547) | func TestHclEncoderPrintDocumentSeparator(t *testing.T) {
function TestHclEncoderPrintLeadingContent (line 559) | func TestHclEncoderPrintLeadingContent(t *testing.T) {
function TestHclEncoderCanHandleAliases (line 571) | func TestHclEncoderCanHandleAliases(t *testing.T) {
function TestHclFormatScenarios (line 576) | func TestHclFormatScenarios(t *testing.T) {
FILE: pkg/yqlib/ini.go
type INIPreferences (line 3) | type INIPreferences struct
method Copy (line 13) | func (p *INIPreferences) Copy() INIPreferences {
function NewDefaultINIPreferences (line 7) | func NewDefaultINIPreferences() INIPreferences {
FILE: pkg/yqlib/ini_test.go
constant simpleINIInput (line 13) | simpleINIInput = `[section]
constant expectedSimpleINIOutput (line 17) | expectedSimpleINIOutput = `[section]
constant expectedSimpleINIYaml (line 21) | expectedSimpleINIYaml = `section:
function documentRoundtripINIScenario (line 52) | func documentRoundtripINIScenario(w *bufio.Writer, s formatScenario) {
function documentDecodeINIScenario (line 76) | func documentDecodeINIScenario(w *bufio.Writer, s formatScenario) {
function testINIScenario (line 100) | func testINIScenario(t *testing.T, s formatScenario) {
function documentINIScenario (line 120) | func documentINIScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function documentINIEncodeScenario (line 139) | func documentINIEncodeScenario(w *bufio.Writer, s formatScenario) {
function documentDecodeErrorINIScenario (line 163) | func documentDecodeErrorINIScenario(w *bufio.Writer, s formatScenario) {
function TestINIScenarios (line 178) | func TestINIScenarios(t *testing.T) {
FILE: pkg/yqlib/json.go
type JsonPreferences (line 3) | type JsonPreferences struct
method Copy (line 17) | func (p *JsonPreferences) Copy() JsonPreferences {
function NewDefaultJsonPreferences (line 9) | func NewDefaultJsonPreferences() JsonPreferences {
FILE: pkg/yqlib/json_test.go
constant complexExpectYaml (line 14) | complexExpectYaml = `a: Easy! as one two three
constant sampleNdJson (line 22) | sampleNdJson = `{"this": "is a multidoc json file"}
constant sampleNdJsonKey (line 27) | sampleNdJsonKey = `{"a": "first", "b": "next", "ab": "last"}`
constant expectedJsonKeysInOrder (line 29) | expectedJsonKeysInOrder = `a: first
constant expectedNdJsonYaml (line 34) | expectedNdJsonYaml = `this: is a multidoc json file
constant expectedRoundTripSampleNdJson (line 42) | expectedRoundTripSampleNdJson = `{"this":"is a multidoc json file"}
constant expectedUpdatedMultilineJson (line 47) | expectedUpdatedMultilineJson = `{"this":"is a multidoc json file"}
constant sampleMultiLineJson (line 52) | sampleMultiLineJson = `{
constant roundTripMultiLineJson (line 67) | roundTripMultiLineJson = `{
function documentRoundtripNdJsonScenario (line 310) | func documentRoundtripNdJsonScenario(w *bufio.Writer, s formatScenario, ...
function documentDecodeNdJsonScenario (line 338) | func documentDecodeNdJsonScenario(w *bufio.Writer, s formatScenario) {
function decodeJSON (line 363) | func decodeJSON(t *testing.T, jsonString string) *CandidateNode {
function testJSONScenario (line 388) | func testJSONScenario(t *testing.T, s formatScenario) {
function documentJSONDecodeScenario (line 416) | func documentJSONDecodeScenario(t *testing.T, w *bufio.Writer, s formatS...
function documentJSONScenario (line 445) | func documentJSONScenario(t *testing.T, w *bufio.Writer, i interface{}) {
function documentJSONEncodeScenario (line 467) | func documentJSONEncodeScenario(w *bufio.Writer, s formatScenario) {
function TestJSONScenarios (line 498) | func TestJSONScenarios(t *testing.T) {
FILE: pkg/yqlib/kyaml.go
type KYamlPreferences (line 5) | type KYamlPreferences struct
method Copy (line 21) | func (p *KYamlPreferences) Copy() KYamlPreferences {
function NewDefaultKYamlPreferences (line 12) | func NewDefaultKYamlPreferences() KYamlPreferences {
FILE: pkg/yqlib/kyaml_test.go
function stripANSI (line 18) | func stripANSI(s string) string {
function testKYamlScenario (line 213) | func testKYamlScenario(t *testing.T, s formatScenario) {
function documentKYamlScenario (line 231) | func documentKYamlScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function documentKYamlEncodeScenario (line 245) | func documentKYamlEncodeScenario(w *bufio.Writer, s formatScenario) {
function TestKYamlFormatScenarios (line 278) | func TestKYamlFormatScenarios(t *testing.T) {
function TestKYamlEncoderPrintDocumentSeparator (line 290) | func TestKYamlEncoderPrintDocumentSeparator(t *testing.T) {
function TestKYamlEncoderEncodeUnwrapScalar (line 320) | func TestKYamlEncoderEncodeUnwrapScalar(t *testing.T) {
function TestKYamlEncoderEncodeColorsEnabled (line 338) | func TestKYamlEncoderEncodeColorsEnabled(t *testing.T) {
function TestKYamlEncoderWriteNodeAliasAndUnknown (line 361) | func TestKYamlEncoderWriteNodeAliasAndUnknown(t *testing.T) {
function TestKYamlEncoderEmptyCollections (line 401) | func TestKYamlEncoderEmptyCollections(t *testing.T) {
function TestKYamlEncoderScalarFallbackAndEscaping (line 427) | func TestKYamlEncoderScalarFallbackAndEscaping(t *testing.T) {
function TestKYamlEncoderCommentsInMapping (line 462) | func TestKYamlEncoderCommentsInMapping(t *testing.T) {
function TestKYamlEncoderCommentBlockAndInlineComment (line 506) | func TestKYamlEncoderCommentBlockAndInlineComment(t *testing.T) {
FILE: pkg/yqlib/lexer.go
type expressionTokeniser (line 8) | type expressionTokeniser interface
type tokenType (line 12) | type tokenType
constant operationToken (line 15) | operationToken = 1 << iota
constant openBracket (line 16) | openBracket
constant closeBracket (line 17) | closeBracket
constant openCollect (line 18) | openCollect
constant closeCollect (line 19) | closeCollect
constant openCollectObject (line 20) | openCollectObject
constant closeCollectObject (line 21) | closeCollectObject
constant traverseArrayCollect (line 22) | traverseArrayCollect
type token (line 25) | type token struct
method toString (line 33) | func (t *token) toString(detail bool) string {
function unwrap (line 59) | func unwrap(value string) string {
function extractNumberParameter (line 63) | func extractNumberParameter(value string) (int, error) {
function hasOptionParameter (line 73) | func hasOptionParameter(value string, option string) bool {
function postProcessTokens (line 84) | func postProcessTokens(tokens []*token) []*token {
function tokenIsOpType (line 100) | func tokenIsOpType(token *token, opType *operationType) bool {
function handleToken (line 104) | func handleToken(tokens []*token, index int, postProcessedTokens []*toke...
FILE: pkg/yqlib/lexer_participle.go
type yqAction (line 236) | type yqAction
type participleYqRule (line 238) | type participleYqRule struct
type participleLexer (line 245) | type participleLexer struct
method getYqDefinition (line 572) | func (p *participleLexer) getYqDefinition(rawToken lexer.Token) *parti...
method Tokenise (line 581) | func (p *participleLexer) Tokenise(expression string) ([]*token, error) {
function simpleOp (line 249) | func simpleOp(name string, opType *operationType) *participleYqRule {
function assignableOp (line 253) | func assignableOp(name string, opType *operationType, assignOpType *oper...
function newParticipleLexer (line 257) | func newParticipleLexer() expressionTokeniser {
function pathToken (line 272) | func pathToken(wrapped bool) yqAction {
function recursiveDecentOpToken (line 292) | func recursiveDecentOpToken(includeMapKeys bool) yqAction {
function opTokenWithPrefs (line 303) | func opTokenWithPrefs(opType *operationType, assignOpType *operationType...
function expressionOpToken (line 315) | func expressionOpToken(expression string) yqAction {
function flattenWithDepth (line 323) | func flattenWithDepth() yqAction {
function assignAllCommentsOp (line 337) | func assignAllCommentsOp(updateAssign bool) yqAction {
function assignOpToken (line 352) | func assignOpToken(updateAssign bool) yqAction {
function booleanValue (line 365) | func booleanValue(val bool) yqAction {
function nullValue (line 371) | func nullValue() yqAction {
function stringValue (line 377) | func stringValue() yqAction {
function envOp (line 391) | func envOp(strenv bool) yqAction {
function envSubstWithOptions (line 413) | func envSubstWithOptions() yqAction {
function multiplyWithPrefs (line 433) | func multiplyWithPrefs(op *operationType) yqAction {
function getVariableOpToken (line 461) | func getVariableOpToken() yqAction {
function hexValue (line 474) | func hexValue() yqAction {
function floatValue (line 488) | func floatValue() yqAction {
function numberValue (line 499) | func numberValue() yqAction {
function parentWithLevel (line 511) | func parentWithLevel() yqAction {
function parentWithDefaultLevel (line 525) | func parentWithDefaultLevel() yqAction {
function encodeParseIndent (line 533) | func encodeParseIndent(outputFormat *Format) yqAction {
function encodeWithIndent (line 547) | func encodeWithIndent(outputFormat *Format, indent int) yqAction {
function decodeOp (line 552) | func decodeOp(format *Format) yqAction {
function loadOp (line 557) | func loadOp(decoder Decoder) yqAction {
function opToken (line 562) | func opToken(op *operationType) yqAction {
function literalToken (line 566) | func literalToken(tt tokenType, checkForPost bool) yqAction {
FILE: pkg/yqlib/lexer_participle_test.go
type participleLexerScenario (line 10) | type participleLexerScenario struct
function TestParticipleLexer (line 793) | func TestParticipleLexer(t *testing.T) {
FILE: pkg/yqlib/lib.go
function InitExpressionParser (line 16) | func InitExpressionParser() {
function GetLogger (line 27) | func GetLogger() *logging.Logger {
function getContentValueByKey (line 31) | func getContentValueByKey(content []*CandidateNode, key string) *Candida...
function recurseNodeArrayEqual (line 42) | func recurseNodeArrayEqual(lhs *CandidateNode, rhs *CandidateNode) bool {
function findInArray (line 55) | func findInArray(array *CandidateNode, item *CandidateNode) int {
function findKeyInMap (line 65) | func findKeyInMap(dataMap *CandidateNode, item *CandidateNode) int {
function recurseNodeObjectEqual (line 75) | func recurseNodeObjectEqual(lhs *CandidateNode, rhs *CandidateNode) bool {
function parseSnippet (line 93) | func parseSnippet(value string) (*CandidateNode, error) {
function recursiveNodeEqual (line 129) | func recursiveNodeEqual(lhs *CandidateNode, rhs *CandidateNode) bool {
function parseInt64 (line 160) | func parseInt64(numberString string) (string, int64, error) {
function parseInt (line 177) | func parseInt(numberString string) (int, error) {
function processEscapeCharacters (line 189) | func processEscapeCharacters(original string) string {
function headAndLineComment (line 259) | func headAndLineComment(node *CandidateNode) string {
function headComment (line 263) | func headComment(node *CandidateNode) string {
function lineComment (line 267) | func lineComment(node *CandidateNode) string {
function footComment (line 271) | func footComment(node *CandidateNode) string {
function NodesToString (line 276) | func NodesToString(collection *list.List) string {
function NodeToString (line 288) | func NodeToString(node *CandidateNode) string {
function NodeContentToString (line 306) | func NodeContentToString(node *CandidateNode, depth int) string {
function KindString (line 323) | func KindString(kind Kind) string {
FILE: pkg/yqlib/lib_test.go
function TestGetLogger (line 11) | func TestGetLogger(t *testing.T) {
type parseSnippetScenario (line 18) | type parseSnippetScenario struct
function TestParseSnippet (line 98) | func TestParseSnippet(t *testing.T) {
type parseInt64Scenario (line 117) | type parseInt64Scenario struct
function TestParseInt64 (line 148) | func TestParseInt64(t *testing.T) {
function TestGetContentValueByKey (line 165) | func TestGetContentValueByKey(t *testing.T) {
function TestRecurseNodeArrayEqual (line 191) | func TestRecurseNodeArrayEqual(t *testing.T) {
function TestFindInArray (line 229) | func TestFindInArray(t *testing.T) {
function TestFindKeyInMap (line 249) | func TestFindKeyInMap(t *testing.T) {
function TestRecurseNodeObjectEqual (line 269) | func TestRecurseNodeObjectEqual(t *testing.T) {
function TestParseInt (line 305) | func TestParseInt(t *testing.T) {
function TestHeadAndLineComment (line 352) | func TestHeadAndLineComment(t *testing.T) {
function TestHeadComment (line 362) | func TestHeadComment(t *testing.T) {
function TestLineComment (line 376) | func TestLineComment(t *testing.T) {
function TestFootComment (line 390) | func TestFootComment(t *testing.T) {
function TestKindString (line 404) | func TestKindString(t *testing.T) {
type processEscapeCharactersScenario (line 412) | type processEscapeCharactersScenario struct
function TestProcessEscapeCharacters (line 524) | func TestProcessEscapeCharacters(t *testing.T) {
FILE: pkg/yqlib/lua.go
type LuaPreferences (line 3) | type LuaPreferences struct
function NewDefaultLuaPreferences (line 10) | func NewDefaultLuaPreferences() LuaPreferences {
FILE: pkg/yqlib/lua_test.go
function testLuaScenario (line 253) | func testLuaScenario(t *testing.T, s formatScenario) {
function documentLuaScenario (line 280) | func documentLuaScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function documentLuaDecodeScenario (line 298) | func documentLuaDecodeScenario(w *bufio.Writer, s formatScenario) {
function documentLuaEncodeScenario (line 320) | func documentLuaEncodeScenario(w *bufio.Writer, s formatScenario) {
function documentLuaRoundTripScenario (line 362) | func documentLuaRoundTripScenario(w *bufio.Writer, s formatScenario) {
function TestLuaScenarios (line 380) | func TestLuaScenarios(t *testing.T) {
FILE: pkg/yqlib/matchKeyString.go
function matchKey (line 3) | func matchKey(name string, pattern string) (matched bool) {
function deepMatch (line 16) | func deepMatch(name, pattern string) bool {
FILE: pkg/yqlib/matchKeyString_test.go
function TestDeepMatch (line 8) | func TestDeepMatch(t *testing.T) {
FILE: pkg/yqlib/no_base64.go
function NewBase64Decoder (line 5) | func NewBase64Decoder() Decoder {
function NewBase64Encoder (line 9) | func NewBase64Encoder() Encoder {
FILE: pkg/yqlib/no_csv.go
function NewCSVObjectDecoder (line 5) | func NewCSVObjectDecoder(prefs CsvPreferences) Decoder {
function NewCsvEncoder (line 9) | func NewCsvEncoder(prefs CsvPreferences) Encoder {
FILE: pkg/yqlib/no_hcl.go
function NewHclDecoder (line 5) | func NewHclDecoder() Decoder {
function NewHclEncoder (line 9) | func NewHclEncoder(_ HclPreferences) Encoder {
FILE: pkg/yqlib/no_ini.go
function NewINIDecoder (line 5) | func NewINIDecoder() Decoder {
function NewINIEncoder (line 9) | func NewINIEncoder() Encoder {
FILE: pkg/yqlib/no_json.go
function NewJSONDecoder (line 5) | func NewJSONDecoder() Decoder {
function NewJSONEncoder (line 9) | func NewJSONEncoder(prefs JsonPreferences) Encoder {
FILE: pkg/yqlib/no_kyaml.go
function NewKYamlEncoder (line 5) | func NewKYamlEncoder(_ KYamlPreferences) Encoder {
FILE: pkg/yqlib/no_lua.go
function NewLuaEncoder (line 5) | func NewLuaEncoder(prefs LuaPreferences) Encoder {
function NewLuaDecoder (line 9) | func NewLuaDecoder(prefs LuaPreferences) Decoder {
FILE: pkg/yqlib/no_props.go
function NewPropertiesDecoder (line 5) | func NewPropertiesDecoder() Decoder {
function NewPropertiesEncoder (line 9) | func NewPropertiesEncoder(prefs PropertiesPreferences) Encoder {
FILE: pkg/yqlib/no_sh.go
function NewShEncoder (line 5) | func NewShEncoder() Encoder {
FILE: pkg/yqlib/no_shellvariables.go
function NewShellVariablesEncoder (line 5) | func NewShellVariablesEncoder() Encoder {
FILE: pkg/yqlib/no_toml.go
function NewTomlDecoder (line 5) | func NewTomlDecoder() Decoder {
function NewTomlEncoder (line 9) | func NewTomlEncoder() Encoder {
function NewTomlEncoderWithPrefs (line 13) | func NewTomlEncoderWithPrefs(prefs TomlPreferences) Encoder {
FILE: pkg/yqlib/no_uri.go
function NewUriDecoder (line 5) | func NewUriDecoder() Decoder {
function NewUriEncoder (line 9) | func NewUriEncoder() Encoder {
FILE: pkg/yqlib/no_xml.go
function NewXMLDecoder (line 5) | func NewXMLDecoder(prefs XmlPreferences) Decoder {
function NewXMLEncoder (line 9) | func NewXMLEncoder(prefs XmlPreferences) Encoder {
FILE: pkg/yqlib/operation.go
type Operation (line 5) | type Operation struct
method toString (line 201) | func (p *Operation) toString() string {
type operationType (line 14) | type operationType struct
function createValueOperation (line 27) | func createValueOperation(value interface{}, stringValue string) *Operat...
FILE: pkg/yqlib/operator_add.go
function createAddOp (line 10) | func createAddOp(lhs *ExpressionNode, rhs *ExpressionNode) *ExpressionNo...
function addAssignOperator (line 16) | func addAssignOperator(d *dataTreeNavigator, context Context, expression...
function toNodes (line 20) | func toNodes(candidate *CandidateNode, lhs *CandidateNode) []*CandidateN...
function addOperator (line 39) | func addOperator(d *dataTreeNavigator, context Context, expressionNode *...
function add (line 48) | func add(_ *dataTreeNavigator, context Context, lhs *CandidateNode, rhs ...
function addScalars (line 84) | func addScalars(context Context, target *CandidateNode, lhs *CandidateNo...
function addDateTimes (line 150) | func addDateTimes(layout string, target *CandidateNode, lhs *CandidateNo...
function addSequences (line 168) | func addSequences(target *CandidateNode, lhs *CandidateNode, rhs *Candid...
function addMaps (line 183) | func addMaps(target *CandidateNode, lhsC *CandidateNode, rhsC *Candidate...
FILE: pkg/yqlib/operator_add_test.go
function TestAddOperatorScenarios (line 532) | func TestAddOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_alternative.go
function alternativeOperator (line 3) | func alternativeOperator(d *dataTreeNavigator, context Context, expressi...
function alternativeFunc (line 22) | func alternativeFunc(_ *dataTreeNavigator, _ Context, lhs *CandidateNode...
FILE: pkg/yqlib/operator_alternative_test.go
function TestAlternativeOperatorScenarios (line 108) | func TestAlternativeOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_anchors_aliases.go
function assignAliasOperator (line 10) | func assignAliasOperator(d *dataTreeNavigator, context Context, expressi...
function getAliasOperator (line 53) | func getAliasOperator(_ *dataTreeNavigator, context Context, _ *Expressi...
function assignAnchorOperator (line 65) | func assignAnchorOperator(d *dataTreeNavigator, context Context, express...
function getAnchorOperator (line 107) | func getAnchorOperator(_ *dataTreeNavigator, context Context, _ *Express...
function explodeOperator (line 120) | func explodeOperator(d *dataTreeNavigator, context Context, expressionNo...
function fixedReconstructAliasedMap (line 143) | func fixedReconstructAliasedMap(node *CandidateNode) error {
function reconstructAliasedMap (line 196) | func reconstructAliasedMap(node *CandidateNode, context Context) error {
function explodeNode (line 236) | func explodeNode(node *CandidateNode, context Context) error {
function applyAlias (line 302) | func applyAlias(node *CandidateNode, alias *CandidateNode, aliasIndex in...
function overrideEntry (line 323) | func overrideEntry(node *CandidateNode, key *CandidateNode, value *Candi...
FILE: pkg/yqlib/operator_anchors_aliases_test.go
function TestAnchorAliasOperatorScenarios (line 502) | func TestAnchorAliasOperatorScenarios(t *testing.T) {
function TestAnchorAliasOperatorAlignedToSpecScenarios (line 509) | func TestAnchorAliasOperatorAlignedToSpecScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_array_to_map_test.go
function TestArrayToMapScenarios (line 18) | func TestArrayToMapScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_assign.go
type assignPreferences (line 3) | type assignPreferences struct
function assignUpdateFunc (line 9) | func assignUpdateFunc(prefs assignPreferences) crossFunctionCalculation {
function getAssignPreferences (line 20) | func getAssignPreferences(preferences interface{}) assignPreferences {
function assignUpdateOperator (line 32) | func assignUpdateOperator(d *dataTreeNavigator, context Context, express...
function assignAttributesOperator (line 74) | func assignAttributesOperator(d *dataTreeNavigator, context Context, exp...
FILE: pkg/yqlib/operator_assign_test.go
function TestAssignOperatorScenarios (line 252) | func TestAssignOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_booleans.go
function isTruthyNode (line 9) | func isTruthyNode(node *CandidateNode) bool {
function getOwner (line 27) | func getOwner(lhs *CandidateNode, rhs *CandidateNode) *CandidateNode {
function returnRhsTruthy (line 38) | func returnRhsTruthy(_ *dataTreeNavigator, _ Context, lhs *CandidateNode...
function returnLHSWhen (line 45) | func returnLHSWhen(targetBool bool) func(lhs *CandidateNode) (*Candidate...
function findBoolean (line 61) | func findBoolean(wantBool bool, d *dataTreeNavigator, context Context, e...
function allOperator (line 85) | func allOperator(d *dataTreeNavigator, context Context, expressionNode *...
function anyOperator (line 103) | func anyOperator(d *dataTreeNavigator, context Context, expressionNode *...
function orOperator (line 121) | func orOperator(d *dataTreeNavigator, context Context, expressionNode *E...
function andOperator (line 130) | func andOperator(d *dataTreeNavigator, context Context, expressionNode *...
function notOperator (line 139) | func notOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNod...
FILE: pkg/yqlib/operator_booleans_test.go
function TestBooleanOperatorScenarios (line 271) | func TestBooleanOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_collect.go
function collectTogether (line 7) | func collectTogether(d *dataTreeNavigator, context Context, expressionNo...
function collectOperator (line 24) | func collectOperator(d *dataTreeNavigator, context Context, expressionNo...
FILE: pkg/yqlib/operator_collect_object.go
function collectObjectOperator (line 19) | func collectObjectOperator(d *dataTreeNavigator, originalContext Context...
function collect (line 75) | func collect(d *dataTreeNavigator, context Context, remainingMatches *li...
FILE: pkg/yqlib/operator_collect_object_test.go
function TestCollectObjectOperatorScenarios (line 204) | func TestCollectObjectOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_collect_test.go
function TestCollectOperatorScenarios (line 139) | func TestCollectOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_column.go
function columnOperator (line 8) | func columnOperator(_ *dataTreeNavigator, context Context, _ *Expression...
FILE: pkg/yqlib/operator_column_test.go
function TestColumnOperatorScenarios (line 42) | func TestColumnOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_comments.go
type commentOpPreferences (line 10) | type commentOpPreferences struct
function assignCommentsOperator (line 16) | func assignCommentsOperator(d *dataTreeNavigator, context Context, expre...
function getCommentsOperator (line 75) | func getCommentsOperator(_ *dataTreeNavigator, context Context, expressi...
FILE: pkg/yqlib/operator_comments_test.go
function TestCommentOperatorScenarios (line 301) | func TestCommentOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_compare.go
type compareTypePref (line 9) | type compareTypePref struct
function compareOperator (line 14) | func compareOperator(d *dataTreeNavigator, context Context, expressionNo...
function compare (line 20) | func compare(prefs compareTypePref) func(d *dataTreeNavigator, context C...
function compareDateTime (line 51) | func compareDateTime(layout string, prefs compareTypePref, lhs *Candidat...
function compareScalars (line 72) | func compareScalars(context Context, prefs compareTypePref, lhs *Candida...
function superlativeByComparison (line 134) | func superlativeByComparison(d *dataTreeNavigator, context Context, pref...
function minOperator (line 161) | func minOperator(d *dataTreeNavigator, context Context, _ *ExpressionNod...
function maxOperator (line 166) | func maxOperator(d *dataTreeNavigator, context Context, _ *ExpressionNod...
FILE: pkg/yqlib/operator_contains.go
function containsOperator (line 8) | func containsOperator(d *dataTreeNavigator, context Context, expressionN...
function containsArrayElement (line 12) | func containsArrayElement(array *CandidateNode, item *CandidateNode) (bo...
function containsArray (line 25) | func containsArray(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
function containsObject (line 41) | func containsObject(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
function containsScalars (line 69) | func containsScalars(lhs *CandidateNode, rhs *CandidateNode) (bool, erro...
function contains (line 76) | func contains(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
function containsWithNodes (line 95) | func containsWithNodes(_ *dataTreeNavigator, _ Context, lhs *CandidateNo...
FILE: pkg/yqlib/operator_contains_test.go
function TestContainsOperatorScenarios (line 86) | func TestContainsOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_create_map.go
function createMapOperator (line 7) | func createMapOperator(d *dataTreeNavigator, context Context, expression...
function sequenceFor (line 39) | func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *Ca...
function listToNodeSeq (line 83) | func listToNodeSeq(list *list.List) *CandidateNode {
FILE: pkg/yqlib/operator_create_map_test.go
function TestCreateMapOperatorScenarios (line 109) | func TestCreateMapOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_datetime.go
function getStringParameter (line 11) | func getStringParameter(parameterName string, d *dataTreeNavigator, cont...
function withDateTimeFormat (line 23) | func withDateTimeFormat(d *dataTreeNavigator, context Context, expressio...
function nowOp (line 40) | func nowOp(_ *dataTreeNavigator, context Context, _ *ExpressionNode) (Co...
function parseDateTime (line 52) | func parseDateTime(layout string, datestring string) (time.Time, error) {
function formatDateTime (line 63) | func formatDateTime(d *dataTreeNavigator, context Context, expressionNod...
function tzOp (line 98) | func tzOp(d *dataTreeNavigator, context Context, expressionNode *Express...
function parseUnixTime (line 127) | func parseUnixTime(unixTime string) (time.Time, error) {
function fromUnixOp (line 137) | func fromUnixOp(_ *dataTreeNavigator, context Context, _ *ExpressionNode...
function toUnixOp (line 163) | func toUnixOp(_ *dataTreeNavigator, context Context, _ *ExpressionNode) ...
FILE: pkg/yqlib/operator_datetime_test.go
function TestDatetimeOperatorScenarios (line 131) | func TestDatetimeOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_delete.go
function deleteChildOperator (line 8) | func deleteChildOperator(d *dataTreeNavigator, context Context, expressi...
function removeFromContext (line 41) | func removeFromContext(context Context, candidate *CandidateNode) (Conte...
function deleteFromMap (line 54) | func deleteFromMap(node *CandidateNode, childPath interface{}) {
function deleteFromArray (line 74) | func deleteFromArray(node *CandidateNode, childPath interface{}) {
FILE: pkg/yqlib/operator_delete_test.go
function TestDeleteOperatorScenarios (line 247) | func TestDeleteOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_divide.go
function divideOperator (line 9) | func divideOperator(d *dataTreeNavigator, context Context, expressionNod...
function divide (line 15) | func divide(_ *dataTreeNavigator, _ Context, lhs *CandidateNode, rhs *Ca...
function divideScalars (line 33) | func divideScalars(target *CandidateNode, lhs *CandidateNode, rhs *Candi...
FILE: pkg/yqlib/operator_divide_test.go
function TestDivideOperatorScenarios (line 125) | func TestDivideOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_document_index.go
function getDocumentIndexOperator (line 8) | func getDocumentIndexOperator(_ *dataTreeNavigator, context Context, _ *...
FILE: pkg/yqlib/operator_document_index_test.go
function TestDocumentIndexScenarios (line 53) | func TestDocumentIndexScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_encoder_decoder.go
function configureEncoder (line 12) | func configureEncoder(format *Format, indent int) Encoder {
function encodeToString (line 34) | func encodeToString(candidate *CandidateNode, prefs encoderPreferences) ...
type encoderPreferences (line 48) | type encoderPreferences struct
function encodeOperator (line 56) | func encodeOperator(_ *dataTreeNavigator, context Context, expressionNod...
type decoderPreferences (line 95) | type decoderPreferences struct
function decodeOperator (line 100) | func decodeOperator(_ *dataTreeNavigator, context Context, expressionNod...
FILE: pkg/yqlib/operator_encoder_decoder_test.go
function TestEncoderDecoderOperatorScenarios (line 340) | func TestEncoderDecoderOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_entries.go
function entrySeqFor (line 8) | func entrySeqFor(key *CandidateNode, value *CandidateNode) *CandidateNode {
function toEntriesFromMap (line 17) | func toEntriesFromMap(candidateNode *CandidateNode) *CandidateNode {
function toEntriesfromSeq (line 30) | func toEntriesfromSeq(candidateNode *CandidateNode) *CandidateNode {
function toEntriesOperator (line 43) | func toEntriesOperator(_ *dataTreeNavigator, context Context, _ *Express...
function parseEntry (line 64) | func parseEntry(candidateNode *CandidateNode, position int) (*CandidateN...
function fromEntries (line 87) | func fromEntries(candidateNode *CandidateNode) (*CandidateNode, error) {
function fromEntriesOperator (line 105) | func fromEntriesOperator(_ *dataTreeNavigator, context Context, _ *Expre...
function withEntriesOperator (line 125) | func withEntriesOperator(d *dataTreeNavigator, context Context, expressi...
FILE: pkg/yqlib/operator_entries_test.go
function TestEntriesOperatorScenarios (line 140) | func TestEntriesOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_env.go
type envOpPreferences (line 12) | type envOpPreferences struct
function envOperator (line 19) | func envOperator(_ *dataTreeNavigator, context Context, expressionNode *...
function envsubstOperator (line 59) | func envsubstOperator(_ *dataTreeNavigator, context Context, expressionN...
FILE: pkg/yqlib/operator_env_test.go
function TestEnvOperatorScenarios (line 175) | func TestEnvOperatorScenarios(t *testing.T) {
function TestEnvOperatorSecurityDisabledScenarios (line 203) | func TestEnvOperatorSecurityDisabledScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_equals.go
function equalsOperator (line 3) | func equalsOperator(d *dataTreeNavigator, context Context, expressionNod...
function isEquals (line 8) | func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs...
function notEqualsOperator (line 45) | func notEqualsOperator(d *dataTreeNavigator, context Context, expression...
FILE: pkg/yqlib/operator_equals_test.go
function TestEqualOperatorScenarios (line 192) | func TestEqualOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_error.go
function errorOperator (line 7) | func errorOperator(d *dataTreeNavigator, context Context, expressionNode...
FILE: pkg/yqlib/operator_error_test.go
constant validationExpression (line 5) | validationExpression = `
function TestErrorOperatorScenarios (line 35) | func TestErrorOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_eval.go
function evalOperator (line 7) | func evalOperator(d *dataTreeNavigator, context Context, expressionNode ...
FILE: pkg/yqlib/operator_eval_test.go
function TestEvalOperatorsScenarios (line 38) | func TestEvalOperatorsScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_expression.go
type expressionOpPreferences (line 3) | type expressionOpPreferences struct
function expressionOperator (line 7) | func expressionOperator(d *dataTreeNavigator, context Context, expressio...
FILE: pkg/yqlib/operator_file.go
function getFilenameOperator (line 8) | func getFilenameOperator(_ *dataTreeNavigator, context Context, _ *Expre...
function getFileIndexOperator (line 22) | func getFileIndexOperator(_ *dataTreeNavigator, context Context, _ *Expr...
FILE: pkg/yqlib/operator_file_test.go
function TestFileOperatorsScenarios (line 52) | func TestFileOperatorsScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_filter.go
function filterOperator (line 7) | func filterOperator(d *dataTreeNavigator, context Context, expressionNod...
FILE: pkg/yqlib/operator_filter_test.go
function TestFilterOperatorScenarios (line 62) | func TestFilterOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_first.go
function firstOperator (line 5) | func firstOperator(d *dataTreeNavigator, context Context, expressionNode...
FILE: pkg/yqlib/operator_first_test.go
function TestFirstOperatorScenarios (line 181) | func TestFirstOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_flatten.go
type flattenPreferences (line 7) | type flattenPreferences struct
function flatten (line 11) | func flatten(node *CandidateNode, depth int) {
function flattenOp (line 35) | func flattenOp(_ *dataTreeNavigator, context Context, expressionNode *Ex...
FILE: pkg/yqlib/operator_flatten_test.go
function TestFlattenOperatorScenarios (line 65) | func TestFlattenOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_group_by.go
function processIntoGroups (line 10) | func processIntoGroups(d *dataTreeNavigator, context Context, rhsExp *Ex...
function groupBy (line 38) | func groupBy(d *dataTreeNavigator, context Context, expressionNode *Expr...
FILE: pkg/yqlib/operator_group_by_test.go
function TestGroupByOperatorScenarios (line 36) | func TestGroupByOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_has.go
function hasOperator (line 8) | func hasOperator(d *dataTreeNavigator, context Context, expressionNode *...
FILE: pkg/yqlib/operator_has_test.go
function TestHasOperatorScenarios (line 76) | func TestHasOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_keys.go
function isKeyOperator (line 8) | func isKeyOperator(_ *dataTreeNavigator, context Context, _ *ExpressionN...
function getKeyOperator (line 22) | func getKeyOperator(_ *dataTreeNavigator, context Context, _ *Expression...
function keysOperator (line 39) | func keysOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNo...
function getMapKeys (line 63) | func getMapKeys(node *CandidateNode) *CandidateNode {
function getIndices (line 74) | func getIndices(node *CandidateNode) *CandidateNode {
FILE: pkg/yqlib/operator_keys_test.go
function TestKeysOperatorScenarios (line 124) | func TestKeysOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_kind.go
function kindToText (line 7) | func kindToText(kind Kind) string {
function getKindOperator (line 22) | func getKindOperator(_ *dataTreeNavigator, context Context, _ *Expressio...
FILE: pkg/yqlib/operator_kind_test.go
function TestKindOperatorScenarios (line 44) | func TestKindOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_length.go
function lengthOperator (line 8) | func lengthOperator(_ *dataTreeNavigator, context Context, _ *Expression...
FILE: pkg/yqlib/operator_length_test.go
function TestLengthOperatorScenarios (line 61) | func TestLengthOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_line.go
function lineOperator (line 8) | func lineOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNo...
FILE: pkg/yqlib/operator_line_test.go
function TestLineOperatorScenarios (line 42) | func TestLineOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_load.go
type loadPrefs (line 17) | type loadPrefs struct
function loadString (line 21) | func loadString(filename string) (*CandidateNode, error) {
function loadWithDecoder (line 33) | func loadWithDecoder(filename string, decoder Decoder) (*CandidateNode, ...
function loadStringOperator (line 64) | func loadStringOperator(d *dataTreeNavigator, context Context, expressio...
function loadOperator (line 98) | func loadOperator(d *dataTreeNavigator, context Context, expressionNode ...
FILE: pkg/yqlib/operator_load_test.go
function TestLoadScenarios (line 128) | func TestLoadScenarios(t *testing.T) {
function TestLoadOperatorSecurityDisabledScenarios (line 168) | func TestLoadOperatorSecurityDisabledScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_map.go
function mapValuesOperator (line 7) | func mapValuesOperator(d *dataTreeNavigator, context Context, expression...
function mapOperator (line 32) | func mapOperator(d *dataTreeNavigator, context Context, expressionNode *...
FILE: pkg/yqlib/operator_map_test.go
function TestMapOperatorScenarios (line 132) | func TestMapOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_modulo.go
function moduloOperator (line 10) | func moduloOperator(d *dataTreeNavigator, context Context, expressionNod...
function modulo (line 16) | func modulo(_ *dataTreeNavigator, _ Context, lhs *CandidateNode, rhs *Ca...
function moduloScalars (line 34) | func moduloScalars(target *CandidateNode, lhs *CandidateNode, rhs *Candi...
FILE: pkg/yqlib/operator_modulo_test.go
function TestModuloOperatorScenarios (line 115) | func TestModuloOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_multiply.go
type multiplyPreferences (line 10) | type multiplyPreferences struct
function createMultiplyOp (line 17) | func createMultiplyOp(prefs interface{}) func(lhs *ExpressionNode, rhs *...
function multiplyAssignOperator (line 25) | func multiplyAssignOperator(d *dataTreeNavigator, context Context, expre...
function multiplyOperator (line 31) | func multiplyOperator(d *dataTreeNavigator, context Context, expressionN...
function getComments (line 36) | func getComments(lhs *CandidateNode, rhs *CandidateNode) (leadingContent...
function multiply (line 52) | func multiply(preferences multiplyPreferences) func(d *dataTreeNavigator...
function multiplyScalars (line 80) | func multiplyScalars(lhs *CandidateNode, rhs *CandidateNode) (*Candidate...
function multiplyFloats (line 100) | func multiplyFloats(lhs *CandidateNode, rhs *CandidateNode, lhsIsCustom ...
function multiplyIntegers (line 122) | func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*Candidat...
function repeatString (line 140) | func repeatString(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNod...
function mergeObjects (line 166) | func mergeObjects(d *dataTreeNavigator, context Context, lhs *CandidateN...
function applyAssignment (line 204) | func applyAssignment(d *dataTreeNavigator, context Context, pathIndexToS...
FILE: pkg/yqlib/operator_multiply_test.go
function TestMultiplyOperatorScenarios (line 698) | func TestMultiplyOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_omit.go
function omitMap (line 8) | func omitMap(original *CandidateNode, indices *CandidateNode) *Candidate...
function omitSequence (line 24) | func omitSequence(original *CandidateNode, indices *CandidateNode) *Cand...
function omitOperator (line 38) | func omitOperator(d *dataTreeNavigator, context Context, expressionNode ...
FILE: pkg/yqlib/operator_omit_test.go
function TestOmitOperatorScenarios (line 65) | func TestOmitOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_parent.go
type parentOpPreferences (line 5) | type parentOpPreferences struct
function getParentsOperator (line 9) | func getParentsOperator(_ *dataTreeNavigator, context Context, _ *Expres...
function getParentOperator (line 29) | func getParentOperator(_ *dataTreeNavigator, context Context, expression...
FILE: pkg/yqlib/operator_parent_test.go
function TestParentOperatorScenarios (line 127) | func TestParentOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_path.go
function createPathNodeFor (line 8) | func createPathNodeFor(pathElement interface{}) *CandidateNode {
function getPathArrayFromNode (line 17) | func getPathArrayFromNode(funcName string, node *CandidateNode) ([]inter...
function setPathOperator (line 43) | func setPathOperator(d *dataTreeNavigator, context Context, expressionNo...
function delPathsOperator (line 101) | func delPathsOperator(d *dataTreeNavigator, context Context, expressionN...
function getPathOperator (line 151) | func getPathOperator(_ *dataTreeNavigator, context Context, _ *Expressio...
FILE: pkg/yqlib/operator_path_test.go
function TestPathOperatorsScenarios (line 160) | func TestPathOperatorsScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_pick.go
function pickMap (line 8) | func pickMap(original *CandidateNode, indices *CandidateNode) *Candidate...
function pickSequence (line 28) | func pickSequence(original *CandidateNode, indices *CandidateNode) (*Can...
function pickOperator (line 48) | func pickOperator(d *dataTreeNavigator, context Context, expressionNode ...
FILE: pkg/yqlib/operator_pick_test.go
function TestPickOperatorScenarios (line 74) | func TestPickOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_pipe.go
function pipeOperator (line 3) | func pipeOperator(d *dataTreeNavigator, context Context, expressionNode ...
FILE: pkg/yqlib/operator_pipe_test.go
function TestPipeOperatorScenarios (line 34) | func TestPipeOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_pivot.go
function getUniqueElementTag (line 8) | func getUniqueElementTag(seq *CandidateNode) (string, error) {
function pad (line 26) | func pad[E any](array []E, length int, factory func() E) []E {
function pivotSequences (line 38) | func pivotSequences(seq *CandidateNode) *CandidateNode {
function pivotMaps (line 65) | func pivotMaps(seq *CandidateNode) *CandidateNode {
function pivotOperator (line 96) | func pivotOperator(_ *dataTreeNavigator, context Context, _ *ExpressionN...
FILE: pkg/yqlib/operator_pivot_test.go
function TestPivotOperatorScenarios (line 52) | func TestPivotOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_recursive_descent.go
type recursiveDescentPreferences (line 7) | type recursiveDescentPreferences struct
function recursiveDescentOperator (line 12) | func recursiveDescentOperator(_ *dataTreeNavigator, context Context, exp...
function recursiveDecent (line 24) | func recursiveDecent(results *list.List, context Context, preferences re...
FILE: pkg/yqlib/operator_recursive_descent_test.go
function TestRecursiveDescentOperatorScenarios (line 232) | func TestRecursiveDescentOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_reduce.go
function reduceOperator (line 8) | func reduceOperator(d *dataTreeNavigator, context Context, expressionNod...
FILE: pkg/yqlib/operator_reduce_test.go
function TestReduceOperatorScenarios (line 35) | func TestReduceOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_reverse.go
function reverseOperator (line 8) | func reverseOperator(_ *dataTreeNavigator, context Context, _ *Expressio...
FILE: pkg/yqlib/operator_reverse_test.go
function TestReverseOperatorScenarios (line 68) | func TestReverseOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_select.go
function selectOperator (line 7) | func selectOperator(d *dataTreeNavigator, context Context, expressionNod...
FILE: pkg/yqlib/operator_select_test.go
function TestSelectOperatorScenarios (line 163) | func TestSelectOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_self.go
function selfOperator (line 3) | func selfOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNo...
FILE: pkg/yqlib/operator_shuffle.go
function shuffleOperator (line 9) | func shuffleOperator(_ *dataTreeNavigator, context Context, _ *Expressio...
FILE: pkg/yqlib/operator_shuffle_test.go
function TestShuffleByOperatorScenarios (line 36) | func TestShuffleByOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_slice.go
function getSliceNumber (line 8) | func getSliceNumber(d *dataTreeNavigator, context Context, node *Candida...
function sliceArrayOperator (line 19) | func sliceArrayOperator(d *dataTreeNavigator, context Context, expressio...
FILE: pkg/yqlib/operator_slice_test.go
function TestSliceOperatorScenarios (line 103) | func TestSliceOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_sort.go
function sortOperator (line 12) | func sortOperator(d *dataTreeNavigator, context Context, expressionNode ...
function sortByOperator (line 20) | func sortByOperator(d *dataTreeNavigator, context Context, expressionNod...
type sortableNode (line 67) | type sortableNode struct
type sortableNodeArray (line 73) | type sortableNodeArray
method Len (line 75) | func (a sortableNodeArray) Len() int { return len(a) }
method Swap (line 76) | func (a sortableNodeArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
method Less (line 78) | func (a sortableNodeArray) Less(i, j int) bool {
method compare (line 101) | func (a sortableNodeArray) compare(lhs *CandidateNode, rhs *CandidateN...
FILE: pkg/yqlib/operator_sort_keys.go
function sortKeysOperator (line 7) | func sortKeysOperator(d *dataTreeNavigator, context Context, expressionN...
function sortKeys (line 30) | func sortKeys(node *CandidateNode) {
FILE: pkg/yqlib/operator_sort_keys_test.go
function TestSortKeysOperatorScenarios (line 45) | func TestSortKeysOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_sort_test.go
function TestSortByOperatorScenarios (line 176) | func TestSortByOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_split_document.go
function splitDocumentOperator (line 3) | func splitDocumentOperator(_ *dataTreeNavigator, context Context, _ *Exp...
FILE: pkg/yqlib/operator_split_document_test.go
function TestSplitDocOperatorScenarios (line 37) | func TestSplitDocOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_strings.go
type changeCasePrefs (line 12) | type changeCasePrefs struct
function encodeToYamlString (line 16) | func encodeToYamlString(node *CandidateNode) (string, error) {
function evaluate (line 29) | func evaluate(d *dataTreeNavigator, context Context, expStr string) (str...
function interpolate (line 48) | func interpolate(d *dataTreeNavigator, context Context, str string) (str...
function stringInterpolationOperator (line 111) | func stringInterpolationOperator(d *dataTreeNavigator, context Context, ...
function trimSpaceOperator (line 141) | func trimSpaceOperator(_ *dataTreeNavigator, context Context, _ *Express...
function toStringOperator (line 159) | func toStringOperator(_ *dataTreeNavigator, context Context, _ *Expressi...
function changeCaseOperator (line 184) | func changeCaseOperator(_ *dataTreeNavigator, context Context, expressio...
function getSubstituteParameters (line 211) | func getSubstituteParameters(d *dataTreeNavigator, block *ExpressionNode...
function substitute (line 236) | func substitute(original string, regex *regexp.Regexp, replacement strin...
function substituteStringOperator (line 241) | func substituteStringOperator(d *dataTreeNavigator, context Context, exp...
function addMatch (line 274) | func addMatch(original []*CandidateNode, match string, offset int, name ...
type matchPreferences (line 305) | type matchPreferences struct
function getMatches (line 309) | func getMatches(matchPrefs matchPreferences, regEx *regexp.Regexp, value...
function match (line 325) | func match(matchPrefs matchPreferences, regEx *regexp.Regexp, candidate ...
function capture (line 353) | func capture(matchPrefs matchPreferences, regEx *regexp.Regexp, candidat...
function extractMatchArguments (line 388) | func extractMatchArguments(d *dataTreeNavigator, context Context, expres...
function matchOperator (line 431) | func matchOperator(d *dataTreeNavigator, context Context, expressionNode...
function captureOperator (line 451) | func captureOperator(d *dataTreeNavigator, context Context, expressionNo...
function testOperator (line 471) | func testOperator(d *dataTreeNavigator, context Context, expressionNode ...
function joinStringOperator (line 492) | func joinStringOperator(d *dataTreeNavigator, context Context, expressio...
function join (line 518) | func join(content []*CandidateNode, joinStr string) (Kind, string, strin...
function splitStringOperator (line 531) | func splitStringOperator(d *dataTreeNavigator, context Context, expressi...
function split (line 563) | func split(value string, spltStr string) (Kind, string, []*CandidateNode) {
FILE: pkg/yqlib/operator_strings_test.go
function TestStringsOperatorScenarios (line 369) | func TestStringsOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_style.go
function parseStyle (line 8) | func parseStyle(customStyle string) (Style, error) {
function assignStyleOperator (line 27) | func assignStyleOperator(d *dataTreeNavigator, context Context, expressi...
function getStyleOperator (line 74) | func getStyleOperator(_ *dataTreeNavigator, context Context, _ *Expressi...
FILE: pkg/yqlib/operator_style_test.go
function TestStyleOperatorScenarios (line 172) | func TestStyleOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_subtract.go
function createSubtractOp (line 10) | func createSubtractOp(lhs *ExpressionNode, rhs *ExpressionNode) *Express...
function subtractAssignOperator (line 16) | func subtractAssignOperator(d *dataTreeNavigator, context Context, expre...
function subtractOperator (line 20) | func subtractOperator(d *dataTreeNavigator, context Context, expressionN...
function subtractArray (line 26) | func subtractArray(lhs *CandidateNode, rhs *CandidateNode) []*CandidateN...
function subtract (line 43) | func subtract(_ *dataTreeNavigator, context Context, lhs *CandidateNode,...
function subtractScalars (line 72) | func subtractScalars(context Context, target *CandidateNode, lhs *Candid...
function subtractDateTime (line 133) | func subtractDateTime(layout string, target *CandidateNode, lhs *Candida...
FILE: pkg/yqlib/operator_subtract_test.go
function TestSubtractOperatorScenarios (line 162) | func TestSubtractOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_tag.go
function assignTagOperator (line 7) | func assignTagOperator(d *dataTreeNavigator, context Context, expression...
function getTagOperator (line 48) | func getTagOperator(_ *dataTreeNavigator, context Context, _ *Expression...
FILE: pkg/yqlib/operator_tag_test.go
function TestTagOperatorScenarios (line 95) | func TestTagOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_to_number.go
function tryConvertToNumber (line 9) | func tryConvertToNumber(value string) (string, bool) {
function toNumberOperator (line 25) | func toNumberOperator(_ *dataTreeNavigator, context Context, _ *Expressi...
FILE: pkg/yqlib/operator_to_number_test.go
function TestToNumberOperatorScenarios (line 46) | func TestToNumberOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_traverse_path.go
type traversePreferences (line 11) | type traversePreferences struct
function splat (line 20) | func splat(context Context, prefs traversePreferences) (Context, error) {
function traversePathOperator (line 24) | func traversePathOperator(_ *dataTreeNavigator, context Context, express...
function traverse (line 39) | func traverse(context Context, matchingNode *CandidateNode, operation *O...
function traverseArrayOperator (line 74) | func traverseArrayOperator(d *dataTreeNavigator, context Context, expres...
function traverseNodesWithArrayIndices (line 114) | func traverseNodesWithArrayIndices(context Context, indicesToTraverse []...
function traverseArrayIndices (line 128) | func traverseArrayIndices(context Context, matchingNode *CandidateNode, ...
function traverseMapWithIndices (line 153) | func traverseMapWithIndices(context Context, candidate *CandidateNode, i...
function traverseArrayWithIndices (line 172) | func traverseArrayWithIndices(node *CandidateNode, indices []*CandidateN...
function keyMatches (line 220) | func keyMatches(key *CandidateNode, wantedKey string, exactKeyMatch bool...
function traverseMap (line 228) | func traverseMap(context Context, matchingNode *CandidateNode, keyNode *...
function doTraverseMap (line 267) | func doTraverseMap(newMatches *orderedmap.OrderedMap, node *CandidateNod...
function traverseMergeAnchor (line 333) | func traverseMergeAnchor(newMatches *orderedmap.OrderedMap, merge *Candi...
function traverseArray (line 368) | func traverseArray(candidate *CandidateNode, operation *Operation, prefs...
FILE: pkg/yqlib/operator_traverse_path_test.go
function TestTraversePathOperatorScenarios (line 670) | func TestTraversePathOperatorScenarios(t *testing.T) {
function TestTraversePathOperatorAlignedToSpecScenarios (line 677) | func TestTraversePathOperatorAlignedToSpecScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_union.go
function unionOperator (line 5) | func unionOperator(d *dataTreeNavigator, context Context, expressionNode...
FILE: pkg/yqlib/operator_union_test.go
function TestUnionOperatorScenarios (line 51) | func TestUnionOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_unique.go
function unique (line 10) | func unique(d *dataTreeNavigator, context Context, _ *ExpressionNode) (C...
function uniqueBy (line 17) | func uniqueBy(d *dataTreeNavigator, context Context, expressionNode *Exp...
function getUniqueKeyValue (line 60) | func getUniqueKeyValue(rhs Context) (string, error) {
FILE: pkg/yqlib/operator_unique_test.go
function TestUniqueOperatorScenarios (line 106) | func TestUniqueOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_value.go
function referenceOperator (line 5) | func referenceOperator(_ *dataTreeNavigator, context Context, expression...
function valueOperator (line 9) | func valueOperator(_ *dataTreeNavigator, context Context, expressionNode...
FILE: pkg/yqlib/operator_value_test.go
function TestValueOperatorScenarios (line 187) | func TestValueOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_variables.go
function getVariableOperator (line 8) | func getVariableOperator(_ *dataTreeNavigator, context Context, expressi...
type assignVarPreferences (line 18) | type assignVarPreferences struct
function useWithPipe (line 22) | func useWithPipe(_ *dataTreeNavigator, _ Context, _ *ExpressionNode) (Co...
function variableLoop (line 28) | func variableLoop(d *dataTreeNavigator, context Context, originalExp *Ex...
function variableLoopSingleChild (line 52) | func variableLoopSingleChild(d *dataTreeNavigator, context Context, orig...
FILE: pkg/yqlib/operator_variables_test.go
function TestVariableOperatorScenarios (line 93) | func TestVariableOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operator_with.go
function withOperator (line 5) | func withOperator(d *dataTreeNavigator, context Context, expressionNode ...
FILE: pkg/yqlib/operator_with_test.go
function TestWithOperatorScenarios (line 52) | func TestWithOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operators.go
type operatorHandler (line 11) | type operatorHandler
type compoundCalculation (line 13) | type compoundCalculation
function compoundAssignFunction (line 15) | func compoundAssignFunction(d *dataTreeNavigator, context Context, expre...
function emptyOperator (line 54) | func emptyOperator(_ *dataTreeNavigator, context Context, _ *ExpressionN...
type crossFunctionCalculation (line 59) | type crossFunctionCalculation
function resultsForRHS (line 61) | func resultsForRHS(d *dataTreeNavigator, context Context, lhsCandidate *...
type crossFunctionPreferences (line 105) | type crossFunctionPreferences struct
function doCrossFunc (line 113) | func doCrossFunc(d *dataTreeNavigator, context Context, expressionNode *...
function crossFunction (line 140) | func crossFunction(d *dataTreeNavigator, context Context, expressionNode...
function crossFunctionWithPrefs (line 145) | func crossFunctionWithPrefs(d *dataTreeNavigator, context Context, expre...
function createBooleanCandidate (line 174) | func createBooleanCandidate(owner *CandidateNode, value bool) *Candidate...
function createTraversalTree (line 188) | func createTraversalTree(path []interface{}, traversePrefs traversePrefe...
FILE: pkg/yqlib/operators_compare_test.go
function TestCompareOperatorScenarios (line 380) | func TestCompareOperatorScenarios(t *testing.T) {
function TestMinOperatorScenarios (line 412) | func TestMinOperatorScenarios(t *testing.T) {
function TestMaxOperatorScenarios (line 444) | func TestMaxOperatorScenarios(t *testing.T) {
FILE: pkg/yqlib/operators_test.go
type expressionScenario (line 20) | type expressionScenario struct
function TestMain (line 40) | func TestMain(m *testing.M) {
function NewSimpleYamlPrinter (line 61) | func NewSimpleYamlPrinter(writer io.Writer, unwrapScalar bool, indent in...
function readDocument (line 69) | func readDocument(content string, fakefilename string, fakeFileIndex int...
function testScenario (line 75) | func testScenario(t *testing.T, s *expressionScenario) {
function resultToString (line 155) | func resultToString(t *testing.T, n *CandidateNode) string {
function resultsToString (line 173) | func resultsToString(t *testing.T, results *list.List) []string {
function writeOrPanic (line 185) | func writeOrPanic(w *bufio.Writer, text string) {
function copySnippet (line 192) | func copySnippet(source string, out *os.File) error {
function formatYaml (line 206) | func formatYaml(yaml string, filename string) string {
type documentScenarioFunc (line 222) | type documentScenarioFunc
function documentScenarios (line 224) | func documentScenarios(t *testing.T, folder string, title string, scenar...
function appendOperatorDocumentScenario (line 256) | func appendOperatorDocumentScenario(t *testing.T, title string, scenario...
function documentOperatorScenarios (line 272) | func documentOperatorScenarios(t *testing.T, title string, scenarios []e...
function documentOperatorScenario (line 281) | func documentOperatorScenario(t *testing.T, w *bufio.Writer, i interface...
function documentInput (line 309) | func documentInput(w *bufio.Writer, s expressionScenario) (string, strin...
function documentOutput (line 371) | func documentOutput(t *testing.T, w *bufio.Writer, s expressionScenario,...
FILE: pkg/yqlib/printer.go
type Printer (line 12) | type Printer interface
type resultsPrinter (line 20) | type resultsPrinter struct
method SetNulSepOutput (line 42) | func (p *resultsPrinter) SetNulSepOutput(nulSepOutput bool) {
method SetAppendix (line 48) | func (p *resultsPrinter) SetAppendix(reader io.Reader) {
method PrintedAnything (line 52) | func (p *resultsPrinter) PrintedAnything() bool {
method printNode (line 56) | func (p *resultsPrinter) printNode(node *CandidateNode, writer io.Writ...
method PrintResults (line 72) | func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
function NewPrinter (line 32) | func NewPrinter(encoder Encoder, printerWriter PrinterWriter) Printer {
function removeLastEOL (line 62) | func removeLastEOL(b *bytes.Buffer) {
FILE: pkg/yqlib/printer_node_info.go
type nodeInfoPrinter (line 11) | type nodeInfoPrinter struct
method SetNulSepOutput (line 23) | func (p *nodeInfoPrinter) SetNulSepOutput(_ bool) {
method SetAppendix (line 26) | func (p *nodeInfoPrinter) SetAppendix(reader io.Reader) {
method PrintedAnything (line 30) | func (p *nodeInfoPrinter) PrintedAnything() bool {
method PrintResults (line 34) | func (p *nodeInfoPrinter) PrintResults(matchingNodes *list.List) error {
function NewNodeInfoPrinter (line 17) | func NewNodeInfoPrinter(printerWriter PrinterWriter) Printer {
FILE: pkg/yqlib/printer_node_info_test.go
function TestNodeInfoPrinter_PrintResults (line 13) | func TestNodeInfoPrinter_PrintResults(t *testing.T) {
function TestNodeInfoPrinter_PrintedAnything_True (line 53) | func TestNodeInfoPrinter_PrintedAnything_True(t *testing.T) {
function TestNodeInfoPrinter_PrintedAnything_False (line 79) | func TestNodeInfoPrinter_PrintedAnything_False(t *testing.T) {
function TestNodeInfoPrinter_SetNulSepOutput (line 96) | func TestNodeInfoPrinter_SetNulSepOutput(_ *testing.T) {
function TestNodeInfoPrinter_SetAppendix (line 106) | func TestNodeInfoPrinter_SetAppendix(t *testing.T) {
function TestNodeInfoPrinter_MultipleNodes (line 134) | func TestNodeInfoPrinter_MultipleNodes(t *testing.T) {
function TestNodeInfoPrinter_SequenceNode (line 164) | func TestNodeInfoPrinter_SequenceNode(t *testing.T) {
function TestNodeInfoPrinter_MappingNode (line 189) | func TestNodeInfoPrinter_MappingNode(t *testing.T) {
function TestNodeInfoPrinter_EmptyList (line 212) | func TestNodeInfoPrinter_EmptyList(t *testing.T) {
FILE: pkg/yqlib/printer_test.go
function nodeToList (line 30) | func nodeToList(candidate *CandidateNode) *list.List {
function TestPrinterMultipleDocsInSequenceOnly (line 36) | func TestPrinterMultipleDocsInSequenceOnly(t *testing.T) {
function TestPrinterMultipleDocsInSequenceWithLeadingContent (line 74) | func TestPrinterMultipleDocsInSequenceWithLeadingContent(t *testing.T) {
function TestPrinterMultipleFilesInSequence (line 116) | func TestPrinterMultipleFilesInSequence(t *testing.T) {
function TestPrinterMultipleFilesInSequenceWithLeadingContent (line 163) | func TestPrinterMultipleFilesInSequenceWithLeadingContent(t *testing.T) {
function TestPrinterMultipleDocsInSinglePrint (line 213) | func TestPrinterMultipleDocsInSinglePrint(t *testing.T) {
function TestPrinterMultipleDocsInSinglePrintWithLeadingDoc (line 232) | func TestPrinterMultipleDocsInSinglePrintWithLeadingDoc(t *testing.T) {
function TestPrinterMultipleDocsInSinglePrintWithLeadingDocTrailing (line 261) | func TestPrinterMultipleDocsInSinglePrintWithLeadingDocTrailing(t *testi...
function TestPrinterScalarWithLeadingCont (line 287) | func TestPrinterScalarWithLeadingCont(t *testing.T) {
function TestPrinterMultipleDocsJson (line 312) | func TestPrinterMultipleDocsJson(t *testing.T) {
function TestPrinterNulSeparator (line 346) | func TestPrinterNulSeparator(t *testing.T) {
function TestPrinterNulSeparatorWithJson (line 366) | func TestPrinterNulSeparatorWithJson(t *testing.T) {
function TestPrinterRootUnwrap (line 398) | func TestPrinterRootUnwrap(t *testing.T) {
function TestRemoveLastEOL (line 418) | func TestRemoveLastEOL(t *testing.T) {
function TestPrinterPrintedAnything (line 450) | func TestPrinterPrintedAnything(t *testing.T) {
function TestPrinterNulSeparatorWithNullChar (line 469) | func TestPrinterNulSeparatorWithNullChar(t *testing.T) {
function TestPrinterSetNulSepOutput (line 490) | func TestPrinterSetNulSepOutput(t *testing.T) {
function TestPrinterSetAppendix (line 504) | func TestPrinterSetAppendix(t *testing.T) {
FILE: pkg/yqlib/printer_writer.go
type PrinterWriter (line 12) | type PrinterWriter interface
type singlePrinterWriter (line 16) | type singlePrinterWriter struct
method GetWriter (line 26) | func (sp *singlePrinterWriter) GetWriter(_ *CandidateNode) (*bufio.Wri...
function NewSinglePrinterWriter (line 20) | func NewSinglePrinterWriter(writer io.Writer) PrinterWriter {
type multiPrintWriter (line 30) | type multiPrintWriter struct
method GetWriter (line 55) | func (sp *multiPrintWriter) GetWriter(node *CandidateNode) (*bufio.Wri...
function NewMultiPrinterWriter (line 37) | func NewMultiPrinterWriter(expression *ExpressionNode, format *Format) P...
FILE: pkg/yqlib/properties.go
type PropertiesPreferences (line 3) | type PropertiesPreferences struct
method Copy (line 17) | func (p *PropertiesPreferences) Copy() PropertiesPreferences {
function NewDefaultPropertiesPreferences (line 9) | func NewDefaultPropertiesPreferences() PropertiesPreferences {
FILE: pkg/yqlib/properties_test.go
constant propertiesWithCommentsOnMap (line 11) | propertiesWithCommentsOnMap = `this.thing = hi hi
constant expectedPropertiesWithCommentsOnMapProps (line 17) | expectedPropertiesWithCommentsOnMapProps = `this.thing = hi hi
constant expectedPropertiesWithCommentsOnMapYaml (line 24) | expectedPropertiesWithCommentsOnMapYaml = `this:
constant propertiesWithCommentInArray (line 31) | propertiesWithCommentInArray = `
constant expectedPropertiesWithCommentInArrayProps (line 38) | expectedPropertiesWithCommentInArrayProps = `this.array.0 = cat
constant expectedPropertiesWithCommentInArrayYaml (line 45) | expectedPropertiesWithCommentInArrayYaml = `this:
constant samplePropertiesYaml (line 53) | samplePropertiesYaml = `# block comments come through
constant expectedPropertiesUnwrapped (line 65) | expectedPropertiesUnwrapped = `# block comments come through
constant expectedPropertiesUnwrappedArrayBrackets (line 75) | expectedPropertiesUnwrappedArrayBrackets = `# block comments come through
constant expectedPropertiesUnwrappedCustomSeparator (line 85) | expectedPropertiesUnwrappedCustomSeparator = `# block comments come through
constant expectedPropertiesWrapped (line 95) | expectedPropertiesWrapped = `# block comments come through
constant expectedUpdatedProperties (line 105) | expectedUpdatedProperties = `# block comments come through
constant expectedDecodedYaml (line 115) | expectedDecodedYaml = `person:
constant expectedDecodedPersonYaml (line 128) | expectedDecodedPersonYaml = `# block comments come through
constant expectedPropertiesNoComments (line 140) | expectedPropertiesNoComments = `person.name = Mike Wazowski
constant expectedPropertiesWithEmptyMapsAndArrays (line 146) | expectedPropertiesWithEmptyMapsAndArrays = `# block comments come through
function documentUnwrappedEncodePropertyScenario (line 305) | func documentUnwrappedEncodePropertyScenario(w *bufio.Writer, s formatSc...
function documentWrappedEncodePropertyScenario (line 342) | func documentWrappedEncodePropertyScenario(w *bufio.Writer, s formatScen...
function documentDecodePropertyScenario (line 368) | func documentDecodePropertyScenario(w *bufio.Writer, s formatScenario) {
function documentRoundTripPropertyScenario (line 393) | func documentRoundTripPropertyScenario(w *bufio.Writer, s formatScenario) {
function documentPropertyScenario (line 418) | func documentPropertyScenario(_ *testing.T, w *bufio.Writer, i interface...
function TestPropertyScenarios (line 438) | func TestPropertyScenarios(t *testing.T) {
FILE: pkg/yqlib/recipes_test.go
function TestRecipes (line 158) | func TestRecipes(t *testing.T) {
FILE: pkg/yqlib/security_prefs.go
type SecurityPreferences (line 3) | type SecurityPreferences struct
FILE: pkg/yqlib/shellvariables.go
type ShellVariablesPreferences (line 3) | type ShellVariablesPreferences struct
function NewDefaultShellVariablesPreferences (line 8) | func NewDefaultShellVariablesPreferences() ShellVariablesPreferences {
FILE: pkg/yqlib/shellvariables_test.go
function TestShellVariableScenarios (line 72) | func TestShellVariableScenarios(t *testing.T) {
function documentShellVariableScenario (line 92) | func documentShellVariableScenario(_ *testing.T, w *bufio.Writer, i inte...
FILE: pkg/yqlib/stream_evaluator.go
type StreamEvaluator (line 14) | type StreamEvaluator interface
type streamEvaluator (line 20) | type streamEvaluator struct
method EvaluateNew (line 29) | func (s *streamEvaluator) EvaluateNew(expression string, printer Print...
method EvaluateFiles (line 45) | func (s *streamEvaluator) EvaluateFiles(expression string, filenames [...
method Evaluate (line 78) | func (s *streamEvaluator) Evaluate(filename string, reader io.Reader, ...
function NewStreamEvaluator (line 25) | func NewStreamEvaluator() StreamEvaluator {
FILE: pkg/yqlib/string_evaluator.go
type StringEvaluator (line 10) | type StringEvaluator interface
type stringEvaluator (line 15) | type stringEvaluator struct
method EvaluateAll (line 25) | func (s *stringEvaluator) EvaluateAll(expression string, input string,...
method Evaluate (line 48) | func (s *stringEvaluator) Evaluate(expression string, input string, en...
function NewStringEvaluator (line 19) | func NewStringEvaluator() StringEvaluator {
FILE: pkg/yqlib/string_evaluator_test.go
function TestStringEvaluator_MultipleDocumentMerge (line 9) | func TestStringEvaluator_MultipleDocumentMerge(t *testing.T) {
function TestStringEvaluator_Evaluate_Nominal (line 23) | func TestStringEvaluator_Evaluate_Nominal(t *testing.T) {
FILE: pkg/yqlib/toml.go
type TomlPreferences (line 3) | type TomlPreferences struct
method Copy (line 11) | func (p *TomlPreferences) Copy() TomlPreferences {
function NewDefaultTomlPreferences (line 7) | func NewDefaultTomlPreferences() TomlPreferences {
FILE: pkg/yqlib/toml_test.go
function testTomlScenario (line 619) | func testTomlScenario(t *testing.T, s formatScenario) {
function documentTomlDecodeScenario (line 635) | func documentTomlDecodeScenario(w *bufio.Writer, s formatScenario) {
function documentTomlRoundtripScenario (line 657) | func documentTomlRoundtripScenario(w *bufio.Writer, s formatScenario) {
function documentTomlScenario (line 679) | func documentTomlScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function TestTomlScenarios (line 696) | func TestTomlScenarios(t *testing.T) {
function TestTomlColourization (line 709) | func TestTomlColourization(t *testing.T) {
function TestTomlColorisationNumberBug (line 771) | func TestTomlColorisationNumberBug(t *testing.T) {
function TestTomlEmptyPathPanic (line 883) | func TestTomlEmptyPathPanic(t *testing.T) {
function TestTomlStringEscapeColourization (line 906) | func TestTomlStringEscapeColourization(t *testing.T) {
function TestTomlEncoderPrintDocumentSeparator (line 970) | func TestTomlEncoderPrintDocumentSeparator(t *testing.T) {
function TestTomlEncoderPrintLeadingContent (line 982) | func TestTomlEncoderPrintLeadingContent(t *testing.T) {
function TestTomlEncoderCanHandleAliases (line 994) | func TestTomlEncoderCanHandleAliases(t *testing.T) {
FILE: pkg/yqlib/utils.go
function readStream (line 12) | func readStream(filename string) (io.Reader, error) {
function writeString (line 29) | func writeString(writer io.Writer, txt string) error {
function ReadDocuments (line 34) | func ReadDocuments(reader io.Reader, decoder Decoder) (*list.List, error) {
function readDocuments (line 38) | func readDocuments(reader io.Reader, filename string, fileIndex int, dec...
FILE: pkg/yqlib/write_in_place_handler.go
type writeInPlaceHandler (line 7) | type writeInPlaceHandler interface
type writeInPlaceHandlerImpl (line 12) | type writeInPlaceHandlerImpl struct
method CreateTempFile (line 22) | func (w *writeInPlaceHandlerImpl) CreateTempFile() (*os.File, error) {
method FinishWriteInPlace (line 46) | func (w *writeInPlaceHandlerImpl) FinishWriteInPlace(evaluatedSuccessf...
function NewWriteInPlaceHandler (line 17) | func NewWriteInPlaceHandler(inputFile string) writeInPlaceHandler {
FILE: pkg/yqlib/write_in_place_handler_test.go
function TestWriteInPlaceHandlerImpl_CreateTempFile (line 9) | func TestWriteInPlaceHandlerImpl_CreateTempFile(t *testing.T) {
function TestWriteInPlaceHandlerImpl_CreateTempFile_NonExistentInput (line 37) | func TestWriteInPlaceHandlerImpl_CreateTempFile_NonExistentInput(t *test...
function TestWriteInPlaceHandlerImpl_FinishWriteInPlace_Success (line 52) | func TestWriteInPlaceHandlerImpl_FinishWriteInPlace_Success(t *testing.T) {
function TestWriteInPlaceHandlerImpl_FinishWriteInPlace_Failure (line 97) | func TestWriteInPlaceHandlerImpl_FinishWriteInPlace_Failure(t *testing.T) {
function TestWriteInPlaceHandlerImpl_FinishWriteInPlace_Symlink_Success (line 142) | func TestWriteInPlaceHandlerImpl_FinishWriteInPlace_Symlink_Success(t *t...
function TestWriteInPlaceHandlerImpl_CreateTempFile_Permissions (line 202) | func TestWriteInPlaceHandlerImpl_CreateTempFile_Permissions(t *testing.T) {
function TestWriteInPlaceHandlerImpl_Integration (line 238) | func TestWriteInPlaceHandlerImpl_Integration(t *testing.T) {
FILE: pkg/yqlib/xml.go
type XmlPreferences (line 3) | type XmlPreferences struct
method Copy (line 31) | func (p *XmlPreferences) Copy() XmlPreferences {
function NewDefaultXmlPreferences (line 16) | func NewDefaultXmlPreferences() XmlPreferences {
FILE: pkg/yqlib/xml_test.go
constant yamlInputWithProcInstAndHeadComment (line 13) | yamlInputWithProcInstAndHeadComment = `# cats
constant expectedXmlProcInstAndHeadComment (line 17) | expectedXmlProcInstAndHeadComment = `<?xml version="1.0"?>
constant xmlProcInstAndHeadCommentBlock (line 22) | xmlProcInstAndHeadCommentBlock = `<?xml version="1.0"?>
constant expectedYamlProcInstAndHeadCommentBlock (line 29) | expectedYamlProcInstAndHeadCommentBlock = `#
constant inputXMLWithComments (line 36) | inputXMLWithComments = `
constant inputXMLWithCommentsWithSubChild (line 54) | inputXMLWithCommentsWithSubChild = `
constant expectedDecodeYamlWithSubChild (line 73) | expectedDecodeYamlWithSubChild = `# before cat
constant inputXMLWithCommentsWithArray (line 93) | inputXMLWithCommentsWithArray = `
constant expectedDecodeYamlWithArray (line 113) | expectedDecodeYamlWithArray = `# before cat
constant expectedDecodeYamlWithComments (line 137) | expectedDecodeYamlWithComments = `# before cat
constant expectedRoundtripXMLWithComments (line 154) | expectedRoundtripXMLWithComments = `<!-- before cat -->
constant yamlWithComments (line 166) | yamlWithComments = `#
constant expectedXMLWithComments (line 179) | expectedXMLWithComments = `<!--
constant inputXMLWithNamespacedAttr (line 190) | inputXMLWithNamespacedAttr = `<?xml version="1.0"?>
constant expectedYAMLWithNamespacedAttr (line 197) | expectedYAMLWithNamespacedAttr = `+p_xml: version="1.0"
constant expectedYAMLWithRawNamespacedAttr (line 208) | expectedYAMLWithRawNamespacedAttr = `+p_xml: version="1.0"
constant expectedYAMLWithoutRawNamespacedAttr (line 219) | expectedYAMLWithoutRawNamespacedAttr = `+p_xml: version="1.0"
constant xmlWithCustomDtd (line 230) | xmlWithCustomDtd = `
constant expectedDtd (line 240) | expectedDtd = `<?xml version="1.0"?>
constant expectedSkippedDtd (line 250) | expectedSkippedDtd = `<?xml version="1.0"?>
constant xmlWithProcInstAndDirectives (line 256) | xmlWithProcInstAndDirectives = `<?xml version="1.0"?>
constant yamlWithProcInstAndDirectives (line 265) | yamlWithProcInstAndDirectives = `+p_xml: version="1.0"
constant expectedXmlWithProcInstAndDirectives (line 273) | expectedXmlWithProcInstAndDirectives = `<?xml version="1.0"?>
function testXMLScenario (line 632) | func testXMLScenario(t *testing.T, s formatScenario) {
function documentXMLScenario (line 678) | func documentXMLScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
function documentXMLDecodeScenario (line 703) | func documentXMLDecodeScenario(w *bufio.Writer, s formatScenario) {
function documentXMLDecodeKeepNsScenario (line 725) | func documentXMLDecodeKeepNsScenario(w *bufio.Writer, s formatScenario) {
function documentXMLDecodeKeepNsRawTokenScenario (line 749) | func documentXMLDecodeKeepNsRawTokenScenario(w *bufio.Writer, s formatSc...
function documentXMLEncodeScenario (line 776) | func documentXMLEncodeScenario(w *bufio.Writer, s formatScenario) {
function documentXMLRoundTripScenario (line 794) | func documentXMLRoundTripScenario(w *bufio.Writer, s formatScenario) {
function documentXMLSkipDirectivesScenario (line 812) | func documentXMLSkipDirectivesScenario(w *bufio.Writer, s formatScenario) {
function TestXMLScenarios (line 832) | func TestXMLScenarios(t *testing.T) {
FILE: pkg/yqlib/yaml.go
type YamlPreferences (line 3) | type YamlPreferences struct
method Copy (line 27) | func (p *YamlPreferences) Copy() YamlPreferences {
function NewDefaultYamlPreferences (line 14) | func NewDefaultYamlPreferences() YamlPreferences {
FILE: pkg/yqlib/yaml_test.go
function testYamlScenario (line 146) | func testYamlScenario(t *testing.T, s formatScenario) {
function TestYamlParseScenarios (line 150) | func TestYamlParseScenarios(t *testing.T) {
function TestYamlFormatScenarios (line 156) | func TestYamlFormatScenarios(t *testing.T) {
FILE: test/format_test.go
function TestFormatStringFromFilename (line 10) | func TestFormatStringFromFilename(t *testing.T) {
FILE: test/utils.go
function printDifference (line 14) | func printDifference(t *testing.T, expectedValue interface{}, actualValu...
function AssertResult (line 26) | func AssertResult(t *testing.T, expectedValue interface{}, actualValue i...
function AssertResultComplex (line 33) | func AssertResultComplex(t *testing.T, expectedValue interface{}, actual...
function AssertResultComplexWithContext (line 40) | func AssertResultComplexWithContext(t *testing.T, expectedValue interfac...
function AssertResultWithContext (line 48) | func AssertResultWithContext(t *testing.T, expectedValue interface{}, ac...
FILE: yq.go
function main (line 9) | func main() {
FILE: yq_test.go
function TestMainFunction (line 9) | func TestMainFunction(t *testing.T) {
function TestMainFunctionLogic (line 24) | func TestMainFunctionLogic(t *testing.T) {
function TestMainFunctionWithArgs (line 59) | func TestMainFunctionWithArgs(t *testing.T) {
function TestMainFunctionExecution (line 92) | func TestMainFunctionExecution(t *testing.T) {
function TestMainFunctionErrorHandling (line 109) | func TestMainFunctionErrorHandling(t *testing.T) {
function TestMainFunctionWithCompletionCommand (line 144) | func TestMainFunctionWithCompletionCommand(t *testing.T) {
function TestMainFunctionWithCompletionNoDescCommand (line 166) | func TestMainFunctionWithCompletionNoDescCommand(t *testing.T) {
function TestMainFunctionIntegration (line 188) | func TestMainFunctionIntegration(t *testing.T) {
Condensed preview — 536 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,790K chars).
[
{
"path": ".dockerignore",
"chars": 6,
"preview": "bin/*\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 18,
"preview": "github: mikefarah\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report_v4.md",
"chars": 928,
"preview": "---\nname: Bug report - V4\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug, v4\nassignees: ''\n\n---\n\n**Desc"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 889,
"preview": "---\nname: Feature request - V4\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement, v4\nassignees: ''\n\n"
},
{
"path": ".github/dependabot.yml",
"chars": 662,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/instructions/instructions.md",
"chars": 115,
"preview": "When you find a bug - make sure to include a new test that exposes the bug, as well as the fix for the bug itself.\n"
},
{
"path": ".github/workflows/codeql.yml",
"chars": 2415,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/docker-release.yml",
"chars": 4102,
"preview": "name: Release Docker\n\non:\n release:\n types: [released]\n\n # Allows you to run this workflow manually from the Action"
},
{
"path": ".github/workflows/go.yml",
"chars": 730,
"preview": "name: Build\non: [push, pull_request]\npermissions:\n contents: read\n\njobs:\n\n build:\n name: Build\n runs-on: ubuntu-"
},
{
"path": ".github/workflows/release.yml",
"chars": 1331,
"preview": "name: Release YQ\non:\n push:\n tags:\n - 'v4.*'\n - 'draft-*'\n\njobs:\n publishGitRelease:\n runs-on: ubuntu-"
},
{
"path": ".github/workflows/snap-release.yml",
"chars": 725,
"preview": "name: Release Snap\n\non:\n release:\n types: [released]\n\n # Allows you to run this workflow manually from the Actions "
},
{
"path": ".gitignore",
"chars": 672,
"preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\nbin\nbuild\nbuild-don"
},
{
"path": ".golangci.bck.yml",
"chars": 687,
"preview": "run:\n timeout: 5m\nlinters:\n enable:\n - asciicheck\n - depguard\n - errorlint\n - gci\n - gochecknoinits\n "
},
{
"path": ".golangci.yml",
"chars": 1056,
"preview": "version: \"2\"\nlinters:\n enable:\n - asciicheck\n - depguard\n - errorlint\n - gochecknoinits\n - gosec\n - m"
},
{
"path": ".goreleaser.yaml",
"chars": 767,
"preview": "version: 2\n\ndist: build\n\nbuilds:\n - id: yq\n\n binary: yq_{{ .Os }}_{{ .Arch }}\n\n ldflags:\n - -s -w\n\n env:\n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3357,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 8004,
"preview": "# Before you begin \nNot all new PRs will be merged in \n\nIt's recommended to check with the owner first (e.g. raise an is"
},
{
"path": "Dockerfile",
"chars": 709,
"preview": "FROM golang:1.26.1 AS builder\r\n\r\nWORKDIR /go/src/mikefarah/yq\r\n\r\nCOPY . .\r\n\r\nRUN CGO_ENABLED=0 go build -ldflags \"-s -w\""
},
{
"path": "Dockerfile.dev",
"chars": 259,
"preview": "FROM golang:1.26.1\n\nRUN apt-get update && \\\n apt-get install -y npm && \\\n npm install -g npx cspell@latest\n\nCOPY s"
},
{
"path": "LICENSE",
"chars": 1077,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2017 Mike Farah\n\nPermission is hereby granted, free of charge, to any person obtain"
},
{
"path": "Makefile",
"chars": 3250,
"preview": "MAKEFLAGS += --warn-undefined-variables\nSHELL := /bin/bash\n.SHELLFLAGS := -o pipefail -euc\n.DEFAULT_GOAL := install\nENGI"
},
{
"path": "Makefile.variables",
"chars": 1270,
"preview": "export PROJECT = yq\nIMPORT_PATH := github.com/mikefarah/${PROJECT}\n\nexport GIT_COMMIT = $(shell git rev-parse --short HE"
},
{
"path": "README.md",
"chars": 18343,
"preview": "# yq\n\n  {\n result=$(./yq e -i -n '.a' 2>&1)\n assertEquals 1 $?\n assertEquals \"Error: wr"
},
{
"path": "acceptance_tests/basic.sh",
"chars": 7498,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml 2>/dev/null || true\n rm .xyz 2>/dev/null || true\n rm instructions.txt 2>/dev/nul"
},
{
"path": "acceptance_tests/completion.sh",
"chars": 188,
"preview": "#!/bin/bash\n\ntestCompletionRuns() {\n result=$(./yq __complete \"\" 2>&1)\n assertEquals 0 $?\n assertContains \"$res"
},
{
"path": "acceptance_tests/empty.sh",
"chars": 1355,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n cat >test.yml <<EOL\n# comment\nEOL\n}\n\ntestEmptyEval() {\n X=$(./yq e test"
},
{
"path": "acceptance_tests/flags.sh",
"chars": 338,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n cat >test.yml <<EOL\n# comment\nEOL\n}\n\ntestStringInterpolation() {\n X=$"
},
{
"path": "acceptance_tests/front-matter.sh",
"chars": 1079,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n cat >test.yml <<EOL\n---\na: apple\nb: cat\n---\nnot yaml\nc: at\nEOL\n}\n\ntestFr"
},
{
"path": "acceptance_tests/header-processing-off.sh",
"chars": 600,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n \n}\n\ntestLineCountFirstLineComment() {\n cat >test.yml <<EOL\n#test123 \nab"
},
{
"path": "acceptance_tests/inputs-format-auto.sh",
"chars": 4330,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml 2>/dev/null || true\n rm test*.toml 2>/dev/null || true\n rm test*.tfstate 2>/dev/"
},
{
"path": "acceptance_tests/inputs-format.sh",
"chars": 6093,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml 2>/dev/null || true\n rm test*.properties 2>/dev/null || true\n rm test*.csv 2>/de"
},
{
"path": "acceptance_tests/leading-separator.sh",
"chars": 6707,
"preview": "#!/bin/bash\n\n\n# examples where header-preprocess is required\n\nsetUp() {\n rm test*.yml || true\n cat >test.yml <<EOL\n---"
},
{
"path": "acceptance_tests/load-file.sh",
"chars": 743,
"preview": "#!/bin/bash\n\ntestLoadFileNotExist() {\n result=$(./yq e -n 'load(\"cat.yml\")' 2>&1)\n assertEquals 1 $?\n assertEquals \"E"
},
{
"path": "acceptance_tests/nul-separator.sh",
"chars": 8481,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n}\n\n## Convenient bash shortcut to read records of NUL separated values\n#"
},
{
"path": "acceptance_tests/output-format.sh",
"chars": 5819,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n}\n\ntestOutputJsonDeprecated() {\n cat >test.yml <<EOL\na: {b: [\"cat\"]}\nEOL\n"
},
{
"path": "acceptance_tests/pipe.sh",
"chars": 1227,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n cat >test.yml <<EOL\na: frog\nEOL\n}\n\ntestPipeViaCatWithParam() {\n X=$(cat"
},
{
"path": "acceptance_tests/pretty-print.sh",
"chars": 2859,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n}\n\ntestPrettyPrintWithBooleans() {\n cat >test.yml <<EOL\nleaveUnquoted: [y"
},
{
"path": "acceptance_tests/shebang.sh",
"chars": 316,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yq || true\n cat >test.yq <<EOL\n#!./yq\n.a.b\nEOL\nchmod +x test.yq\n\nrm test*.yml || true"
},
{
"path": "acceptance_tests/split-printer.sh",
"chars": 3636,
"preview": "#!/bin/bash\n\nsetUp() {\n rm test*.yml || true\n rm -rf test_dir* || true\n}\n\ntestBasicSplitWithName() {\n cat >test.yml <"
},
{
"path": "action.yml",
"chars": 442,
"preview": "name: 'yq - portable yaml processor'\ndescription: 'create, read, update, delete, merge, validate and do more with yaml'\n"
},
{
"path": "agents.md",
"chars": 16467,
"preview": "# General rules\n✅ **DO:**\n- You can use ./yq with the `--debug-node-info` flag to get a deeper understanding of the ast."
},
{
"path": "cmd/completion.go",
"chars": 1598,
"preview": "package cmd\n\nimport (\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar completionCmd = &cobra.Command{\n\tUse: \"completion [bas"
},
{
"path": "cmd/constant.go",
"chars": 661,
"preview": "package cmd\n\nvar unwrapScalarFlag = newUnwrapFlag()\n\nvar printNodeInfo = false\n\nvar unwrapScalar = false\n\nvar writeInpla"
},
{
"path": "cmd/evaluate_all_command.go",
"chars": 3724,
"preview": "package cmd\n\nimport (\n\t\"errors\"\n\n\t\"github.com/mikefarah/yq/v4/pkg/yqlib\"\n\t\"github.com/spf13/cobra\"\n)\n\nfunc createEvaluat"
},
{
"path": "cmd/evaluate_all_command_test.go",
"chars": 8553,
"preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestCreateEvaluateAllCommand(t *test"
},
{
"path": "cmd/evaluate_sequence_command.go",
"chars": 3961,
"preview": "package cmd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/mikefarah/yq/v4/pkg/yqlib\"\n\t\"github.com/spf13/cobra\"\n)\n\nfunc create"
},
{
"path": "cmd/evaluate_sequence_command_test.go",
"chars": 7429,
"preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestCreateEvaluateSequenceCommand(t "
},
{
"path": "cmd/root.go",
"chars": 13430,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/mikefarah/yq/v4/pkg/yqlib\"\n\t\"github.com/spf13/cobra\"\n\tloggin"
},
{
"path": "cmd/root_test.go",
"chars": 5342,
"preview": "package cmd\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestNewRuneVar(t *testing.T) {\n\tvar r rune\n\truneVar := newRuneVar(&r"
},
{
"path": "cmd/unwrap_flag.go",
"chars": 743,
"preview": "package cmd\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/spf13/pflag\"\n)\n\ntype boolFlag interface {\n\tpflag.Value\n\tIsExplicitlySet()"
},
{
"path": "cmd/utils.go",
"chars": 8617,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/mikefarah/yq/v4/pkg/yqlib\"\n\t\"github.com/spf13/cobra\"\n\t"
},
{
"path": "cmd/utils_test.go",
"chars": 36037,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/pkg/yqlib\"\n\t\"github.com/spf13/cob"
},
{
"path": "cmd/version.go",
"chars": 1247,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// The git commit that was compiled. This will be filled in by the compiler.\n"
},
{
"path": "cmd/version_test.go",
"chars": 4130,
"preview": "package cmd\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestGetVersionDisplay(t *testing.T) {\n\tvar expectedVersion = Product"
},
{
"path": "cspell.config.yaml",
"chars": 319,
"preview": "---\n$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json\nversion: '0.2'\nlanguage"
},
{
"path": "examples/array.yaml",
"chars": 55,
"preview": "- [cat, dog, frog, cow]\n- [apple, banana, grape, mango]"
},
{
"path": "examples/bad.yaml",
"chars": 82,
"preview": "b:\n d: be gone\n c: 2\n e:\n - name: Billy Bob # comment over here\n\n---\n[123123"
},
{
"path": "examples/base64.txt",
"chars": 40,
"preview": "bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u"
},
{
"path": "examples/data.lua",
"chars": 125,
"preview": "return {\n\t[\"country\"] = \"Australia\"; -- this place\n\t[\"cities\"] = {\n\t\t\"Sydney\",\n\t\t\"Melbourne\",\n\t\t\"Brisbane\",\n\t\t\"Perth\",\n\t"
},
{
"path": "examples/data1-no-comments.yaml",
"chars": 33,
"preview": "a: simple\nb: [1, 2]\nc:\n test: 1\n"
},
{
"path": "examples/data1.yaml",
"chars": 8,
"preview": "a: apple"
},
{
"path": "examples/data2.yaml",
"chars": 152,
"preview": "# --------------------------------------------------\n# It's a test with comment\n# --------------------------------------"
},
{
"path": "examples/data3.yaml",
"chars": 50,
"preview": "a: \"simple\" # just the best\nb: [1, 3]\nc:\n test: 1"
},
{
"path": "examples/empty-no-comment.yaml",
"chars": 0,
"preview": ""
},
{
"path": "examples/empty.yaml",
"chars": 10,
"preview": "# comment\n"
},
{
"path": "examples/environment.yq",
"chars": 153,
"preview": "#! yq\n.[] |(\n ( select(kind == \"scalar\") | key + \"='\" + . + \"'\"),\n ( select(kind == \"seq\") | key + \"=(\" + (map(\"'\""
},
{
"path": "examples/example.properties",
"chars": 123,
"preview": "# comments on values appear\nperson.name = Mike\n\n# comments on array values appear\nperson.pets.0 = cat\nperson.food.0 = pi"
},
{
"path": "examples/front-matter.yaml",
"chars": 52,
"preview": "---\na: apple\nb: banana\n---\nhello there\napples: great"
},
{
"path": "examples/instruction_sample.yaml",
"chars": 105,
"preview": "- command: update \n path: b.c\n value:\n #great \n things: frog # wow!\n- command: delete\n path: b.d"
},
{
"path": "examples/kyaml.yml",
"chars": 67,
"preview": "# leading\na: 1 # a line\n# head b\nb: 2\nc:\n # head d\n - d # d line\n"
},
{
"path": "examples/leading-separator.yaml",
"chars": 11,
"preview": "---\na: test"
},
{
"path": "examples/merge-anchor.yaml",
"chars": 225,
"preview": "foo: &foo\n a: foo_a\n thing: foo_thing\n c: foo_c\n\nbar: &bar\n b: bar_b\n thing: bar_thing\n c: bar_c\n\nfoobarList:\n b:"
},
{
"path": "examples/mike.xml",
"chars": 44,
"preview": "<zoo><thing><frog>boing</frog></thing></zoo>"
},
{
"path": "examples/mike2.xml",
"chars": 305,
"preview": " <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <!-- osm-->\n <osm version=\"0.6\" generator=\"CGImap 0.0.2\">\n <!-- bounds-->\n "
},
{
"path": "examples/multiline-text.yaml",
"chars": 35,
"preview": "test: |\n abcdefg \n hijklmno\n\n\n"
},
{
"path": "examples/multiple_docs.yaml",
"chars": 255,
"preview": "commonKey: first document\na: Easy! as one two three\nb:\n c: 2\n d: [3, 4]\n e:\n - name: fred\n value: 3\n - nam"
},
{
"path": "examples/multiple_docs_small.yaml",
"chars": 67,
"preview": "a: Easy! as one two three\n---\nanother:\n document: here\n---\n- 1\n- 2"
},
{
"path": "examples/numbered_keys.yml",
"chars": 14,
"preview": "5:\n 6: camel!"
},
{
"path": "examples/order.yaml",
"chars": 29,
"preview": "version: 3\napplication: MyApp"
},
{
"path": "examples/order.yml",
"chars": 89,
"preview": "version: '2'\nservices:\n test:\n image: ubuntu:14.04\n stdin_open: true\n tty: true"
},
{
"path": "examples/sample.hcl",
"chars": 210,
"preview": "# Arithmetic with literals and application-provided variables\nsum = 1 + addend\n\n# String interpolation and templates\nmes"
},
{
"path": "examples/sample.ini",
"chars": 204,
"preview": "\n; This is a INI document\n\n[owner]\nname = \"Tom Preston-Werner\"\ndob = 1979-05-27T07:32:00-08:00\n\n[database]\ndb_host = \"lo"
},
{
"path": "examples/sample.json",
"chars": 134,
"preview": "{\"a\":\"Easy! as one two three\",\"b\":{\"c\":2,\"d\":[3,4],\"e\":[{\"name\":\"fred\",\"value\":3},{\"name\":\"sam\",\"value\":4}]},\"ab\":\"must "
},
{
"path": "examples/sample.tf",
"chars": 480,
"preview": "# main.tf\n\n# Define required providers and minimum Terraform version\nterraform {\n required_providers {\n aws = {\n "
},
{
"path": "examples/sample.toml",
"chars": 368,
"preview": "\n\n# This is a TOML document\n\ntitle = \"TOML Example\"\n\n[owner]\nname = \"Tom Preston-Werner\"\ndob = 1979-05-27T07:32:00-08:00"
},
{
"path": "examples/sample.yaml",
"chars": 18,
"preview": " # things\na: apple"
},
{
"path": "examples/sample2.hcl",
"chars": 210,
"preview": "# Arithmetic with literals and application-provided variables\nsum = 1 + addend\n\n# String interpolation and templates\nmes"
},
{
"path": "examples/sample_array.yaml",
"chars": 7,
"preview": "[1,2,3]"
},
{
"path": "examples/sample_array_2.yaml",
"chars": 7,
"preview": "- 4\n- 5"
},
{
"path": "examples/sample_no_sections.ini",
"chars": 146,
"preview": "\n; This is a INI document\nname = \"Tom Preston-Werner\"\ndob = 1979-05-27T07:32:00-08:00\nenabled = true\nip = \"10.0.0.1\"\nrol"
},
{
"path": "examples/sample_objects.csv",
"chars": 83,
"preview": "name,numberOfCats,likesApples,height\n,1,true,168.8\nSamantha's Rabbit,2,false,-188.8"
},
{
"path": "examples/sample_text.yaml",
"chars": 3,
"preview": "hi\n"
},
{
"path": "examples/simple-anchor-exploded.yaml",
"chars": 28,
"preview": "foo:\n a: 1\n\nfoobar: \n a: 1"
},
{
"path": "examples/simple-anchor.yaml",
"chars": 37,
"preview": "foo: &foo\n a: 1\n\nfoobar: \n <<: *foo"
},
{
"path": "examples/small.properties",
"chars": 27,
"preview": "this.is = a properties file"
},
{
"path": "examples/small.xml",
"chars": 24,
"preview": "<this>is some xml</this>"
},
{
"path": "examples/small.yaml",
"chars": 35,
"preview": "---\n# comment\n# about things\na: cat"
},
{
"path": "examples/thing.yml",
"chars": 29,
"preview": "a: apple is included\nb: cool."
},
{
"path": "github-action/Dockerfile",
"chars": 244,
"preview": "FROM mikefarah/yq:4\n\nCOPY entrypoint.sh /entrypoint.sh\n\n# github action recommendation is to run as root.\n# https://docs"
},
{
"path": "github-action/entrypoint.sh",
"chars": 492,
"preview": "#!/bin/sh -l\nset -e\necho \"::debug::\\$cmd: $1\"\nRESULT=$(eval \"$1\")\necho \"::debug::\\$RESULT: $RESULT\"\n# updating from \n# h"
},
{
"path": "go.mod",
"chars": 1410,
"preview": "module github.com/mikefarah/yq/v4\n\nrequire (\n\tgithub.com/a8m/envsubst v1.4.3\n\tgithub.com/alecthomas/participle/v2 v2.1.4"
},
{
"path": "go.sum",
"chars": 7940,
"preview": "github.com/a8m/envsubst v1.4.3 h1:kDF7paGK8QACWYaQo6KtyYBozY2jhQrTuNNuUxQkhJY=\ngithub.com/a8m/envsubst v1.4.3/go.mod h1:"
},
{
"path": "go_install_test.go",
"chars": 703,
"preview": "package main\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"golang.org/x/mod/module\"\n\t\"golang.org/x/mod/zip\"\n)\n\n// TestGoInstallCompatibi"
},
{
"path": "how-it-works.md",
"chars": 5263,
"preview": "# Expression Syntax: A Visual Guide\nIn `yq`, expressions are made up of operators and pipes. A context of nodes is passe"
},
{
"path": "mkdocs.yml",
"chars": 135,
"preview": "docs_dir: mkdocs\nsite_dir: docs\nsite_name: Yq\ntheme: 'material'\nrepo_name: 'mikefarah/yq'\nrepo_url: 'https://github.com/"
},
{
"path": "pkg/yqlib/all_at_once_evaluator.go",
"chars": 2270,
"preview": "package yqlib\n\nimport (\n\t\"container/list\"\n)\n\n// A yaml expression evaluator that runs the expression once against all fi"
},
{
"path": "pkg/yqlib/all_at_once_evaluator_test.go",
"chars": 1126,
"preview": "package yqlib\n\nimport (\n\t\"bufio\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n)\n\nvar evaluateNodesScenario "
},
{
"path": "pkg/yqlib/base64_test.go",
"chars": 7677,
"preview": "//go:build !yq_nobase64\n\npackage yqlib\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n)\n\nconst"
},
{
"path": "pkg/yqlib/candidate_node.go",
"chars": 12309,
"preview": "package yqlib\n\nimport (\n\t\"container/list\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype Kind uint32\n\nconst (\n\tSequenceNode Kind ="
},
{
"path": "pkg/yqlib/candidate_node_goccy_yaml.go",
"chars": 6600,
"preview": "package yqlib\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tyaml \"github.com/goccy/go-yaml\"\n\t\"github.com/goccy/go-yaml/ast\"\n\tgoccyToken "
},
{
"path": "pkg/yqlib/candidate_node_test.go",
"chars": 10984,
"preview": "package yqlib\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n)\n\ntype valueRepScenario struct {\n\tinput "
},
{
"path": "pkg/yqlib/candidate_node_yaml.go",
"chars": 5422,
"preview": "package yqlib\n\nimport (\n\t\"fmt\"\n\n\tyaml \"go.yaml.in/yaml/v4\"\n)\n\nfunc MapYamlStyle(original yaml.Style) Style {\n\tswitch ori"
},
{
"path": "pkg/yqlib/candidiate_node_json.go",
"chars": 4234,
"preview": "//go:build !yq_nojson\n\npackage yqlib\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/goccy/go-json\"\n)\n\nfunc (o *"
},
{
"path": "pkg/yqlib/chown_linux.go",
"chars": 474,
"preview": "//go:build linux\n\npackage yqlib\n\nimport (\n\t\"io/fs\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc changeOwner(info fs.FileInfo, file *os.File)"
},
{
"path": "pkg/yqlib/chown_linux_test.go",
"chars": 3626,
"preview": "//go:build linux\n\npackage yqlib\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestChangeOwner(t *testing.T"
},
{
"path": "pkg/yqlib/chown_not_linux_os.go",
"chars": 127,
"preview": "//go:build !linux\n\npackage yqlib\n\nimport (\n\t\"io/fs\"\n\t\"os\"\n)\n\nfunc changeOwner(_ fs.FileInfo, _ *os.File) error {\n\treturn"
},
{
"path": "pkg/yqlib/color_print.go",
"chars": 1478,
"preview": "package yqlib\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/fatih/color\"\n\t\"github.com/goccy/go-yaml/lexer\"\n\t\"github.com/goccy/go-"
},
{
"path": "pkg/yqlib/color_print_test.go",
"chars": 3263,
"preview": "package yqlib\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/fatih/color\"\n)\n\nfunc TestFormat(t *testing.T) {\n\tte"
},
{
"path": "pkg/yqlib/context.go",
"chars": 2567,
"preview": "package yqlib\n\nimport (\n\t\"container/list\"\n\t\"fmt\"\n\t\"time\"\n\n\tlogging \"gopkg.in/op/go-logging.v1\"\n)\n\ntype Context struct {\n"
},
{
"path": "pkg/yqlib/context_test.go",
"chars": 7715,
"preview": "package yqlib\n\nimport (\n\t\"container/list\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n\tlogging \"gopkg.in/o"
},
{
"path": "pkg/yqlib/csv.go",
"chars": 428,
"preview": "package yqlib\n\ntype CsvPreferences struct {\n\tSeparator rune\n\tAutoParse bool\n}\n\nfunc NewDefaultCsvPreferences() CsvPrefer"
},
{
"path": "pkg/yqlib/csv_test.go",
"chars": 11986,
"preview": "package yqlib\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n)\n\nconst csvSimple = `name,number"
},
{
"path": "pkg/yqlib/data_tree_navigator.go",
"chars": 2218,
"preview": "package yqlib\n\nimport (\n\t\"fmt\"\n\n\tlogging \"gopkg.in/op/go-logging.v1\"\n)\n\ntype DataTreeNavigator interface {\n\t// given the"
},
{
"path": "pkg/yqlib/data_tree_navigator_test.go",
"chars": 12134,
"preview": "package yqlib\n\nimport (\n\t\"container/list\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n)\n\nfunc TestGetMatchingNodes_Ni"
},
{
"path": "pkg/yqlib/decoder.go",
"chars": 124,
"preview": "package yqlib\n\nimport (\n\t\"io\"\n)\n\ntype Decoder interface {\n\tInit(reader io.Reader) error\n\tDecode() (*CandidateNode, error"
},
{
"path": "pkg/yqlib/decoder_base64.go",
"chars": 1741,
"preview": "//go:build !yq_nobase64\n\npackage yqlib\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"strings\"\n)\n\ntype base64Decoder stru"
},
{
"path": "pkg/yqlib/decoder_csv_object.go",
"chars": 1934,
"preview": "//go:build !yq_nocsv\n\npackage yqlib\n\nimport (\n\t\"encoding/csv\"\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/dimchansky/utfbom\"\n)\n\ntype c"
},
{
"path": "pkg/yqlib/decoder_goccy_yaml.go",
"chars": 994,
"preview": "//go:build !yq_noyaml\n\n//\n// NOTE this is still a WIP - not yet ready.\n//\n\npackage yqlib\n\nimport (\n\t\"io\"\n\n\tyaml \"github."
},
{
"path": "pkg/yqlib/decoder_hcl.go",
"chars": 13842,
"preview": "//go:build !yq_nohcl\n\npackage yqlib\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/hashi"
},
{
"path": "pkg/yqlib/decoder_ini.go",
"chars": 2638,
"preview": "//go:build !yq_noini\n\npackage yqlib\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/go-ini/ini\"\n)\n\ntype iniDecoder struct {\n\treader"
},
{
"path": "pkg/yqlib/decoder_json.go",
"chars": 500,
"preview": "//go:build !yq_nojson\n\npackage yqlib\n\nimport (\n\t\"io\"\n\n\t\"github.com/goccy/go-json\"\n)\n\ntype jsonDecoder struct {\n\tdecoder "
},
{
"path": "pkg/yqlib/decoder_lua.go",
"chars": 3363,
"preview": "//go:build !yq_nolua\n\npackage yqlib\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\n\tlua \"github.com/yuin/gopher-lua\"\n)\n\ntype luaDecoder"
},
{
"path": "pkg/yqlib/decoder_properties.go",
"chars": 2963,
"preview": "//go:build !yq_noprops\n\npackage yqlib\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/magiconair/pro"
},
{
"path": "pkg/yqlib/decoder_test.go",
"chars": 1628,
"preview": "package yqlib\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype formatScenario struct {\n\tinput string\n\tinde"
},
{
"path": "pkg/yqlib/decoder_toml.go",
"chars": 16118,
"preview": "//go:build !yq_notoml\n\npackage yqlib\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\ttoml \"git"
},
{
"path": "pkg/yqlib/decoder_uri.go",
"chars": 999,
"preview": "//go:build !yq_nouri\n\npackage yqlib\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net/url\"\n)\n\ntype uriDecoder struct {\n\treader io.Rea"
},
{
"path": "pkg/yqlib/decoder_uri_test.go",
"chars": 4237,
"preview": "//go:build !yq_nouri\n\npackage yqlib\n\nimport (\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/mikefarah/yq/v4/test\"\n)\n\nfunc Te"
},
{
"path": "pkg/yqlib/decoder_xml.go",
"chars": 11135,
"preview": "//go:build !yq_noxml\n\npackage yqlib\n\nimport (\n\t\"encoding/xml\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\""
},
{
"path": "pkg/yqlib/decoder_yaml.go",
"chars": 5537,
"preview": "package yqlib\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n\n\tyaml \"go.yaml.in/yaml/v4\"\n)\n\nvar (\n\tcom"
},
{
"path": "pkg/yqlib/doc/.gitignore",
"chars": 6,
"preview": "*.zip\n"
},
{
"path": "pkg/yqlib/doc/notification-snippet.md",
"chars": 0,
"preview": ""
},
{
"path": "pkg/yqlib/doc/operators/add.md",
"chars": 4513,
"preview": "# Add\n\nAdd behaves differently according to the type of the LHS:\n* arrays: concatenate\n* number scalars: arithmetic addi"
},
{
"path": "pkg/yqlib/doc/operators/alternative-default-value.md",
"chars": 1310,
"preview": "# Alternative (Default value)\n\nThis operator is used to provide alternative (or default) values when a particular expres"
},
{
"path": "pkg/yqlib/doc/operators/anchor-and-alias-operators.md",
"chars": 7628,
"preview": "# Anchor and Alias Operators\n\nUse the `alias` and `anchor` operators to read and write yaml aliases and anchors. The `ex"
},
{
"path": "pkg/yqlib/doc/operators/array-to-map.md",
"chars": 458,
"preview": "# Array to Map\n\nUse this operator to convert an array to..a map. The indices are used as map keys, null values in the ar"
},
{
"path": "pkg/yqlib/doc/operators/assign-update.md",
"chars": 3648,
"preview": "# Assign (Update)\n\nThis operator is used to update node values. It can be used in either the:\n\n### plain form: `=`\nWhich"
},
{
"path": "pkg/yqlib/doc/operators/boolean-operators.md",
"chars": 3770,
"preview": "# Boolean Operators\n\nThe `or` and `and` operators take two parameters and return a boolean result. \n\n`not` flips a boole"
},
{
"path": "pkg/yqlib/doc/operators/collect-into-array.md",
"chars": 426,
"preview": "# Collect into Array\n\nThis creates an array using the expression between the square brackets.\n\n\n## Collect empty\nRunning"
},
{
"path": "pkg/yqlib/doc/operators/column.md",
"chars": 833,
"preview": "# Column\n\nReturns the column of the matching node. Starts from 1, 0 indicates there was no column data.\n\nColumn is the n"
},
{
"path": "pkg/yqlib/doc/operators/comment-operators.md",
"chars": 5649,
"preview": "# Comment Operators\n\nUse these comment operators to set or retrieve comments. Note that line comments on maps/arrays are"
},
{
"path": "pkg/yqlib/doc/operators/compare.md",
"chars": 1574,
"preview": "# Compare Operators\n\nComparison operators (`>`, `>=`, `<`, `<=`) can be used for comparing scalar values of the same tim"
},
{
"path": "pkg/yqlib/doc/operators/contains.md",
"chars": 1874,
"preview": "# Contains\n\nThis returns `true` if the context contains the passed in parameter, and false otherwise. For arrays, this w"
},
{
"path": "pkg/yqlib/doc/operators/create-collect-into-object.md",
"chars": 1199,
"preview": "# Create, Collect into Object\n\nThis is used to construct objects (or maps). This can be used against existing yaml, or t"
},
{
"path": "pkg/yqlib/doc/operators/datetime.md",
"chars": 4697,
"preview": "# Date Time\n\nVarious operators for parsing and manipulating dates. \n\n## Date time formatting\nThis uses Golang's built in"
},
{
"path": "pkg/yqlib/doc/operators/delete.md",
"chars": 1284,
"preview": "# Delete\n\nDeletes matching entries in maps or arrays.\n\n## Delete entry in map\nGiven a sample.yml file of:\n```yaml\na: cat"
},
{
"path": "pkg/yqlib/doc/operators/divide.md",
"chars": 761,
"preview": "# Divide\n\nDivide behaves differently according to the type of the LHS:\n* strings: split by the divider\n* number: arithme"
},
{
"path": "pkg/yqlib/doc/operators/document-index.md",
"chars": 1063,
"preview": "# Document Index\n\nUse the `documentIndex` operator (or the `di` shorthand) to select nodes of a particular document.\n\n##"
},
{
"path": "pkg/yqlib/doc/operators/encode-decode.md",
"chars": 7870,
"preview": "# Encoder / Decoder\n\nEncode operators will take the piped in object structure and encode it as a string in the desired f"
},
{
"path": "pkg/yqlib/doc/operators/entries.md",
"chars": 2346,
"preview": "# Entries\n\nSimilar to the same named functions in `jq` these functions convert to/from an object and an array of key-val"
},
{
"path": "pkg/yqlib/doc/operators/env-variable-operators.md",
"chars": 6312,
"preview": "# Env Variable Operators\n\nThese operators are used to handle environment variables usage in expressions and documents. W"
},
{
"path": "pkg/yqlib/doc/operators/equals.md",
"chars": 1735,
"preview": "# Equals / Not Equals\n\nThis is a boolean operator that will return `true` if the LHS is equal to the RHS and `false` oth"
},
{
"path": "pkg/yqlib/doc/operators/error.md",
"chars": 1020,
"preview": "# Error\n\nUse this operation to short-circuit expressions. Useful for validation.\n\n## Validate a particular value\nGiven a"
},
{
"path": "pkg/yqlib/doc/operators/eval.md",
"chars": 951,
"preview": "# Eval\n\nUse `eval` to dynamically process an expression - for instance from an environment variable.\n\n`eval` takes a sin"
},
{
"path": "pkg/yqlib/doc/operators/file-operators.md",
"chars": 1225,
"preview": "# File Operators\n\nFile operators are most often used with merge when needing to merge specific files together. Note that"
},
{
"path": "pkg/yqlib/doc/operators/filter.md",
"chars": 491,
"preview": "# Filter\n\nFilters an array (or map values) by the expression given. Equivalent to doing `map(select(exp))`.\n\n\n## Filter "
},
{
"path": "pkg/yqlib/doc/operators/first.md",
"chars": 4021,
"preview": "# First\n\nReturns the first matching element in an array, or first matching value in a map.\n\nCan be given an expression t"
},
{
"path": "pkg/yqlib/doc/operators/flatten.md",
"chars": 712,
"preview": "# Flatten\nThis recursively flattens arrays.\n\n## Flatten\nRecursively flattens all arrays\n\nGiven a sample.yml file of:\n```"
},
{
"path": "pkg/yqlib/doc/operators/group-by.md",
"chars": 659,
"preview": "# Group By\n\nThis is used to group items in an array by an expression.\n\n## Group by field\nGiven a sample.yml file of:\n```"
},
{
"path": "pkg/yqlib/doc/operators/has.md",
"chars": 777,
"preview": "# Has\n\nThis operation returns true if the key exists in a map (or index in an array), false otherwise.\n\n## Has map key\nG"
},
{
"path": "pkg/yqlib/doc/operators/headers/Main.md",
"chars": 1840,
"preview": "# NAME\n *yq* is a portable command-line data file processor\n\n# SYNOPSIS \n\nyq [eval/eval-all] [expression] files..\n\neval"
},
{
"path": "pkg/yqlib/doc/operators/headers/add.md",
"chars": 355,
"preview": "# Add\n\nAdd behaves differently according to the type of the LHS:\n* arrays: concatenate\n* number scalars: arithmetic addi"
},
{
"path": "pkg/yqlib/doc/operators/headers/alternative-default-value.md",
"chars": 150,
"preview": "# Alternative (Default value)\n\nThis operator is used to provide alternative (or default) values when a particular expres"
},
{
"path": "pkg/yqlib/doc/operators/headers/anchor-and-alias-operators.md",
"chars": 1185,
"preview": "# Anchor and Alias Operators\n\nUse the `alias` and `anchor` operators to read and write yaml aliases and anchors. The `ex"
},
{
"path": "pkg/yqlib/doc/operators/headers/array-to-map.md",
"chars": 268,
"preview": "# Array to Map\n\nUse this operator to convert an array to..a map. The indices are used as map keys, null values in the ar"
},
{
"path": "pkg/yqlib/doc/operators/headers/assign-update.md",
"chars": 496,
"preview": "# Assign (Update)\n\nThis operator is used to update node values. It can be used in either the:\n\n### plain form: `=`\nWhich"
},
{
"path": "pkg/yqlib/doc/operators/headers/boolean-operators.md",
"chars": 969,
"preview": "# Boolean Operators\n\nThe `or` and `and` operators take two parameters and return a boolean result. \n\n`not` flips a boole"
},
{
"path": "pkg/yqlib/doc/operators/headers/collect-into-array.md",
"chars": 95,
"preview": "# Collect into Array\n\nThis creates an array using the expression between the square brackets.\n\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/column.md",
"chars": 186,
"preview": "# Column\n\nReturns the column of the matching node. Starts from 1, 0 indicates there was no column data.\n\nColumn is the n"
},
{
"path": "pkg/yqlib/doc/operators/headers/comment-operators.md",
"chars": 702,
"preview": "# Comment Operators\n\nUse these comment operators to set or retrieve comments. Note that line comments on maps/arrays are"
},
{
"path": "pkg/yqlib/doc/operators/headers/compare.md",
"chars": 515,
"preview": "# Compare Operators\n\nComparison operators (`>`, `>=`, `<`, `<=`) can be used for comparing scalar values of the same tim"
},
{
"path": "pkg/yqlib/doc/operators/headers/contains.md",
"chars": 617,
"preview": "# Contains\n\nThis returns `true` if the context contains the passed in parameter, and false otherwise. For arrays, this w"
},
{
"path": "pkg/yqlib/doc/operators/headers/create-collect-into-object.md",
"chars": 151,
"preview": "# Create, Collect into Object\n\nThis is used to construct objects (or maps). This can be used against existing yaml, or t"
},
{
"path": "pkg/yqlib/doc/operators/headers/datetime.md",
"chars": 1013,
"preview": "# Date Time\n\nVarious operators for parsing and manipulating dates. \n\n## Date time formatting\nThis uses Golang's built in"
},
{
"path": "pkg/yqlib/doc/operators/headers/delete.md",
"chars": 54,
"preview": "# Delete\n\nDeletes matching entries in maps or arrays.\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/divide.md",
"chars": 133,
"preview": "# Divide\n\nDivide behaves differently according to the type of the LHS:\n* strings: split by the divider\n* number: arithme"
},
{
"path": "pkg/yqlib/doc/operators/headers/document-index.md",
"chars": 117,
"preview": "# Document Index\n\nUse the `documentIndex` operator (or the `di` shorthand) to select nodes of a particular document.\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/encode-decode.md",
"chars": 1244,
"preview": "# Encoder / Decoder\n\nEncode operators will take the piped in object structure and encode it as a string in the desired f"
},
{
"path": "pkg/yqlib/doc/operators/headers/entries.md",
"chars": 282,
"preview": "# Entries\n\nSimilar to the same named functions in `jq` these functions convert to/from an object and an array of key-val"
},
{
"path": "pkg/yqlib/doc/operators/headers/env-variable-operators.md",
"chars": 1630,
"preview": "# Env Variable Operators\n\nThese operators are used to handle environment variables usage in expressions and documents. W"
},
{
"path": "pkg/yqlib/doc/operators/headers/equals.md",
"chars": 633,
"preview": "# Equals / Not Equals\n\nThis is a boolean operator that will return `true` if the LHS is equal to the RHS and `false` oth"
},
{
"path": "pkg/yqlib/doc/operators/headers/error.md",
"chars": 81,
"preview": "# Error\n\nUse this operation to short-circuit expressions. Useful for validation.\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/eval.md",
"chars": 349,
"preview": "# Eval\n\nUse `eval` to dynamically process an expression - for instance from an environment variable.\n\n`eval` takes a sin"
},
{
"path": "pkg/yqlib/doc/operators/headers/file-operators.md",
"chars": 571,
"preview": "# File Operators\n\nFile operators are most often used with merge when needing to merge specific files together. Note that"
},
{
"path": "pkg/yqlib/doc/operators/headers/filter.md",
"chars": 109,
"preview": "# Filter\n\nFilters an array (or map values) by the expression given. Equivalent to doing `map(select(exp))`.\n\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/first.md",
"chars": 172,
"preview": "# First\n\nReturns the first matching element in an array, or first matching value in a map.\n\nCan be given an expression t"
},
{
"path": "pkg/yqlib/doc/operators/headers/flatten.md",
"chars": 44,
"preview": "# Flatten\nThis recursively flattens arrays.\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/group-by.md",
"chars": 70,
"preview": "# Group By\n\nThis is used to group items in an array by an expression.\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/has.md",
"chars": 103,
"preview": "# Has\n\nThis operation returns true if the key exists in a map (or index in an array), false otherwise.\n"
},
{
"path": "pkg/yqlib/doc/operators/headers/keys.md",
"chars": 70,
"preview": "# Keys\n\nUse the `keys` operator to return map keys or array indices. \n"
}
]
// ... and 336 more files (download for full content)
About this extraction
This page contains the full source code of the mikefarah/yq GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 536 files (1.5 MB), approximately 491.1k tokens, and a symbol index with 1406 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.