From da184df24aeb010d9a397311d4b5e466f8e59f34 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Thu, 22 Jun 2023 10:43:06 -0700 Subject: [PATCH 1/2] fix(codegen/go): Use raw string literals for multiline-strings We already have logic in place to generate mutliline strings with backticks if they meet certain conditions in genTemplateExpression. However, the logic came into effect only if the string was complex enough to warrant use of `Sprintf` because the function short circuits to just printing a string literal if the string doesn't need a `Sprintf`. This changes genStringLiteral to be responsible for the decision of whether the string warrants backticks or not, retaining the prior conditions on whether the string would benefit from being split across multiple lines. Resolves #12358 --- ...-literals-for-long-multi-line-strings.yaml | 4 +++ pkg/codegen/go/gen_program_expressions.go | 28 ++++++++++----- pkg/codegen/testing/test/program_driver.go | 4 +++ .../dotnet/multiline-string.cs | 36 +++++++++++++++++++ .../go/multiline-string.go | 33 +++++++++++++++++ .../multiline-string-pp/multiline-string.pp | 19 ++++++++++ .../nodejs/multiline-string.ts | 25 +++++++++++++ .../python/multiline-string.py | 25 +++++++++++++ 8 files changed, 165 insertions(+), 9 deletions(-) create mode 100644 changelog/pending/20230622--programgen-go--use-raw-string-literals-for-long-multi-line-strings.yaml create mode 100644 pkg/codegen/testing/test/testdata/multiline-string-pp/dotnet/multiline-string.cs create mode 100644 pkg/codegen/testing/test/testdata/multiline-string-pp/go/multiline-string.go create mode 100644 pkg/codegen/testing/test/testdata/multiline-string-pp/multiline-string.pp create mode 100644 pkg/codegen/testing/test/testdata/multiline-string-pp/nodejs/multiline-string.ts create mode 100644 pkg/codegen/testing/test/testdata/multiline-string-pp/python/multiline-string.py 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" + ] +} +""", +]) From 92af19b74326533ed974eb5ed2ff1501f94fe57b Mon Sep 17 00:00:00 2001 From: Zaid Ajaj Date: Thu, 22 Jun 2023 21:00:40 +0200 Subject: [PATCH 2/2] Freeze v3.73.0 --- .version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.version b/.version index 825ba76692f8..4e4047ad6b4b 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -3.73.0 +3.73.1