Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested conversion using gocty.FromCtyValue fails #38

Closed
DavidGamba opened this issue Jan 31, 2020 · 6 comments
Closed

Nested conversion using gocty.FromCtyValue fails #38

DavidGamba opened this issue Jan 31, 2020 · 6 comments

Comments

@DavidGamba
Copy link

Given a spec:

var mapDetailsSpec = &hcldec.ObjectSpec{
	"width": &hcldec.AttrSpec{
		Name:     "width",
		Required: false,
		Type:     cty.Number,
	},
	"font_size": &hcldec.AttrSpec{
		Name:     "font_size",
		Required: false,
		Type:     cty.Number,
	},
}

I can parse basic HCL:

width = 100
font_size = 9
	parser := hclparse.NewParser()
	f, diags := parser.ParseHCL([]byte(data), filename)
	val, moreDiags := hcldec.Decode(f.Body, mapDetailsSpec, nil)

Then converting to a golang struct works:

type MapDetails struct {
	Width    int `cty:"width"`
	FontSize int `cty:"font_size"`
}

	var mapDetails MapDetails
	err := gocty.FromCtyValue(val, &mapDetails)

However, when I try to do a nested structure:

size {
	width = 100
	font_size = 9
}
var mapDetailsSpec = &hcldec.ObjectSpec{
	"size": &hcldec.BlockListSpec{
		TypeName: "size",
		Nested: &hcldec.ObjectSpec{
			"width": &hcldec.AttrSpec{
				Name:     "width",
				Required: false,
				Type:     cty.Number,
			},
			"font_size": &hcldec.AttrSpec{
				Name:     "font_size",
				Required: false,
				Type:     cty.Number,
			},
		},
	},
}

I haven't been able to convert to a native golang struct:

type MapDetails struct {
	Size Size `cty:"size"`
}

type Size struct {
	Width    *int `cty:"width"`
	Height   *int `cty:"height"`
	Margin   *int `cty:"margin"`
	FontSize *int `cty:"font_size"`
}

and gocty.FromCtyValue always fails with "object or tuple value is required".

@DavidGamba
Copy link
Author

Adding a minimal reproduction file:

main.txt

@apparentlymart
Copy link
Collaborator

Hi @DavidGamba! I think this may be related to #17, but I'm not totally sure yet because I've not traced this through all of the HCL layers to see what the final cty value actually looks like here.

In the meantime, you might find it simpler to go directly from HCL to a Go struct, without the intermediate hcldec and gocty steps, using HCL's own gohcl package. Because that package is working with HCL concepts rather than cty concepts, it's able to better handle HCL's own conventions, and as a bonus it will tend to produce better error messages that use HCL terminology rather than cty terminology.

@DavidGamba
Copy link
Author

@apparentlymart thanks for the reply, I'll dive into gohcl and report back, sorry for the delay.

@DavidGamba
Copy link
Author

@apparentlymart I have a working implementation using gohcl (https://github.com/DavidGamba/go-wardley/blob/master/hcl/hcl.go#L131). My problem is that I want to figure out how to do something like:

node user {
	...
	x = 1
}
node vcs {
	...
	x = node.user.x + 1
}

But haven't figured out how to yet, that is why I started diving into the cty code.
Any pointers would be greatly useful, the HCL documentation doesn't have any standalone examples that leverage additional features that so far are only seen in Terraform.

Thanks!

@apparentlymart
Copy link
Collaborator

Hi @DavidGamba,

I think you're describing the pattern that's covered in the HCL manual as Interdependent Blocks. There isn't a complete code example there but it does give some hints on how to achieve it, though written under the assumption that you've already read earlier content like Decoding into Native Go Values.

If you'd like to discuss that some more I'm happy to work with you in an issue in the HCL repository. cty features can't really help directly with that particular processing model because it relates to HCL's expressions concept, not to cty's types and values.

@DavidGamba
Copy link
Author

Thanks for the pointers, I'll close the issue here and open an issue in the HCL repo if I can't manage to figure it out.
Thanks so much for the great libraries and taking the time to respond.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants