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

Add metadata functions structs #68

Merged
merged 5 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package tfjson

import (
"encoding/json"
"errors"
"fmt"

"github.com/hashicorp/go-version"
"github.com/zclconf/go-cty/cty"
)

// MetadataFunctionsFormatVersionConstraints defines the versions of the JSON
// metadata functions format that are supported by this package.
var MetadataFunctionsFormatVersionConstraints = "~> 1.0"

// MetadataFunctions is the top-level object returned when exporting function
// signatures
type MetadataFunctions struct {
// The version of the format. This should always match the
// MetadataFunctionsFormatVersionConstraints in this package, else
// unmarshaling will fail.
FormatVersion string `json:"format_version"`

// The signatures of the functions available in a Terraform version.
Signatures map[string]*FunctionSignature `json:"function_signatures,omitempty"`
}

// Validate checks to ensure that MetadataFunctions is present, and the
// version matches the version supported by this library.
func (f *MetadataFunctions) Validate() error {
if f == nil {
return errors.New("metadata functions data is nil")
}

if f.FormatVersion == "" {
return errors.New("unexpected metadata functions data, format version is missing")
}

constraint, err := version.NewConstraint(MetadataFunctionsFormatVersionConstraints)
if err != nil {
return fmt.Errorf("invalid version constraint: %w", err)
}

version, err := version.NewVersion(f.FormatVersion)
if err != nil {
return fmt.Errorf("invalid format version %q: %w", f.FormatVersion, err)
}

if !constraint.Check(version) {
return fmt.Errorf("unsupported metadata functions format version: %q does not satisfy %q",
version, constraint)
}

return nil
}

func (f *MetadataFunctions) UnmarshalJSON(b []byte) error {
type rawFunctions MetadataFunctions
var functions rawFunctions

err := json.Unmarshal(b, &functions)
if err != nil {
return err
}

*f = *(*MetadataFunctions)(&functions)

return f.Validate()
}

// FunctionSignature represents a function signature.
type FunctionSignature struct {
// Description is an optional human-readable description
// of the function
Description string `json:"description,omitempty"`

// ReturnType is the ctyjson representation of the function's
// return types based on supplying all parameters using
// dynamic types. Functions can have dynamic return types.
ReturnType cty.Type `json:"return_type"`

// Parameters describes the function's fixed positional parameters.
Parameters []*FunctionParameter `json:"parameters,omitempty"`

// VariadicParameter describes the function's variadic
// parameter if it is supported.
VariadicParameter *FunctionParameter `json:"variadic_parameter,omitempty"`
}

// FunctionParameter represents a parameter to a function.
type FunctionParameter struct {
// Name is an optional name for the argument.
Name string `json:"name,omitempty"`

// Description is an optional human-readable description
// of the argument
Description string `json:"description,omitempty"`

// IsNullable is true if null is acceptable value for the argument
IsNullable bool `json:"is_nullable,omitempty"`

// A type that any argument for this parameter must conform to.
Type cty.Type `json:"type"`
}
24 changes: 24 additions & 0 deletions metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package tfjson

import (
"encoding/json"
"os"
"testing"
)

func TestMetadataFunctionsValidate(t *testing.T) {
f, err := os.Open("testdata/basic/functions.json")
if err != nil {
t.Fatal(err)
}
defer f.Close()

var functions *MetadataFunctions
if err := json.NewDecoder(f).Decode(&functions); err != nil {
t.Fatal(err)
}

if err := functions.Validate(); err != nil {
t.Fatal(err)
}
}
2 changes: 1 addition & 1 deletion schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (p *ProviderSchemas) Validate() error {
return errors.New("unexpected provider schema data, format version is missing")
}

constraint, err := version.NewConstraint(PlanFormatVersionConstraints)
constraint, err := version.NewConstraint(ProviderSchemasFormatVersionConstraints)
dbanck marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return fmt.Errorf("invalid version constraint: %w", err)
}
Expand Down
Loading