Merge changes I9a08bbc0,I049d1bb9

* changes:
  Add validations to RuleBuilderCommand
  Fix bug in RuleBuilderCommand.OrderOnlys
This commit is contained in:
Treehugger Robot 2021-04-21 23:06:33 +00:00 committed by Gerrit Code Review
commit 752d63cd83
2 changed files with 89 additions and 21 deletions

View file

@ -283,6 +283,28 @@ func (r *RuleBuilder) OrderOnlys() Paths {
return orderOnlyList return orderOnlyList
} }
// Validations returns the list of paths that were passed to RuleBuilderCommand.Validation or
// RuleBuilderCommand.Validations. The list is sorted and duplicates removed.
func (r *RuleBuilder) Validations() Paths {
validations := make(map[string]Path)
for _, c := range r.commands {
for _, validation := range c.validations {
validations[validation.String()] = validation
}
}
var validationList Paths
for _, validation := range validations {
validationList = append(validationList, validation)
}
sort.Slice(validationList, func(i, j int) bool {
return validationList[i].String() < validationList[j].String()
})
return validationList
}
func (r *RuleBuilder) outputSet() map[string]WritablePath { func (r *RuleBuilder) outputSet() map[string]WritablePath {
outputs := make(map[string]WritablePath) outputs := make(map[string]WritablePath)
for _, c := range r.commands { for _, c := range r.commands {
@ -460,7 +482,6 @@ func (r *RuleBuilder) Build(name string, desc string) {
r.ctx.Build(pctx, BuildParams{ r.ctx.Build(pctx, BuildParams{
Rule: ErrorRule, Rule: ErrorRule,
Outputs: r.Outputs(), Outputs: r.Outputs(),
OrderOnly: r.OrderOnlys(),
Description: desc, Description: desc,
Args: map[string]string{ Args: map[string]string{
"error": "missing dependencies: " + strings.Join(r.missingDeps, ", "), "error": "missing dependencies: " + strings.Join(r.missingDeps, ", "),
@ -707,6 +728,8 @@ func (r *RuleBuilder) Build(name string, desc string) {
}), }),
Inputs: rspFileInputs, Inputs: rspFileInputs,
Implicits: inputs, Implicits: inputs,
OrderOnly: r.OrderOnlys(),
Validations: r.Validations(),
Output: output, Output: output,
ImplicitOutputs: implicitOutputs, ImplicitOutputs: implicitOutputs,
SymlinkOutputs: r.SymlinkOutputs(), SymlinkOutputs: r.SymlinkOutputs(),
@ -727,6 +750,7 @@ type RuleBuilderCommand struct {
inputs Paths inputs Paths
implicits Paths implicits Paths
orderOnlys Paths orderOnlys Paths
validations Paths
outputs WritablePaths outputs WritablePaths
symlinkOutputs WritablePaths symlinkOutputs WritablePaths
depFiles WritablePaths depFiles WritablePaths
@ -1061,6 +1085,20 @@ func (c *RuleBuilderCommand) OrderOnlys(paths Paths) *RuleBuilderCommand {
return c return c
} }
// Validation adds the specified input path to the validation dependencies by
// RuleBuilder.Validations without modifying the command line.
func (c *RuleBuilderCommand) Validation(path Path) *RuleBuilderCommand {
c.validations = append(c.validations, path)
return c
}
// Validations adds the specified input paths to the validation dependencies by
// RuleBuilder.Validations without modifying the command line.
func (c *RuleBuilderCommand) Validations(paths Paths) *RuleBuilderCommand {
c.validations = append(c.validations, paths...)
return c
}
// Output adds the specified output path to the command line. The path will also be added to the outputs returned by // Output adds the specified output path to the command line. The path will also be added to the outputs returned by
// RuleBuilder.Outputs. // RuleBuilder.Outputs.
func (c *RuleBuilderCommand) Output(path WritablePath) *RuleBuilderCommand { func (c *RuleBuilderCommand) Output(path WritablePath) *RuleBuilderCommand {

View file

@ -15,6 +15,8 @@
package android package android
import ( import (
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -320,6 +322,7 @@ func TestRuleBuilder(t *testing.T) {
Input(PathForSource(ctx, "Input")). Input(PathForSource(ctx, "Input")).
Output(PathForOutput(ctx, "module/Output")). Output(PathForOutput(ctx, "module/Output")).
OrderOnly(PathForSource(ctx, "OrderOnly")). OrderOnly(PathForSource(ctx, "OrderOnly")).
Validation(PathForSource(ctx, "Validation")).
SymlinkOutput(PathForOutput(ctx, "module/SymlinkOutput")). SymlinkOutput(PathForOutput(ctx, "module/SymlinkOutput")).
ImplicitSymlinkOutput(PathForOutput(ctx, "module/ImplicitSymlinkOutput")). ImplicitSymlinkOutput(PathForOutput(ctx, "module/ImplicitSymlinkOutput")).
Text("Text"). Text("Text").
@ -331,6 +334,7 @@ func TestRuleBuilder(t *testing.T) {
Input(PathForSource(ctx, "input2")). Input(PathForSource(ctx, "input2")).
Output(PathForOutput(ctx, "module/output2")). Output(PathForOutput(ctx, "module/output2")).
OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})). OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})).
Validations(PathsForSource(ctx, []string{"Validations"})).
Tool(PathForSource(ctx, "tool2")) Tool(PathForSource(ctx, "tool2"))
// Test updates to the first command after the second command has been started // Test updates to the first command after the second command has been started
@ -358,6 +362,7 @@ func TestRuleBuilder(t *testing.T) {
"module/DepFile", "module/depfile", "module/ImplicitDepFile", "module/depfile2"}) "module/DepFile", "module/depfile", "module/ImplicitDepFile", "module/depfile2"})
wantTools := PathsForSource(ctx, []string{"Tool", "tool2"}) wantTools := PathsForSource(ctx, []string{"Tool", "tool2"})
wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"}) wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"})
wantValidations := PathsForSource(ctx, []string{"Validation", "Validations"})
wantSymlinkOutputs := PathsForOutput(ctx, []string{ wantSymlinkOutputs := PathsForOutput(ctx, []string{
"module/ImplicitSymlinkOutput", "module/SymlinkOutput"}) "module/ImplicitSymlinkOutput", "module/SymlinkOutput"})
@ -385,6 +390,7 @@ func TestRuleBuilder(t *testing.T) {
AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations())
AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
}) })
@ -414,6 +420,7 @@ func TestRuleBuilder(t *testing.T) {
AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations())
AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
}) })
@ -443,6 +450,7 @@ func TestRuleBuilder(t *testing.T) {
AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations())
AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
}) })
@ -472,6 +480,7 @@ func TestRuleBuilder(t *testing.T) {
AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles())
AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools())
AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys())
AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations())
AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String())
}) })
@ -497,6 +506,9 @@ type testRuleBuilderModule struct {
func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) { func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
in := PathsForSource(ctx, t.properties.Srcs) in := PathsForSource(ctx, t.properties.Srcs)
implicit := PathForSource(ctx, "implicit")
orderOnly := PathForSource(ctx, "orderonly")
validation := PathForSource(ctx, "validation")
out := PathForModuleOut(ctx, "gen", ctx.ModuleName()) out := PathForModuleOut(ctx, "gen", ctx.ModuleName())
outDep := PathForModuleOut(ctx, "gen", ctx.ModuleName()+".d") outDep := PathForModuleOut(ctx, "gen", ctx.ModuleName()+".d")
outDir := PathForModuleOut(ctx, "gen") outDir := PathForModuleOut(ctx, "gen")
@ -506,9 +518,9 @@ func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForModuleOut(ctx, "sbox.textproto") manifestPath := PathForModuleOut(ctx, "sbox.textproto")
testRuleBuilder_Build(ctx, in, out, outDep, outDir, manifestPath, t.properties.Restat, testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
t.properties.Sbox, t.properties.Sbox_inputs, rspFile, rspFileContents, manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs,
rspFile2, rspFileContents2) rspFile, rspFileContents, rspFile2, rspFileContents2)
} }
type testRuleBuilderSingleton struct{} type testRuleBuilderSingleton struct{}
@ -518,7 +530,10 @@ func testRuleBuilderSingletonFactory() Singleton {
} }
func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) { func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
in := PathForSource(ctx, "bar") in := PathsForSource(ctx, []string{"in"})
implicit := PathForSource(ctx, "implicit")
orderOnly := PathForSource(ctx, "orderonly")
validation := PathForSource(ctx, "validation")
out := PathForOutput(ctx, "singleton/gen/baz") out := PathForOutput(ctx, "singleton/gen/baz")
outDep := PathForOutput(ctx, "singleton/gen/baz.d") outDep := PathForOutput(ctx, "singleton/gen/baz.d")
outDir := PathForOutput(ctx, "singleton/gen") outDir := PathForOutput(ctx, "singleton/gen")
@ -527,11 +542,14 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
rspFileContents := PathsForSource(ctx, []string{"rsp_in"}) rspFileContents := PathsForSource(ctx, []string{"rsp_in"})
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForOutput(ctx, "singleton/sbox.textproto") manifestPath := PathForOutput(ctx, "singleton/sbox.textproto")
testRuleBuilder_Build(ctx, Paths{in}, out, outDep, outDir, manifestPath, true, false, false,
testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
manifestPath, true, false, false,
rspFile, rspFileContents, rspFile2, rspFileContents2) rspFile, rspFileContents, rspFile2, rspFileContents2)
} }
func testRuleBuilder_Build(ctx BuilderContext, in Paths, out, outDep, outDir, manifestPath WritablePath, func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path,
out, outDep, outDir, manifestPath WritablePath,
restat, sbox, sboxInputs bool, restat, sbox, sboxInputs bool,
rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) { rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) {
@ -547,6 +565,9 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, out, outDep, outDir, ma
rule.Command(). rule.Command().
Tool(PathForSource(ctx, "cp")). Tool(PathForSource(ctx, "cp")).
Inputs(in). Inputs(in).
Implicit(implicit).
OrderOnly(orderOnly).
Validation(validation).
Output(out). Output(out).
ImplicitDepFile(outDep). ImplicitDepFile(outDep).
FlagWithRspFileInputList("@", rspFile, rspFileContents). FlagWithRspFileInputList("@", rspFile, rspFileContents).
@ -566,24 +587,24 @@ var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx Registration
func TestRuleBuilder_Build(t *testing.T) { func TestRuleBuilder_Build(t *testing.T) {
fs := MockFS{ fs := MockFS{
"bar": nil, "in": nil,
"cp": nil, "cp": nil,
} }
bp := ` bp := `
rule_builder_test { rule_builder_test {
name: "foo", name: "foo",
srcs: ["bar"], srcs: ["in"],
restat: true, restat: true,
} }
rule_builder_test { rule_builder_test {
name: "foo_sbox", name: "foo_sbox",
srcs: ["bar"], srcs: ["in"],
sbox: true, sbox: true,
} }
rule_builder_test { rule_builder_test {
name: "foo_sbox_inputs", name: "foo_sbox_inputs",
srcs: ["bar"], srcs: ["in"],
sbox: true, sbox: true,
sbox_inputs: true, sbox_inputs: true,
} }
@ -614,11 +635,17 @@ func TestRuleBuilder_Build(t *testing.T) {
wantInputs := []string{"rsp_in"} wantInputs := []string{"rsp_in"}
AssertArrayString(t, "Inputs", wantInputs, params.Inputs.Strings()) AssertArrayString(t, "Inputs", wantInputs, params.Inputs.Strings())
wantImplicits := append([]string{"bar"}, extraImplicits...) wantImplicits := append([]string{"implicit", "in"}, extraImplicits...)
// The second rsp file and the files listed in it should be in implicits // The second rsp file and the files listed in it should be in implicits
wantImplicits = append(wantImplicits, "rsp_in2", wantRspFile2) wantImplicits = append(wantImplicits, "rsp_in2", wantRspFile2)
AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits) AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits)
wantOrderOnlys := []string{"orderonly"}
AssertPathsRelativeToTopEquals(t, "OrderOnly", wantOrderOnlys, params.OrderOnly)
wantValidations := []string{"validation"}
AssertPathsRelativeToTopEquals(t, "Validations", wantValidations, params.Validations)
wantRspFileContent := "$in" wantRspFileContent := "$in"
AssertStringEquals(t, "RspfileContent", wantRspFileContent, params.RuleParams.RspfileContent) AssertStringEquals(t, "RspfileContent", wantRspFileContent, params.RuleParams.RspfileContent)
@ -646,7 +673,7 @@ func TestRuleBuilder_Build(t *testing.T) {
rspFile2 := "out/soong/.intermediates/foo/rsp2" rspFile2 := "out/soong/.intermediates/foo/rsp2"
module := result.ModuleForTests("foo", "") module := result.ModuleForTests("foo", "")
check(t, module.Rule("rule"), module.Output(rspFile2), check(t, module.Rule("rule"), module.Output(rspFile2),
"cp bar "+outFile+" @"+rspFile+" @"+rspFile2, "cp in "+outFile+" @"+rspFile+" @"+rspFile2,
outFile, outFile+".d", rspFile, rspFile2, true, nil, nil) outFile, outFile+".d", rspFile, rspFile2, true, nil, nil)
}) })
t.Run("sbox", func(t *testing.T) { t.Run("sbox", func(t *testing.T) {
@ -688,7 +715,7 @@ func TestRuleBuilder_Build(t *testing.T) {
rspFile2 := filepath.Join("out/soong/singleton/rsp2") rspFile2 := filepath.Join("out/soong/singleton/rsp2")
singleton := result.SingletonForTests("rule_builder_test") singleton := result.SingletonForTests("rule_builder_test")
check(t, singleton.Rule("rule"), singleton.Output(rspFile2), check(t, singleton.Rule("rule"), singleton.Output(rspFile2),
"cp bar "+outFile+" @"+rspFile+" @"+rspFile2, "cp in "+outFile+" @"+rspFile+" @"+rspFile2,
outFile, outFile+".d", rspFile, rspFile2, true, nil, nil) outFile, outFile+".d", rspFile, rspFile2, true, nil, nil)
}) })
} }
@ -702,6 +729,11 @@ func TestRuleBuilderHashInputs(t *testing.T) {
// the list of inputs changes because the command line or a dependency // the list of inputs changes because the command line or a dependency
// changes. // changes.
hashOf := func(s string) string {
sum := sha256.Sum256([]byte(s))
return hex.EncodeToString(sum[:])
}
bp := ` bp := `
rule_builder_test { rule_builder_test {
name: "hash0", name: "hash0",
@ -727,14 +759,12 @@ func TestRuleBuilderHashInputs(t *testing.T) {
expectedHash string expectedHash string
}{ }{
{ {
name: "hash0", name: "hash0",
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum expectedHash: hashOf("implicit\nin1.txt\nin2.txt"),
expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
}, },
{ {
name: "hash1", name: "hash1",
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum expectedHash: hashOf("implicit\nin1.txt\nin2.txt\nin3.txt"),
expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
}, },
} }