blob: 294c43c2167d9343ffe850994d059192ee6b42c1 [file] [log] [blame]
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"flag"
"fmt"
"log"
"os"
"github.com/google/slothfs/cookie"
"github.com/google/slothfs/gitiles"
"github.com/google/slothfs/manifest"
git "github.com/libgit2/git2go"
)
func main() {
gitilesURL := flag.String("gitiles", "", "URL for gitiles")
branch := flag.String("branch", "master", "branch to use for manifest")
repo := flag.String("repo", "platform/manifest", "manifest repository")
cookieJarPath := flag.String("cookies", "", "path to cURL-style cookie jar file.")
agent := flag.String("agent", "slothfs-expand", "gitiles User-Agent string to use.")
flag.Parse()
if *gitilesURL == "" {
log.Fatal("must set --gitiles")
}
opts := gitiles.Options{
UserAgent: *agent,
}
if *cookieJarPath != "" {
var err error
opts.CookieJar, err = cookie.NewJar(*cookieJarPath)
if err != nil {
log.Fatal(err)
}
}
// SustainedQPS is a little high, but since this is a one-shot
// program let's try to get away with it.
service, err := gitiles.NewService(*gitilesURL, opts)
if err != nil {
log.Fatalf("NewService: %v", err)
}
mf, err := fetchManifest(service, *repo, *branch)
if err != nil {
log.Fatalf("fetchManifest: %v", err)
}
mf.Filter()
if err := derefManifest(service, *repo, mf); err != nil {
log.Fatalf("derefManifest: %v", err)
}
xml, err := mf.MarshalXML()
if err != nil {
log.Fatalf("MarshalXML: %v", err)
}
os.Stdout.Write(xml)
}
func fetchManifest(service *gitiles.Service, repo, branch string) (*manifest.Manifest, error) {
project := service.NewRepoService(repo)
// When checking this out, it's called "manifest.xml". Go figure.
c, err := project.GetBlob(branch, "default.xml")
if err != nil {
return nil, err
}
mf, err := manifest.Parse(c)
if err != nil {
return nil, err
}
return mf, nil
}
func derefManifest(service *gitiles.Service, manifestRepo string, mf *manifest.Manifest) error {
branchSet := map[string]struct{}{}
var todoProjects []int
for i, p := range mf.Project {
rev := mf.ProjectRevision(&p)
if _, err := git.NewOid(rev); err == nil {
continue
}
branchSet[rev] = struct{}{}
todoProjects = append(todoProjects, i)
}
var branches []string
for k := range branchSet {
branches = append(branches, k)
}
repos, err := service.List(branches)
if err != nil {
return err
}
for _, i := range todoProjects {
p := &mf.Project[i]
proj, ok := repos[p.Name]
if !ok {
return fmt.Errorf("server list doesn't mention repo %s", p.Name)
}
p.CloneURL = proj.CloneURL
branch := mf.ProjectRevision(p)
commit, ok := proj.Branches[branch]
if !ok {
return fmt.Errorf("branch %q for repo %s not returned.", branch, p.Name)
}
p.Revision = commit
}
return nil
}