Skip to content

Commit

Permalink
Merge #13249 #13252
Browse files Browse the repository at this point in the history
13249: fix(codegen/go): Use raw string literals for multiline-strings r=abhinav a=abhinav

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


13252: Freeze v3.73.0 r=Zaid-Ajaj a=Zaid-Ajaj



Co-authored-by: Abhinav Gupta <abhinav@pulumi.com>
Co-authored-by: Zaid Ajaj <zaid.naom@gmail.com>
  • Loading branch information
3 people committed Jun 22, 2023
3 parents 34f524b + da184df + 92af19b commit 2f424ee
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.73.0
3.73.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
changes:
- type: fix
scope: programgen/go
description: Use raw string literals for long, multi-line strings.
28 changes: 19 additions & 9 deletions pkg/codegen/go/gen_program_expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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, ")")
Expand Down Expand Up @@ -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, "\"")
Expand Down
4 changes: 4 additions & 0 deletions pkg/codegen/testing/test/program_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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""
]
}
",
},
});
});

Original file line number Diff line number Diff line change
@@ -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
})
}
Original file line number Diff line number Diff line change
@@ -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
]
}
Original file line number Diff line number Diff line change
@@ -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"
]
}
`,
]});
Original file line number Diff line number Diff line change
@@ -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"
]
}
""",
])

0 comments on commit 2f424ee

Please sign in to comment.