Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit affbb60b authored by Chris Parsons's avatar Chris Parsons
Browse files

Process v2 bazel analysis protos in aquery responses

Test: USE_BAZEL_ANALYSIS=1 m libc
Change-Id: I549e136a2706aa555d5a2cf0aa38739e80791826
parent 1f8c2729
Loading
Loading
Loading
Loading
+42 −9
Original line number Diff line number Diff line
@@ -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
}