summaryrefslogtreecommitdiff
path: root/bazel/aquery.go
diff options
context:
space:
mode:
Diffstat (limited to 'bazel/aquery.go')
-rw-r--r--bazel/aquery.go51
1 files changed, 42 insertions, 9 deletions
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 69d4fde14..404be8ce0 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -16,6 +16,8 @@ package bazel
import (
"encoding/json"
+ "fmt"
+ "path/filepath"
"strings"
"github.com/google/blueprint/proptools"
@@ -24,8 +26,14 @@ import (
// artifact contains relevant portions of Bazel's aquery proto, Artifact.
// Represents a single artifact, whether it's a source file or a derived output file.
type artifact struct {
- Id string
- ExecPath string
+ Id int
+ PathFragmentId int
+}
+
+type pathFragment struct {
+ Id int
+ Label string
+ ParentId int
}
// KeyValuePair represents Bazel's aquery proto, KeyValuePair.
@@ -38,9 +46,9 @@ type KeyValuePair struct {
// Represents a data structure containing one or more files. Depsets in Bazel are an efficient
// data structure for storing large numbers of file paths.
type depSetOfFiles struct {
- Id string
+ Id int
// TODO(cparsons): Handle non-flat depsets.
- DirectArtifactIds []string
+ DirectArtifactIds []int
}
// action contains relevant portions of Bazel's aquery proto, Action.
@@ -48,9 +56,9 @@ type depSetOfFiles struct {
type action struct {
Arguments []string
EnvironmentVariables []KeyValuePair
- InputDepSetIds []string
+ InputDepSetIds []int
Mnemonic string
- OutputIds []string
+ OutputIds []int
}
// actionGraphContainer contains relevant portions of Bazel's aquery proto, ActionGraphContainer.
@@ -59,6 +67,7 @@ type actionGraphContainer struct {
Artifacts []artifact
Actions []action
DepSetOfFiles []depSetOfFiles
+ PathFragments []pathFragment
}
// BuildStatement contains information to register a build statement corresponding (one to one)
@@ -80,11 +89,20 @@ func AqueryBuildStatements(aqueryJsonProto []byte) []BuildStatement {
var aqueryResult actionGraphContainer
json.Unmarshal(aqueryJsonProto, &aqueryResult)
- artifactIdToPath := map[string]string{}
+ pathFragments := map[int]pathFragment{}
+ for _, pathFragment := range aqueryResult.PathFragments {
+ pathFragments[pathFragment.Id] = pathFragment
+ }
+ artifactIdToPath := map[int]string{}
for _, artifact := range aqueryResult.Artifacts {
- artifactIdToPath[artifact.Id] = artifact.ExecPath
+ artifactPath, err := expandPathFragment(artifact.PathFragmentId, pathFragments)
+ if err != nil {
+ // TODO(cparsons): Better error handling.
+ panic(err.Error())
+ }
+ artifactIdToPath[artifact.Id] = artifactPath
}
- depsetIdToArtifactIds := map[string][]string{}
+ depsetIdToArtifactIds := map[int][]int{}
for _, depset := range aqueryResult.DepSetOfFiles {
depsetIdToArtifactIds[depset.Id] = depset.DirectArtifactIds
}
@@ -114,3 +132,18 @@ func AqueryBuildStatements(aqueryJsonProto []byte) []BuildStatement {
return buildStatements
}
+
+func expandPathFragment(id int, pathFragmentsMap map[int]pathFragment) (string, error) {
+ labels := []string{}
+ currId := id
+ // Only positive IDs are valid for path fragments. An ID of zero indicates a terminal node.
+ for currId > 0 {
+ currFragment, ok := pathFragmentsMap[currId]
+ if !ok {
+ return "", fmt.Errorf("undefined path fragment id '%s'", currId)
+ }
+ labels = append([]string{currFragment.Label}, labels...)
+ currId = currFragment.ParentId
+ }
+ return filepath.Join(labels...), nil
+}