Add rspfile support to RuleBuilder
Allow RuleBuilderCommands to use an rspfile with FlagWithRspFileInputList.
This requires being more careful with ninja escaping, as the rspfile
will be $out.rsp, and the value for $out may not be known yet so it
must be inserted as a ninja variable that must not be escaped.
Test: rule_builder_test.go
Change-Id: Ifa91e24a0bb8f0ceeb5c9bfa5689be2a4ff3b9cd
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index cfbc2ab..6eba4f1 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -38,6 +38,7 @@
"ls": nil,
"turbine": nil,
"java": nil,
+ "javac": nil,
})
}
@@ -235,6 +236,34 @@
// ls --sort=time,size
}
+func ExampleRuleBuilderCommand_FlagWithRspFileInputList() {
+ ctx := pathContext()
+ fmt.Println(NewRuleBuilder().Command().
+ Tool(PathForSource(ctx, "javac")).
+ FlagWithRspFileInputList("@", PathsForTesting("a.java", "b.java")).
+ NinjaEscapedString())
+ // Output:
+ // javac @$out.rsp
+}
+
+func ExampleRuleBuilderCommand_String() {
+ fmt.Println(NewRuleBuilder().Command().
+ Text("FOO=foo").
+ Text("echo $FOO").
+ String())
+ // Output:
+ // FOO=foo echo $FOO
+}
+
+func ExampleRuleBuilderCommand_NinjaEscapedString() {
+ fmt.Println(NewRuleBuilder().Command().
+ Text("FOO=foo").
+ Text("echo $FOO").
+ NinjaEscapedString())
+ // Output:
+ // FOO=foo echo $$FOO
+}
+
func TestRuleBuilder(t *testing.T) {
fs := map[string][]byte{
"dep_fixer": nil,
@@ -503,3 +532,77 @@
"cp bar "+outFile, outFile, outFile+".d", true, nil)
})
}
+
+func Test_ninjaEscapeExceptForSpans(t *testing.T) {
+ type args struct {
+ s string
+ spans [][2]int
+ }
+ tests := []struct {
+ name string
+ args args
+ want string
+ }{
+ {
+ name: "empty",
+ args: args{
+ s: "",
+ },
+ want: "",
+ },
+ {
+ name: "unescape none",
+ args: args{
+ s: "$abc",
+ },
+ want: "$$abc",
+ },
+ {
+ name: "unescape all",
+ args: args{
+ s: "$abc",
+ spans: [][2]int{{0, 4}},
+ },
+ want: "$abc",
+ },
+ {
+ name: "unescape first",
+ args: args{
+ s: "$abc$",
+ spans: [][2]int{{0, 1}},
+ },
+ want: "$abc$$",
+ },
+ {
+ name: "unescape last",
+ args: args{
+ s: "$abc$",
+ spans: [][2]int{{4, 5}},
+ },
+ want: "$$abc$",
+ },
+ {
+ name: "unescape middle",
+ args: args{
+ s: "$a$b$c$",
+ spans: [][2]int{{2, 5}},
+ },
+ want: "$$a$b$c$$",
+ },
+ {
+ name: "unescape multiple",
+ args: args{
+ s: "$a$b$c$",
+ spans: [][2]int{{2, 3}, {4, 5}},
+ },
+ want: "$$a$b$c$$",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := ninjaEscapeExceptForSpans(tt.args.s, tt.args.spans); got != tt.want {
+ t.Errorf("ninjaEscapeExceptForSpans() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}