diff --git a/.version b/.version index 825ba76692f8..4e4047ad6b4b 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -3.73.0 +3.73.1 diff --git a/changelog/pending/20230622--programgen-go--use-raw-string-literals-for-long-multi-line-strings.yaml b/changelog/pending/20230622--programgen-go--use-raw-string-literals-for-long-multi-line-strings.yaml new file mode 100644 index 000000000000..9d636abdef3d --- /dev/null +++ b/changelog/pending/20230622--programgen-go--use-raw-string-literals-for-long-multi-line-strings.yaml @@ -0,0 +1,4 @@ +changes: +- type: fix + scope: programgen/go + description: Use raw string literals for long, multi-line strings. diff --git a/pkg/codegen/go/gen_program_expressions.go b/pkg/codegen/go/gen_program_expressions.go index b15704247b51..49ca2617a1f6 100644 --- a/pkg/codegen/go/gen_program_expressions.go +++ b/pkg/codegen/go/gen_program_expressions.go @@ -448,10 +448,10 @@ func (g *generator) genLiteralValueExpression(w io.Writer, expr *model.LiteralVa strVal := expr.Value.AsString() if isPulumiType { g.Fgenf(w, "%s(", argTypeName) - g.genStringLiteral(w, strVal) + g.genStringLiteral(w, strVal, true /* allow raw */) g.Fgenf(w, ")") } else { - g.genStringLiteral(w, strVal) + g.genStringLiteral(w, strVal, true /* allow raw */) } default: contract.Failf("unexpected opaque type in GenLiteralValueExpression: %v (%v)", destType, @@ -726,12 +726,7 @@ func (g *generator) genTemplateExpression(w io.Writer, expr *model.TemplateExpre g.Fgenf(args, ", %.v", v) } g.Fgenf(w, "fmt.Sprintf(") - str := fmtStr.String() - if canBeRaw && len(str) > 50 && strings.Count(str, "\n") > 5 { - fmt.Fprintf(w, "`%s`", str) - } else { - g.genStringLiteral(w, fmtStr.String()) - } + g.genStringLiteral(w, fmtStr.String(), canBeRaw) _, err := args.WriteTo(w) contract.AssertNoErrorf(err, "Failed to write arguments") g.Fgenf(w, ")") @@ -1113,7 +1108,22 @@ func (g *generator) rewriteThenForAllApply( return then, typeConvDecls } -func (g *generator) genStringLiteral(w io.Writer, v string) { +// Writes a Go string literal. +// The literal will be a raw string literal if allowRaw is true +// and the string is long enough to benefit from it. +func (g *generator) genStringLiteral(w io.Writer, v string, allowRaw bool) { + // If the string is longer than 50 characters, + // contains at least 5 newlines, + // and does not contain a backtick, + // use a backtick string literal for readability. + canBeRaw := len(v) > 50 && + strings.Count(v, "\n") >= 5 && + !strings.Contains(v, "`") + if allowRaw && canBeRaw { + fmt.Fprintf(w, "`%s`", v) + return + } + g.Fgen(w, "\"") g.Fgen(w, g.escapeString(v)) g.Fgen(w, "\"") diff --git a/pkg/codegen/testing/test/program_driver.go b/pkg/codegen/testing/test/program_driver.go index d1ca66413422..b557a0f2a935 100644 --- a/pkg/codegen/testing/test/program_driver.go +++ b/pkg/codegen/testing/test/program_driver.go @@ -247,6 +247,10 @@ var PulumiPulumiProgramTests = []ProgramTest{ Directory: "retain-on-delete", Description: "Generate RetainOnDelete option", }, + { + Directory: "multiline-string", + Description: "Multiline string literals", + }, { Directory: "throw-not-implemented", Description: "Function notImplemented is compiled to a runtime error at call-site", diff --git a/pkg/codegen/testing/test/testdata/multiline-string-pp/dotnet/multiline-string.cs b/pkg/codegen/testing/test/testdata/multiline-string-pp/dotnet/multiline-string.cs new file mode 100644 index 000000000000..df1600b8b664 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/multiline-string-pp/dotnet/multiline-string.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Random = Pulumi.Random; + +return await Deployment.RunAsync(() => +{ + var foo = new Random.RandomShuffle("foo", new() + { + Inputs = new[] + { + @"just one +newline", + @"foo +bar +baz +qux +quux +qux", + @"{ + ""a"": 1, + ""b"": 2, + ""c"": [ + ""foo"", + ""bar"", + ""baz"", + ""qux"", + ""quux"" + ] +} +", + }, + }); + +}); + diff --git a/pkg/codegen/testing/test/testdata/multiline-string-pp/go/multiline-string.go b/pkg/codegen/testing/test/testdata/multiline-string-pp/go/multiline-string.go new file mode 100644 index 000000000000..2fcff4c584fc --- /dev/null +++ b/pkg/codegen/testing/test/testdata/multiline-string-pp/go/multiline-string.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/pulumi/pulumi-random/sdk/v4/go/random" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := random.NewRandomShuffle(ctx, "foo", &random.RandomShuffleArgs{ + Inputs: pulumi.StringArray{ + pulumi.String("just one\nnewline"), + pulumi.String("foo\nbar\nbaz\nqux\nquux\nqux"), + pulumi.String(`{ + "a": 1, + "b": 2, + "c": [ + "foo", + "bar", + "baz", + "qux", + "quux" + ] +} +`), + }, + }) + if err != nil { + return err + } + return nil + }) +} diff --git a/pkg/codegen/testing/test/testdata/multiline-string-pp/multiline-string.pp b/pkg/codegen/testing/test/testdata/multiline-string-pp/multiline-string.pp new file mode 100644 index 000000000000..06bf70f38f11 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/multiline-string-pp/multiline-string.pp @@ -0,0 +1,19 @@ +resource foo "random:index/randomShuffle:RandomShuffle" { + inputs = [ + "just one\nnewline", + "foo\nbar\nbaz\nqux\nquux\nqux", + <<-EOT + { + "a": 1, + "b": 2, + "c": [ + "foo", + "bar", + "baz", + "qux", + "quux" + ] + } + EOT + ] +} diff --git a/pkg/codegen/testing/test/testdata/multiline-string-pp/nodejs/multiline-string.ts b/pkg/codegen/testing/test/testdata/multiline-string-pp/nodejs/multiline-string.ts new file mode 100644 index 000000000000..e16fb037c2c6 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/multiline-string-pp/nodejs/multiline-string.ts @@ -0,0 +1,25 @@ +import * as pulumi from "@pulumi/pulumi"; +import * as random from "@pulumi/random"; + +const foo = new random.RandomShuffle("foo", {inputs: [ + `just one +newline`, + `foo +bar +baz +qux +quux +qux`, + `{ + "a": 1, + "b": 2, + "c": [ + "foo", + "bar", + "baz", + "qux", + "quux" + ] +} +`, +]}); diff --git a/pkg/codegen/testing/test/testdata/multiline-string-pp/python/multiline-string.py b/pkg/codegen/testing/test/testdata/multiline-string-pp/python/multiline-string.py new file mode 100644 index 000000000000..9dcc74f3efc8 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/multiline-string-pp/python/multiline-string.py @@ -0,0 +1,25 @@ +import pulumi +import pulumi_random as random + +foo = random.RandomShuffle("foo", inputs=[ + """just one +newline""", + """foo +bar +baz +qux +quux +qux""", + """{ + "a": 1, + "b": 2, + "c": [ + "foo", + "bar", + "baz", + "qux", + "quux" + ] +} +""", +])