From 3d27c75de87fd0c17a5be6918a6787c5281c2626 Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Mon, 21 Nov 2022 17:15:05 -0800 Subject: [PATCH 1/2] Don't emit missing var errors for const vars We test that consts behave correctly by omitting them from an example and assigning from the omitted value. --- pkg/codegen/hcl2/model/type_const.go | 17 +++++++++++++++++ pkg/codegen/pcl/binder_resource.go | 11 +++++++++-- pkg/codegen/testing/test/program_driver.go | 3 --- .../kubernetes-pod-pp/dotnet/kubernetes-pod.cs | 3 ++- .../kubernetes-pod-pp/go/kubernetes-pod.go | 4 ++-- .../kubernetes-pod-pp/kubernetes-pod.pp | 4 +++- .../kubernetes-pod-pp/nodejs/kubernetes-pod.ts | 2 +- .../kubernetes-pod-pp/python/kubernetes-pod.py | 2 +- 8 files changed, 35 insertions(+), 11 deletions(-) diff --git a/pkg/codegen/hcl2/model/type_const.go b/pkg/codegen/hcl2/model/type_const.go index a23b61904f81..b124a9f7a0a8 100644 --- a/pkg/codegen/hcl2/model/type_const.go +++ b/pkg/codegen/hcl2/model/type_const.go @@ -98,3 +98,20 @@ func (t *ConstType) unify(other Type) (Type, ConversionKind) { } func (*ConstType) isType() {} + +func IsConstType(t Type) bool { + switch t := t.(type) { + case *ConstType: + return true + case *UnionType: + for _, t := range t.ElementTypes { + _, ok := t.(*ConstType) + if !ok { + return false + } + } + return true + default: + return false + } +} diff --git a/pkg/codegen/pcl/binder_resource.go b/pkg/codegen/pcl/binder_resource.go index 9d67fe063e56..2dd78ee48f79 100644 --- a/pkg/codegen/pcl/binder_resource.go +++ b/pkg/codegen/pcl/binder_resource.go @@ -382,9 +382,16 @@ func (b *binder) bindResourceBody(node *Resource) hcl.Diagnostics { } for _, k := range codegen.SortedKeys(objectType.Properties) { - if !model.IsOptionalType(objectType.Properties[k]) && !attrNames.Has(k) { - diag(missingRequiredAttribute(k, block.Body.Syntax.MissingItemRange())) + typ := objectType.Properties[k] + if model.IsOptionalType(typ) || attrNames.Has(k) { + // The type is present or optional. No error. + continue + } + if model.IsConstType(objectType.Properties[k]) { + // The type is const, so the value is implied. No error. + continue } + diag(missingRequiredAttribute(k, block.Body.Syntax.MissingItemRange())) } } diff --git a/pkg/codegen/testing/test/program_driver.go b/pkg/codegen/testing/test/program_driver.go index 23645bc96ed4..b2c685e67ce8 100644 --- a/pkg/codegen/testing/test/program_driver.go +++ b/pkg/codegen/testing/test/program_driver.go @@ -292,9 +292,6 @@ var PulumiPulumiYAMLProgramTests = []ProgramTest{ Directory: transpiled("kubernetes"), Description: "Kubernetes", Skip: codegen.NewStringSet("go"), - // PCL resource attribute type checking doesn't handle missing `const` attributes. - // - BindOptions: []pcl.BindOption{pcl.SkipResourceTypechecking}, }, { Directory: transpiled("pulumi-variable"), diff --git a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/dotnet/kubernetes-pod.cs b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/dotnet/kubernetes-pod.cs index 0c28c2b3d50d..afd19ac6b5e0 100644 --- a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/dotnet/kubernetes-pod.cs +++ b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/dotnet/kubernetes-pod.cs @@ -7,7 +7,6 @@ var bar = new Kubernetes.Core.V1.Pod("bar", new() { ApiVersion = "v1", - Kind = "Pod", Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs { Namespace = "foo", @@ -41,5 +40,7 @@ }, }); + var kind = bar.Kind; + }); diff --git a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/go/kubernetes-pod.go b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/go/kubernetes-pod.go index e640a1b4147f..7678679cebff 100644 --- a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/go/kubernetes-pod.go +++ b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/go/kubernetes-pod.go @@ -8,9 +8,8 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { - _, err := corev1.NewPod(ctx, "bar", &corev1.PodArgs{ + bar, err := corev1.NewPod(ctx, "bar", &corev1.PodArgs{ ApiVersion: pulumi.String("v1"), - Kind: pulumi.String("Pod"), Metadata: &metav1.ObjectMetaArgs{ Namespace: pulumi.String("foo"), Name: pulumi.String("bar"), @@ -38,6 +37,7 @@ func main() { if err != nil { return err } + _ := bar.Kind return nil }) } diff --git a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/kubernetes-pod.pp b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/kubernetes-pod.pp index c644257df020..4751e7b0ac89 100644 --- a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/kubernetes-pod.pp +++ b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/kubernetes-pod.pp @@ -1,6 +1,5 @@ resource bar "kubernetes:core/v1:Pod" { apiVersion = "v1" - kind = "Pod" metadata = { namespace = "foo" name = "bar" @@ -21,3 +20,6 @@ ] } } + +// Test that we can assign from a constant without type errors +kind = bar.kind diff --git a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/nodejs/kubernetes-pod.ts b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/nodejs/kubernetes-pod.ts index 1384d236a269..d728c8e80160 100644 --- a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/nodejs/kubernetes-pod.ts +++ b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/nodejs/kubernetes-pod.ts @@ -3,7 +3,6 @@ import * as kubernetes from "@pulumi/kubernetes"; const bar = new kubernetes.core.v1.Pod("bar", { apiVersion: "v1", - kind: "Pod", metadata: { namespace: "foo", name: "bar", @@ -24,3 +23,4 @@ const bar = new kubernetes.core.v1.Pod("bar", { }], }, }); +const kind = bar.kind; diff --git a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/python/kubernetes-pod.py b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/python/kubernetes-pod.py index 4117e40ace32..2fe8aa1d3d3a 100644 --- a/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/python/kubernetes-pod.py +++ b/pkg/codegen/testing/test/testdata/kubernetes-pod-pp/python/kubernetes-pod.py @@ -3,7 +3,6 @@ bar = kubernetes.core.v1.Pod("bar", api_version="v1", - kind="Pod", metadata=kubernetes.meta.v1.ObjectMetaArgs( namespace="foo", name="bar", @@ -23,3 +22,4 @@ ), )], )) +kind = bar.kind From b6d61ec35ed5ad2249b97c1654a8074981dc6daa Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Wed, 23 Nov 2022 17:37:44 +0000 Subject: [PATCH 2/2] Don't print the update plan message if using --json --- ...nt-print-update-plan-message-with-json.yaml | 4 ++++ pkg/cmd/pulumi/preview.go | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 changelog/pending/20221123--cli--dont-print-update-plan-message-with-json.yaml diff --git a/changelog/pending/20221123--cli--dont-print-update-plan-message-with-json.yaml b/changelog/pending/20221123--cli--dont-print-update-plan-message-with-json.yaml new file mode 100644 index 000000000000..7f0d6e1d298b --- /dev/null +++ b/changelog/pending/20221123--cli--dont-print-update-plan-message-with-json.yaml @@ -0,0 +1,4 @@ +changes: +- type: fix + scope: cli + description: Don't print update plan message with --json. diff --git a/pkg/cmd/pulumi/preview.go b/pkg/cmd/pulumi/preview.go index 4e6e995729f8..1b22cd3e920b 100644 --- a/pkg/cmd/pulumi/preview.go +++ b/pkg/cmd/pulumi/preview.go @@ -261,14 +261,16 @@ func newPreviewCmd() *cobra.Command { return result.FromError(err) } - // Write out message on how to use the plan - var buf bytes.Buffer - fprintf(&buf, "Update plan written to '%s'", planFilePath) - fprintf( - &buf, - "\nRun `pulumi up --plan='%s'` to constrain the update to the operations planned by this preview", - planFilePath) - cmdutil.Diag().Infof(diag.RawMessage("" /*urn*/, buf.String())) + // Write out message on how to use the plan (if not writing out --json) + if !jsonDisplay { + var buf bytes.Buffer + fprintf(&buf, "Update plan written to '%s'", planFilePath) + fprintf( + &buf, + "\nRun `pulumi up --plan='%s'` to constrain the update to the operations planned by this preview", + planFilePath) + cmdutil.Diag().Infof(diag.RawMessage("" /*urn*/, buf.String())) + } } return nil }