Merge branch 'master' into toml_encoder

This commit is contained in:
Mike Farah 2025-12-16 14:27:22 +11:00
commit aa858520a8
8 changed files with 104 additions and 4 deletions

1
.gitignore vendored
View File

@ -43,6 +43,7 @@ yq*.snap
test.yml test.yml
test*.yml test*.yml
test*.tf
test*.xml test*.xml
test*.toml test*.toml
test*.yaml test*.yaml

View File

@ -363,6 +363,8 @@ gah install yq
- [Load content from other files](https://mikefarah.gitbook.io/yq/operators/load) - [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 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 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 properties](https://mikefarah.gitbook.io/yq/v/v4.x/usage/properties)
- [Convert to/from csv/tsv](https://mikefarah.gitbook.io/yq/usage/csv-tsv) - [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) - [General shell completion scripts (bash/zsh/fish/powershell)](https://mikefarah.gitbook.io/yq/v/v4.x/commands/shell-completion)
@ -413,7 +415,7 @@ Flags:
-h, --help help for yq -h, --help help for yq
-I, --indent int sets indent level for output (default 2) -I, --indent int sets indent level for output (default 2)
-i, --inplace update the file in place of first file given. -i, --inplace update the file in place of first file given.
-p, --input-format string [auto|a|yaml|y|json|j|props|p|csv|c|tsv|t|xml|x|base64|uri|toml|lua|l|ini|i] parse format for input. (default "auto") -p, --input-format string [auto|a|yaml|y|json|j|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-globals output keys as top-level global variables
--lua-prefix string prefix (default "return ") --lua-prefix string prefix (default "return ")
--lua-suffix string suffix (default ";\n") --lua-suffix string suffix (default ";\n")
@ -422,7 +424,7 @@ Flags:
-N, --no-doc Don't print document separators (---) -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. -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. -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|props|p|csv|c|tsv|t|xml|x|base64|uri|toml|shell|s|lua|l|ini|i] output format type. (default "auto") -o, --output-format string [auto|a|yaml|y|json|j|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 = ""' -P, --prettyPrint pretty print, shorthand for '... style = ""'
--properties-array-brackets use [x] in array paths (e.g. for SpringBoot) --properties-array-brackets use [x] in array paths (e.g. for SpringBoot)
--properties-separator string separator to use between keys and values (default " = ") --properties-separator string separator to use between keys and values (default " = ")

View File

@ -6,6 +6,7 @@ setUp() {
rm test*.csv 2>/dev/null || true rm test*.csv 2>/dev/null || true
rm test*.tsv 2>/dev/null || true rm test*.tsv 2>/dev/null || true
rm test*.xml 2>/dev/null || true rm test*.xml 2>/dev/null || true
rm test*.tf 2>/dev/null || true
} }
testInputProperties() { testInputProperties() {
@ -255,4 +256,61 @@ EOM
assertEquals "$expected" "$X" 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 source ./scripts/shunit2

27
examples/sample.tf Normal file
View File

@ -0,0 +1,27 @@
# main.tf
# Define required providers and minimum Terraform version
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.2"
}
# Configure the AWS provider
provider "aws" {
region = var.aws_region
}
# Define an S3 bucket resource
resource "aws_s3_bucket" "example_bucket" {
bucket = var.bucket_name
tags = {
Environment = "Development"
Project = "TerraformExample"
}
}

View File

@ -43,6 +43,9 @@ func (he *hclEncoder) PrintLeadingContent(_ io.Writer, _ string) error {
func (he *hclEncoder) Encode(writer io.Writer, node *CandidateNode) error { func (he *hclEncoder) Encode(writer io.Writer, node *CandidateNode) error {
log.Debugf("I need to encode %v", NodeToString(node)) log.Debugf("I need to encode %v", NodeToString(node))
if node.Kind == ScalarNode {
return writeString(writer, node.Value+"\n")
}
f := hclwrite.NewEmptyFile() f := hclwrite.NewEmptyFile()
body := f.Body() body := f.Body()
@ -490,7 +493,7 @@ func (he *hclEncoder) encodeBlockIfMapping(body *hclwrite.Body, key string, valu
// encodeNode encodes a CandidateNode directly to HCL, preserving style information // encodeNode encodes a CandidateNode directly to HCL, preserving style information
func (he *hclEncoder) encodeNode(body *hclwrite.Body, node *CandidateNode) error { func (he *hclEncoder) encodeNode(body *hclwrite.Body, node *CandidateNode) error {
if node.Kind != MappingNode { if node.Kind != MappingNode {
return fmt.Errorf("HCL encoder expects a mapping at the root level") return fmt.Errorf("HCL encoder expects a mapping at the root level, got %v", kindToString(node.Kind))
} }
for i := 0; i < len(node.Content); i += 2 { for i := 0; i < len(node.Content); i += 2 {

View File

@ -67,7 +67,7 @@ var TomlFormat = &Format{"toml", []string{},
func() Decoder { return NewTomlDecoder() }, func() Decoder { return NewTomlDecoder() },
} }
var HclFormat = &Format{"hcl", []string{"h"}, var HclFormat = &Format{"hcl", []string{"h", "tf"},
func() Encoder { return NewHclEncoder(ConfiguredHclPreferences) }, func() Encoder { return NewHclEncoder(ConfiguredHclPreferences) },
func() Decoder { return NewHclDecoder() }, func() Decoder { return NewHclDecoder() },
} }

View File

@ -325,6 +325,14 @@ var hclFormatScenarios = []formatScenario{
expected: "# Configuration\nport = 8080\n", expected: "# Configuration\nport = 8080\n",
scenarioType: "roundtrip", scenarioType: "roundtrip",
}, },
{
description: "Roundtrip: extraction",
skipDoc: true,
input: simpleSample,
expression: ".shouty_message",
expected: "upper(message)\n",
scenarioType: "roundtrip",
},
{ {
description: "Roundtrip: With templates, functions and arithmetic", description: "Roundtrip: With templates, functions and arithmetic",
input: simpleSample, input: simpleSample,

View File

@ -1,5 +1,6 @@
4.50.1: 4.50.1:
- Added HCL support! - Added HCL support!
- Fixing handling of CRLF #2352
- Bumped dependencies - Bumped dependencies
4.49.2: 4.49.2: