blob: 61a899fff0da3979953b5f9edba1337eae094279 [file] [log] [blame]
package repo
import (
"context"
"encoding/xml"
"go.chromium.org/luci/common/errors"
"log"
"net/http"
"testplans/internal/git"
)
var (
// Name of the root XML file to seek in manifest-internal.
rootXml = "snapshot.xml"
)
// Manifest is a top-level Repo definition file.
type Manifest struct {
Includes []Include `xml:"include"`
Projects []Project `xml:"project"`
}
// Project is an element of a manifest containing a Gerrit project to source path definition.
type Project struct {
Path string `xml:"path,attr"`
Name string `xml:"name,attr"`
}
// Include is a manifest element that imports another manifest file.
type Include struct {
Name string `xml:"name,attr"`
}
func fetchManifestRecursive(authedClient *http.Client, ctx context.Context, manifestCommit string, file string) (map[string]*Manifest, error) {
results := make(map[string]*Manifest)
log.Printf("Fetching manifest file %s at revision '%s'", file, manifestCommit)
files, err := git.FetchFilesFromGitiles(
authedClient,
ctx,
"chrome-internal.googlesource.com",
"chromeos/manifest-internal",
manifestCommit,
[]string{file})
if err != nil {
return nil, errors.Annotate(err, "failed to fetch %s", file).Err()
}
manifest := &Manifest{}
if err = xml.Unmarshal([]byte((*files)[file]), manifest); err != nil {
return nil, errors.Annotate(err, "failed to unmarshal %s", file).Err()
}
results[file] = manifest
// Recursively fetch manifests listed in "include" elements.
for _, incl := range manifest.Includes {
subResults, err := fetchManifestRecursive(authedClient, ctx, manifestCommit, incl.Name)
if err != nil {
return nil, err
}
for k, v := range subResults {
results[k] = v
}
}
return results, nil
}
// GetRepoToSourceRootFromManifests constructs a Gerrit project to path mapping by fetching manifest
// XML files from Gitiles.
func GetRepoToSourceRootFromManifests(authedClient *http.Client, ctx context.Context, manifestCommit string) (map[string]string, error) {
manifests, err := fetchManifestRecursive(authedClient, ctx, manifestCommit, rootXml)
if err != nil {
return nil, err
}
repoToSourceRoot := make(map[string]string)
for _, m := range manifests {
for _, p := range m.Projects {
repoToSourceRoot[p.Name] = p.Path
}
}
log.Printf("Found %d repo to source root mappings from manifest files", len(repoToSourceRoot))
return repoToSourceRoot, nil
}