From 843129da2172d1a3c416153213a6555c1f111e8e Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Fri, 8 Aug 2025 08:01:22 -0400 Subject: [PATCH] add unlinked action --- schemas.go | 20 +++++++++++ schemas_test.go | 50 ++++++++++++++++++++++++++ testdata/actions/unlinked_schemas.json | 1 + 3 files changed, 71 insertions(+) create mode 100644 testdata/actions/unlinked_schemas.json diff --git a/schemas.go b/schemas.go index dad47e7..6781db0 100644 --- a/schemas.go +++ b/schemas.go @@ -90,6 +90,9 @@ type ProviderSchema struct { // The schemas for any ephemeral resources in this provider. EphemeralResourceSchemas map[string]*Schema `json:"ephemeral_resource_schemas,omitempty"` + // The schemas for any actions in this provider. + ActionSchemas map[string]*ActionSchema `json:"action_schemas,omitempty"` + // The definitions for any functions in this provider. Functions map[string]*FunctionSignature `json:"functions,omitempty"` @@ -328,3 +331,20 @@ type IdentityAttribute struct { // provider OptionalForImport bool `json:"optional_for_import,omitempty"` } + +// ActionSchema is the JSON representation of an action schema +type ActionSchema struct { + // The version of the action schema. + Version uint64 `json:"version"` + + // The root-level block of configuration values. + Block *SchemaBlock `json:"block,omitempty"` + + // Additional information about the action, only populated if the action is unlinked. + Unlinked *UnlinkedSchemaType `json:"unlinked,omitempty"` +} + +// UnlinkedSchemaType contains any additional information about an unlinked action. +type UnlinkedSchemaType struct { + // Currently there is no additional information for unlinked action schema types +} diff --git a/schemas_test.go b/schemas_test.go index 59b9c7f..4a554d3 100644 --- a/schemas_test.go +++ b/schemas_test.go @@ -7,6 +7,10 @@ import ( "encoding/json" "os" "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/zclconf/go-cty/cty" ) func TestProviderSchemasValidate(t *testing.T) { @@ -75,3 +79,49 @@ func TestProviderSchemas_writeOnlyAttribute(t *testing.T) { t.Fatal("expected terraform_example.foo to not be marked as write-only") } } + +func TestProviderSchemas_unlinked_action(t *testing.T) { + expectedAction := &ActionSchema{ + Block: &SchemaBlock{ + DescriptionKind: SchemaDescriptionKindPlain, + Attributes: map[string]*SchemaAttribute{ + "program": { + AttributeType: cty.List(cty.String), + Description: "A list of strings, whose first element is the program to run and whose subsequent elements are optional command line arguments to the program.", + DescriptionKind: SchemaDescriptionKindPlain, + Required: true, + }, + "query": { + AttributeType: cty.Map(cty.String), + Description: "A map of string values to pass to the external program as the query arguments. If not supplied, the program will receive an empty object as its input.", + DescriptionKind: SchemaDescriptionKindPlain, + Optional: true, + }, + "working_dir": { + AttributeType: cty.String, + Description: "Working directory of the program. If not supplied, the program will run in the current directory.", + DescriptionKind: SchemaDescriptionKindPlain, + Optional: true, + }, + }, + }, + Unlinked: &UnlinkedSchemaType{}, + } + + f, err := os.Open("testdata/actions/unlinked_schemas.json") + if err != nil { + t.Fatal(err) + } + defer f.Close() + + var schemas *ProviderSchemas + if err := json.NewDecoder(f).Decode(&schemas); err != nil { + t.Fatal(err) + } + + gotAction := schemas.Schemas["registry.terraform.io/hashicorp/external"].ActionSchemas["external"] + if diff := cmp.Diff(gotAction, expectedAction, cmpopts.EquateComparable(cty.Type{})); diff != "" { + t.Errorf("Unexpected diff (+wanted, -got): %s", diff) + return + } +} diff --git a/testdata/actions/unlinked_schemas.json b/testdata/actions/unlinked_schemas.json new file mode 100644 index 0000000..ad0d5e0 --- /dev/null +++ b/testdata/actions/unlinked_schemas.json @@ -0,0 +1 @@ +{"format_version":"1.0","provider_schemas":{"registry.terraform.io/hashicorp/external":{"provider":{"version":0,"block":{"description_kind":"plain"}},"action_schemas":{"external":{"block":{"attributes":{"program":{"type":["list","string"],"description":"A list of strings, whose first element is the program to run and whose subsequent elements are optional command line arguments to the program.","description_kind":"plain","required":true},"query":{"type":["map","string"],"description":"A map of string values to pass to the external program as the query arguments. If not supplied, the program will receive an empty object as its input.","description_kind":"plain","optional":true},"working_dir":{"type":"string","description":"Working directory of the program. If not supplied, the program will run in the current directory.","description_kind":"plain","optional":true}},"description_kind":"plain"},"unlinked":{}}}}}}