diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 786ce1e3ed45..b0c61761bf78 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,13 +1,18 @@ ### Improvements -- [area/cli] - Implement `pulumi stack unselect` [#9179](https://github.com/pulumi/pulumi/pull/9179) +- [area/cli] - Implement `pulumi stack unselect`. + [#9179](https://github.com/pulumi/pulumi/pull/9179) + - [language/dotnet] - Updated Pulumi dotnet packages to use grpc-dotnet instead of grpc. - [#9149](https://github.com/pulumi/pulumi/pull/9149) + [#9149](https://github.com/pulumi/pulumi/pull/9149) - [cli/config] Rename the `config` property in `Pulumi.yaml` to `stackConfigDir`. The `config` key will continue to be supported. [#9145](https://github.com/pulumi/pulumi/pull/9145) ### Bug Fixes - [sdk/nodejs] - Fix uncaught error "ENOENT: no such file or directory" when an error occurs during the stack up +- [sdk/nodejs] - Fix uncaught error "ENOENT: no such file or directory" when an error occurs during the stack up. [#9065](https://github.com/pulumi/pulumi/issues/9065) + +- [sdk/go] - Fix a panic in `pulumi.All` when using pointer inputs. + [#9197](https://github.com/pulumi/pulumi/issues/9197) \ No newline at end of file diff --git a/sdk/go/pulumi/types.go b/sdk/go/pulumi/types.go index 264d0b700b5c..c28f95f9914d 100644 --- a/sdk/go/pulumi/types.go +++ b/sdk/go/pulumi/types.go @@ -718,10 +718,18 @@ func awaitInputs(ctx context.Context, v, resolved reflect.Value) (bool, bool, [] } else { // Handle pointer inputs. if v.Kind() == reflect.Ptr { - v, valueType = v.Elem(), valueType.Elem() - - resolved.Set(reflect.New(resolved.Type().Elem())) - resolved = resolved.Elem() + v = v.Elem() + valueType = valueType.Elem() + if resolved.Type() != anyType { + // resolved should be some pointer type U such that value Type is convertable to U. + resolved.Set(reflect.New(resolved.Type().Elem())) + resolved = resolved.Elem() + } else { + // Allocate storage for a pointer and assign that to resolved, then continue below with resolved set to the inner value of the pointer just allocated + ptr := reflect.New(valueType) + resolved.Set(ptr) + resolved = ptr.Elem() + } } } } diff --git a/sdk/go/pulumi/types_test.go b/sdk/go/pulumi/types_test.go index c59151a3bc06..5f5e74d5ef92 100644 --- a/sdk/go/pulumi/types_test.go +++ b/sdk/go/pulumi/types_test.go @@ -718,3 +718,61 @@ func TestRegisterInputType(t *testing.T) { RegisterInputType(reflect.TypeOf((*FooInput)(nil)).Elem(), FooArgs{}) }) } + +func TestAll(t *testing.T) { + t.Parallel() + + aStringInput := String("Test") + aStringPtrInput := StringPtr("Hello World") + aStringOutput := String("Frob").ToStringOutput() + + a := All(aStringInput).ApplyT(func(args []interface{}) (string, error) { + a := args[0].(string) + return a, nil + }).(StringOutput) + + v, known, secret, deps, err := await(a) + assert.Equal(t, "Test", v) + assert.True(t, known) + assert.False(t, secret) + assert.ElementsMatch(t, []Resource{}, deps) + assert.NoError(t, err) + + a = All(aStringPtrInput).ApplyT(func(args []interface{}) (string, error) { + a := args[0].(*string) + return *a, nil + }).(StringOutput) + + v, known, secret, deps, err = await(a) + assert.Equal(t, "Hello World", v) + assert.True(t, known) + assert.False(t, secret) + assert.ElementsMatch(t, []Resource{}, deps) + assert.NoError(t, err) + + a = All(aStringOutput).ApplyT(func(args []interface{}) (string, error) { + a := args[0].(string) + return a, nil + }).(StringOutput) + + v, known, secret, deps, err = await(a) + assert.Equal(t, "Frob", v) + assert.True(t, known) + assert.False(t, secret) + assert.ElementsMatch(t, []Resource{}, deps) + assert.NoError(t, err) + + a = All(aStringInput, aStringPtrInput, aStringOutput).ApplyT(func(args []interface{}) (string, error) { + a := args[0].(string) + b := args[1].(*string) + c := args[2].(string) + return fmt.Sprintf("%s: %s: %s", a, *b, c), nil + }).(StringOutput) + + v, known, secret, deps, err = await(a) + assert.Equal(t, "Test: Hello World: Frob", v) + assert.True(t, known) + assert.False(t, secret) + assert.ElementsMatch(t, []Resource{}, deps) + assert.NoError(t, err) +}