v.io/jiri: refactor to move DataDir out of jiri, part 1.
jiri project poll is moved into jiri-test poll
jiri contributors is moved into an external command jiri-contributors
Change-Id: I9a63717cb6cc41b70cf8af3eeae95aecd363fefc
diff --git a/jiri-contributors/contrib.go b/jiri-contributors/contrib.go
new file mode 100644
index 0000000..9ac4331
--- /dev/null
+++ b/jiri-contributors/contrib.go
@@ -0,0 +1,239 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The following enables go generate to generate the doc.go file.
+//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go -env=CMDLINE_PREFIX=jiri .
+
+package main
+
+import (
+ "encoding/xml"
+ "fmt"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+
+ "v.io/jiri"
+ "v.io/jiri/collect"
+ "v.io/jiri/gitutil"
+ "v.io/jiri/project"
+ "v.io/jiri/tool"
+ "v.io/x/devtools/tooldata"
+ "v.io/x/lib/cmdline"
+ "v.io/x/lib/set"
+)
+
+const (
+ aliasesFileName = "aliases.v1.xml"
+)
+
+var (
+ countFlag bool
+ aliasesFlag string
+)
+
+func init() {
+ cmdContributorsList.Flags.BoolVar(&countFlag, "n", false, "Show number of contributions.")
+ cmdContributorsList.Flags.StringVar(&aliasesFlag, "aliases", "", "Path to the aliases file.")
+}
+
+// cmdContributors represents the "jiri contributors" command.
+var cmdContributors = &cmdline.Command{
+ Name: "contributors",
+ Short: "List project contributors",
+ Long: "List project contributors.",
+ Children: []*cmdline.Command{cmdContributorsList},
+}
+
+// cmdContributorsList represents the "jiri contributors list" command.
+var cmdContributorsList = &cmdline.Command{
+ Runner: jiri.RunnerFunc(runContributorsList),
+ Name: "contributors",
+ Short: "List project contributors",
+ Long: `
+Lists project contributors. Projects to consider can be specified as
+an argument. If no projects are specified, all projects in the current
+manifest are considered by default.
+`,
+ ArgsName: "<projects>",
+ ArgsLong: "<projects> is a list of projects to consider.",
+}
+
+type contributor struct {
+ count int
+ email string
+ name string
+}
+
+var (
+ contributorRE = regexp.MustCompile("^(.*)\t(.*) <(.*)>$")
+)
+
+type aliasesSchema struct {
+ XMLName xml.Name `xml:"aliases"`
+ Names []nameSchema `xml:"name"`
+ Emails []emailSchema `xml:"email"`
+}
+
+type nameSchema struct {
+ Canonical string `xml:"canonical"`
+ Aliases []string `xml:"alias"`
+}
+
+type emailSchema struct {
+ Canonical string `xml:"canonical"`
+ Aliases []string `xml:"alias"`
+}
+
+type aliasMaps struct {
+ emails map[string]string
+ names map[string]string
+}
+
+func canonicalize(aliases *aliasMaps, email, name string) (string, string) {
+ canonicalEmail, canonicalName := email, name
+ if email, ok := aliases.emails[email]; ok {
+ canonicalEmail = email
+ }
+ if name, ok := aliases.names[name]; ok {
+ canonicalName = name
+ }
+ return canonicalEmail, canonicalName
+}
+
+func loadAliases(jirix *jiri.X) (*aliasMaps, error) {
+ aliasesFile := aliasesFlag
+ if aliasesFile == "" {
+ dataDir, err := tooldata.DataDirPath(jirix, tool.Name)
+ if err != nil {
+ return nil, err
+ }
+ aliasesFile = filepath.Join(dataDir, aliasesFileName)
+ }
+ bytes, err := jirix.NewSeq().ReadFile(aliasesFile)
+ if err != nil {
+ return nil, err
+ }
+ var data aliasesSchema
+ if err := xml.Unmarshal(bytes, &data); err != nil {
+ return nil, fmt.Errorf("Unmarshal(%v) failed: %v", string(bytes), err)
+ }
+ aliases := &aliasMaps{
+ emails: map[string]string{},
+ names: map[string]string{},
+ }
+ for _, email := range data.Emails {
+ for _, alias := range email.Aliases {
+ aliases.emails[alias] = email.Canonical
+ }
+ }
+ for _, name := range data.Names {
+ for _, alias := range name.Aliases {
+ aliases.names[alias] = name.Canonical
+ }
+ }
+ return aliases, nil
+}
+
+func runContributorsList(jirix *jiri.X, args []string) error {
+ localProjects, err := project.LocalProjects(jirix, project.FastScan)
+ if err != nil {
+ return err
+ }
+ projectNames := map[string]struct{}{}
+ if len(args) != 0 {
+ projectNames = set.String.FromSlice(args)
+ } else {
+ for _, p := range localProjects {
+ projectNames[p.Name] = struct{}{}
+ }
+ }
+
+ aliases, err := loadAliases(jirix)
+ if err != nil {
+ return err
+ }
+ contributors := map[string]*contributor{}
+ for name, _ := range projectNames {
+ projects := localProjects.Find(name)
+ if len(projects) == 0 {
+ continue
+ }
+
+ for _, project := range projects {
+ if err := jirix.NewSeq().Chdir(project.Path).Done(); err != nil {
+ return err
+ }
+ switch project.Protocol {
+ case "git":
+ lines, err := listCommitters(jirix)
+ if err != nil {
+ return err
+ }
+ for _, line := range lines {
+ matches := contributorRE.FindStringSubmatch(line)
+ if got, want := len(matches), 4; got != want {
+ return fmt.Errorf("unexpected length of %v: got %v, want %v", matches, got, want)
+ }
+ count, err := strconv.Atoi(strings.TrimSpace(matches[1]))
+ if err != nil {
+ return fmt.Errorf("Atoi(%v) failed: %v", strings.TrimSpace(matches[1]), err)
+ }
+ c := &contributor{
+ count: count,
+ email: strings.TrimSpace(matches[3]),
+ name: strings.TrimSpace(matches[2]),
+ }
+ if c.email == "jenkins.veyron@gmail.com" || c.email == "jenkins.veyron.rw@gmail.com" {
+ continue
+ }
+ c.email, c.name = canonicalize(aliases, c.email, c.name)
+ if existing, ok := contributors[c.name]; ok {
+ existing.count += c.count
+ } else {
+ contributors[c.name] = c
+ }
+ }
+ }
+ }
+ }
+ names := []string{}
+ for name, _ := range contributors {
+ names = append(names, name)
+ }
+ sort.Strings(names)
+ for _, name := range names {
+ c := contributors[name]
+ if countFlag {
+ fmt.Fprintf(jirix.Stdout(), "%4d ", c.count)
+ }
+ fmt.Fprintf(jirix.Stdout(), "%v <%v>\n", c.name, c.email)
+ }
+ return nil
+}
+
+func listCommitters(jirix *jiri.X) (_ []string, e error) {
+ branch, err := gitutil.New(jirix.NewSeq()).CurrentBranchName()
+ if err != nil {
+ return nil, err
+ }
+ stashed, err := gitutil.New(jirix.NewSeq()).Stash()
+ if err != nil {
+ return nil, err
+ }
+ if stashed {
+ defer collect.Error(func() error { return gitutil.New(jirix.NewSeq()).StashPop() }, &e)
+ }
+ if err := gitutil.New(jirix.NewSeq()).CheckoutBranch("master"); err != nil {
+ return nil, err
+ }
+ defer collect.Error(func() error { return gitutil.New(jirix.NewSeq()).CheckoutBranch(branch) }, &e)
+ return gitutil.New(jirix.NewSeq()).Committers()
+}
+
+func main() {
+ cmdline.Main(cmdContributors)
+}
diff --git a/jiri-contributors/doc.go b/jiri-contributors/doc.go
new file mode 100644
index 0000000..5bf5512
--- /dev/null
+++ b/jiri-contributors/doc.go
@@ -0,0 +1,67 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+List project contributors.
+
+Usage:
+ jiri contributors [flags] <command>
+
+The jiri contributors commands are:
+ contributors List project contributors
+ help Display help for commands or topics
+
+The global flags are:
+ -metadata=<just specify -metadata to activate>
+ Displays metadata for the program and exits.
+ -time=false
+ Dump timing information to stderr before exiting the program.
+
+Jiri contributors contributors - List project contributors
+
+Lists project contributors. Projects to consider can be specified as an
+argument. If no projects are specified, all projects in the current manifest are
+considered by default.
+
+Usage:
+ jiri contributors contributors [flags] <projects>
+
+<projects> is a list of projects to consider.
+
+The jiri contributors contributors flags are:
+ -aliases=
+ Path to the aliases file.
+ -n=false
+ Show number of contributions.
+
+Jiri contributors help - Display help for commands or topics
+
+Help with no args displays the usage of the parent command.
+
+Help with args displays the usage of the specified sub-command or help topic.
+
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+ jiri contributors help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The jiri contributors help flags are:
+ -style=compact
+ The formatting style for help output:
+ compact - Good for compact cmdline output.
+ full - Good for cmdline output, shows all global flags.
+ godoc - Good for godoc processing.
+ shortonly - Only output short description.
+ Override the default by setting the CMDLINE_STYLE environment variable.
+ -width=<terminal width>
+ Format output to this target width in runes, or unlimited if width < 0.
+ Defaults to the terminal width if available. Override the default by setting
+ the CMDLINE_WIDTH environment variable.
+*/
+package main
diff --git a/jiri-profile-v23/doc.go b/jiri-profile-v23/doc.go
new file mode 100644
index 0000000..500261e
--- /dev/null
+++ b/jiri-profile-v23/doc.go
@@ -0,0 +1,251 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Profiles are used to manage external sofware dependencies and offer a balance
+between providing no support at all and a full blown package manager. Profiles
+can be built natively as well as being cross compiled. A profile is a named
+collection of software required for a given system component or application.
+Current example profiles include 'syncbase' which consists of the leveldb and
+snappy libraries or 'android' which consists of all of the android components
+and downloads needed to build android applications. Profiles are built for
+specific targets.
+
+Targets
+
+Profiles generally refer to uncompiled source code that needs to be compiled for
+a specific "target". Targets hence represent compiled code and consist of:
+
+1. An 'architecture' that refers to the CPU to be generate code for
+
+2. An 'operating system' that refers to the operating system to generate code
+for
+
+3. A lexicographically orderd set of supported versions, one of which is
+designated as the default.
+
+4. An 'environment' which is a set of environment variables to use when
+compiling the profile
+
+Targets thus provide the basic support needed for cross compilation.
+
+Targets are versioned and multiple versions may be installed and used
+simultaneously. Versions are ordered lexicographically and each target specifies
+a 'default' version to be used when a specific version is not explicitly
+requested. A request to 'upgrade' the profile will result in the installation of
+the default version of the targets currently installed if that default version
+is not already installed.
+
+The Supported Commands
+
+Profiles, or more correctly, targets for specific profiles may be installed or
+removed. When doing so, the name of the profile is required, but the other
+components of the target are optional and will default to the values of the
+system that the commands are run on (so-called native builds) and the default
+version for that target. Once a profile is installed it may be referred to by
+its tag for subsequent removals.
+
+The are also update and cleanup commands. Update installs the default version of
+the requested profile or for all profiles for the already installed targets.
+Cleanup will uninstall targets whose version is older than the default.
+
+Finally, there are commands to list the available and installed profiles and to
+access the environment variables specified and stored in each profile
+installation and a command (recreate) to generate a list of commands that can be
+run to recreate the currently installed profiles.
+
+The Profiles Database
+
+The profiles packages manages a database that tracks the installed profiles and
+their configurations. Other command line tools and packages are expected to read
+information about the currently installed profiles from this database via the
+profiles package. The profile command line tools support displaying the database
+(via the list command) or for specifying an alternate version of the file (via
+the -profiles-db flag) which is generally useful for debugging.
+
+Adding Profiles
+
+Profiles are intended to be provided as go packages that register themselves
+with the profile command line tools via the *v.io/jiri/profiles* package. They
+must implement the interfaces defined by that package and be imported (e.g.
+import _ "myprofile") by the command line tools that are to use them.
+
+Usage:
+ jiri profile-v23 [flags] <command>
+
+The jiri profile-v23 commands are:
+ install Install the given profiles
+ uninstall Uninstall the given profiles
+ update Install the latest default version of the given profiles
+ cleanup Cleanup the locally installed profiles
+ available List the available profiles
+ help Display help for commands or topics
+
+The jiri profile-v23 flags are:
+ -color=true
+ Use color to format output.
+ -v=false
+ Print verbose output.
+
+The global flags are:
+ -metadata=<just specify -metadata to activate>
+ Displays metadata for the program and exits.
+ -time=false
+ Dump timing information to stderr before exiting the program.
+
+Jiri profile-v23 install - Install the given profiles
+
+Install the given profiles.
+
+Usage:
+ jiri profile-v23 install [flags] <profiles>
+
+<profiles> is a list of profiles to install.
+
+The jiri profile-v23 install flags are:
+ -env=
+ specify an environment variable in the form: <var>=[<val>],...
+ -force=false
+ force install the profile even if it is already installed
+ -go.sysroot-image=
+ sysroot image for cross compiling to the currently specified target
+ -go.sysroot-image-dirs-to-use=/lib:/usr/lib:/usr/include
+ a colon separated list of directories to use from the sysroot image
+ -mojodev.dir=
+ Path of mojo repo checkout.
+ -profiles-db=$JIRI_ROOT/.jiri_root/profile_db
+ the path, relative to JIRI_ROOT, that contains the profiles database.
+ -profiles-dir=.jiri_root/profiles
+ the directory, relative to JIRI_ROOT, that profiles are installed in
+ -target=<runtime.GOARCH>-<runtime.GOOS>
+ specifies a profile target in the following form: <arch>-<os>[@<version>]
+
+ -color=true
+ Use color to format output.
+ -v=false
+ Print verbose output.
+
+Jiri profile-v23 uninstall - Uninstall the given profiles
+
+Uninstall the given profiles.
+
+Usage:
+ jiri profile-v23 uninstall [flags] <profiles>
+
+<profiles> is a list of profiles to uninstall.
+
+The jiri profile-v23 uninstall flags are:
+ -all-targets=false
+ apply to all targets for the specified profile(s)
+ -go.sysroot-image=
+ sysroot image for cross compiling to the currently specified target
+ -go.sysroot-image-dirs-to-use=/lib:/usr/lib:/usr/include
+ a colon separated list of directories to use from the sysroot image
+ -profiles-db=$JIRI_ROOT/.jiri_root/profile_db
+ the path, relative to JIRI_ROOT, that contains the profiles database.
+ -profiles-dir=.jiri_root/profiles
+ the directory, relative to JIRI_ROOT, that profiles are installed in
+ -target=<runtime.GOARCH>-<runtime.GOOS>
+ specifies a profile target in the following form: <arch>-<os>[@<version>]
+ -v=false
+ print more detailed information
+
+ -color=true
+ Use color to format output.
+
+Jiri profile-v23 update - Install the latest default version of the given profiles
+
+Install the latest default version of the given profiles.
+
+Usage:
+ jiri profile-v23 update [flags] <profiles>
+
+<profiles> is a list of profiles to update, if omitted all profiles are updated.
+
+The jiri profile-v23 update flags are:
+ -profiles-db=$JIRI_ROOT/.jiri_root/profile_db
+ the path, relative to JIRI_ROOT, that contains the profiles database.
+ -profiles-dir=.jiri_root/profiles
+ the directory, relative to JIRI_ROOT, that profiles are installed in
+ -v=false
+ print more detailed information
+
+ -color=true
+ Use color to format output.
+
+Jiri profile-v23 cleanup - Cleanup the locally installed profiles
+
+Cleanup the locally installed profiles. This is generally required when
+recovering from earlier bugs or when preparing for a subsequent change to the
+profiles implementation.
+
+Usage:
+ jiri profile-v23 cleanup [flags] <profiles>
+
+<profiles> is a list of profiles to cleanup, if omitted all profiles are
+cleaned.
+
+The jiri profile-v23 cleanup flags are:
+ -gc=false
+ uninstall profile targets that are older than the current default
+ -profiles-db=$JIRI_ROOT/.jiri_root/profile_db
+ the path, relative to JIRI_ROOT, that contains the profiles database.
+ -profiles-dir=.jiri_root/profiles
+ the directory, relative to JIRI_ROOT, that profiles are installed in
+ -rewrite-profiles-db=false
+ rewrite the profiles database to use the latest schema version
+ -rm-all=false
+ remove profiles database and all profile generated output files.
+ -v=false
+ print more detailed information
+
+ -color=true
+ Use color to format output.
+
+Jiri profile-v23 available - List the available profiles
+
+List the available profiles.
+
+Usage:
+ jiri profile-v23 available [flags]
+
+The jiri profile-v23 available flags are:
+ -describe=false
+ print the profile description
+ -v=false
+ print more detailed information
+
+ -color=true
+ Use color to format output.
+
+Jiri profile-v23 help - Display help for commands or topics
+
+Help with no args displays the usage of the parent command.
+
+Help with args displays the usage of the specified sub-command or help topic.
+
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+ jiri profile-v23 help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The jiri profile-v23 help flags are:
+ -style=compact
+ The formatting style for help output:
+ compact - Good for compact cmdline output.
+ full - Good for cmdline output, shows all global flags.
+ godoc - Good for godoc processing.
+ shortonly - Only output short description.
+ Override the default by setting the CMDLINE_STYLE environment variable.
+ -width=<terminal width>
+ Format output to this target width in runes, or unlimited if width < 0.
+ Defaults to the terminal width if available. Override the default by setting
+ the CMDLINE_WIDTH environment variable.
+*/
+package main
diff --git a/jiri-test/doc.go b/jiri-test/doc.go
index 129c9ed..d83368b 100644
--- a/jiri-test/doc.go
+++ b/jiri-test/doc.go
@@ -12,6 +12,7 @@
jiri test [flags] <command>
The jiri test commands are:
+ poll Poll existing jiri projects
project Run tests for a vanadium project
run Run vanadium tests
list List vanadium tests
@@ -41,6 +42,38 @@
-time=false
Dump timing information to stderr before exiting the program.
+Jiri test poll - Poll existing jiri projects
+
+Poll jiri projects that can affect the outcome of the given tests and report
+whether any new changes in these projects exist. If no tests are specified, all
+projects are polled by default.
+
+Usage:
+ jiri test poll [flags] <test ...>
+
+<test ...> is a list of tests that determine what projects to poll.
+
+The jiri test poll flags are:
+ -manifest=
+ Name of the project manifest.
+
+ -color=true
+ Use color to format output.
+ -env=
+ specify an environment variable in the form: <var>=[<val>],...
+ -merge-policies=+CCFLAGS,+CGO_CFLAGS,+CGO_CXXFLAGS,+CGO_LDFLAGS,+CXXFLAGS,GOARCH,GOOS,GOPATH:,^GOROOT*,+LDFLAGS,:PATH,VDLPATH:
+ specify policies for merging environment variables
+ -profiles=v23:base,jiri
+ a comma separated list of profiles to use
+ -profiles-db=$JIRI_ROOT/.jiri_root/profile_db
+ the path, relative to JIRI_ROOT, that contains the profiles database.
+ -skip-profiles=false
+ if set, no profiles will be used
+ -target=<runtime.GOARCH>-<runtime.GOOS>
+ specifies a profile target in the following form: <arch>-<os>[@<version>]
+ -v=false
+ Print verbose output.
+
Jiri test project - Run tests for a vanadium project
Runs tests for a vanadium project that is by the remote URL specified as the
diff --git a/jiri-test/test.go b/jiri-test/test.go
index 8ab0bb1..a844362 100644
--- a/jiri-test/test.go
+++ b/jiri-test/test.go
@@ -8,16 +8,20 @@
package main
import (
+ "encoding/json"
"fmt"
"runtime"
"strings"
"v.io/jiri"
"v.io/jiri/profiles/profilescmdline"
+ "v.io/jiri/project"
"v.io/jiri/tool"
"v.io/x/devtools/internal/test"
jiriTest "v.io/x/devtools/jiri-test/internal/test"
+ "v.io/x/devtools/tooldata"
"v.io/x/lib/cmdline"
+ "v.io/x/lib/set"
)
var (
@@ -48,6 +52,7 @@
cmdTestRun.Flags.StringVar(&mockTestFilePaths, "mock-file-paths", "", "Colon-separated file paths to read when testing presubmit test. This flag is only used when running presubmit end-to-end test.")
cmdTestRun.Flags.StringVar(&mockTestFileContents, "mock-file-contents", "", "Colon-separated file contents to check when testing presubmit test. This flag is only used when running presubmit end-to-end test.")
tool.InitializeRunFlags(&cmdTest.Flags)
+ tool.InitializeProjectFlags(&cmdProjectPoll.Flags)
profilescmdline.RegisterReaderFlags(&cmdTest.Flags, &readerFlags, jiri.ProfilesDBDir)
}
@@ -56,7 +61,7 @@
Name: "test",
Short: "Manage vanadium tests",
Long: "Manage vanadium tests.",
- Children: []*cmdline.Command{cmdTestProject, cmdTestRun, cmdTestList},
+ Children: []*cmdline.Command{cmdProjectPoll, cmdTestProject, cmdTestRun, cmdTestList},
}
// cmdTestProject represents the "jiri test project" command.
@@ -121,6 +126,68 @@
return nil
}
+// cmdProjectPoll represents the "jiri project poll" command.
+var cmdProjectPoll = &cmdline.Command{
+ Runner: jiri.RunnerFunc(runProjectPoll),
+ Name: "poll",
+ Short: "Poll existing jiri projects",
+ Long: `
+Poll jiri projects that can affect the outcome of the given tests
+and report whether any new changes in these projects exist. If no
+tests are specified, all projects are polled by default.
+`,
+ ArgsName: "<test ...>",
+ ArgsLong: "<test ...> is a list of tests that determine what projects to poll.",
+}
+
+// runProjectPoll generates a description of changes that exist
+// remotely but do not exist locally.
+func runProjectPoll(jirix *jiri.X, args []string) error {
+ projectSet := map[string]struct{}{}
+ if len(args) > 0 {
+ config, err := tooldata.LoadConfig(jirix)
+ if err != nil {
+ return err
+ }
+ // Compute a map from tests to projects that can change the
+ // outcome of the test.
+ testProjects := map[string][]string{}
+ for _, project := range config.Projects() {
+ for _, test := range config.ProjectTests([]string{project}) {
+ testProjects[test] = append(testProjects[test], project)
+ }
+ }
+ for _, arg := range args {
+ projects, ok := testProjects[arg]
+ if !ok {
+ return fmt.Errorf("failed to find any projects for test %q", arg)
+ }
+ set.String.Union(projectSet, set.String.FromSlice(projects))
+ }
+ }
+ update, err := project.PollProjects(jirix, projectSet)
+ if err != nil {
+ return err
+ }
+
+ // Remove projects with empty changes.
+ for project := range update {
+ if changes := update[project]; len(changes) == 0 {
+ delete(update, project)
+ }
+ }
+
+ // Print update if it is not empty.
+ if len(update) > 0 {
+ bytes, err := json.MarshalIndent(update, "", " ")
+ if err != nil {
+ return fmt.Errorf("MarshalIndent() failed: %v", err)
+ }
+ fmt.Fprintf(jirix.Stdout(), "%s\n", bytes)
+ }
+ return nil
+}
+
func optsFromFlags() (opts []jiriTest.Opt) {
if partFlag >= 0 {
opt := jiriTest.PartOpt(partFlag)
diff --git a/jiridoc/doc.go b/jiridoc/doc.go
index 4a41e53..3766690 100644
--- a/jiridoc/doc.go
+++ b/jiridoc/doc.go
@@ -1480,6 +1480,7 @@
jiri test [flags] <command>
The jiri test commands are:
+ poll Poll existing jiri projects
project Run tests for a vanadium project
run Run vanadium tests
list List vanadium tests
@@ -1502,6 +1503,38 @@
-v=false
Print verbose output.
+Jiri test poll - Poll existing jiri projects
+
+Poll jiri projects that can affect the outcome of the given tests and report
+whether any new changes in these projects exist. If no tests are specified, all
+projects are polled by default.
+
+Usage:
+ jiri test poll [flags] <test ...>
+
+<test ...> is a list of tests that determine what projects to poll.
+
+The jiri test poll flags are:
+ -manifest=
+ Name of the project manifest.
+
+ -color=true
+ Use color to format output.
+ -env=
+ specify an environment variable in the form: <var>=[<val>],...
+ -merge-policies=+CCFLAGS,+CGO_CFLAGS,+CGO_CXXFLAGS,+CGO_LDFLAGS,+CXXFLAGS,GOARCH,GOOS,GOPATH:,^GOROOT*,+LDFLAGS,:PATH,VDLPATH:
+ specify policies for merging environment variables
+ -profiles=v23:base,jiri
+ a comma separated list of profiles to use
+ -profiles-db=$JIRI_ROOT/.jiri_root/profile_db
+ the path, relative to JIRI_ROOT, that contains the profiles database.
+ -skip-profiles=false
+ if set, no profiles will be used
+ -target=<runtime.GOARCH>-<runtime.GOOS>
+ specifies a profile target in the following form: <arch>-<os>[@<version>]
+ -v=false
+ Print verbose output.
+
Jiri test project - Run tests for a vanadium project
Runs tests for a vanadium project that is by the remote URL specified as the
diff --git a/tooldata/.api b/tooldata/.api
new file mode 100644
index 0000000..56f4e19
--- /dev/null
+++ b/tooldata/.api
@@ -0,0 +1,45 @@
+pkg tooldata, func ConfigFilePath(*jiri.X) (string, error)
+pkg tooldata, func DataDirPath(*jiri.X, string) (string, error)
+pkg tooldata, func LoadConfig(*jiri.X) (*Config, error)
+pkg tooldata, func LoadOncallRotation(*jiri.X) (*OncallRotation, error)
+pkg tooldata, func NewConfig(...ConfigOpt) *Config
+pkg tooldata, func Oncall(*jiri.X, time.Time) (*OncallShift, error)
+pkg tooldata, func OncallRotationPath(*jiri.X) (string, error)
+pkg tooldata, func SaveConfig(*jiri.X, *Config) error
+pkg tooldata, func ThirdPartyBinPath(*jiri.X, string) (string, error)
+pkg tooldata, method (Config) APICheckProjects() map[string]struct{}
+pkg tooldata, method (Config) CopyrightCheckProjects() map[string]struct{}
+pkg tooldata, method (Config) GoPath(*jiri.X) string
+pkg tooldata, method (Config) GoWorkspaces() []string
+pkg tooldata, method (Config) GroupTests([]string) []string
+pkg tooldata, method (Config) JenkinsMatrixJobs() map[string]JenkinsMatrixJobInfo
+pkg tooldata, method (Config) ProjectTests([]string) []string
+pkg tooldata, method (Config) Projects() []string
+pkg tooldata, method (Config) TestDependencies(string) []string
+pkg tooldata, method (Config) TestParts(string) []string
+pkg tooldata, method (Config) VDLPath(*jiri.X) string
+pkg tooldata, method (Config) VDLWorkspaces() []string
+pkg tooldata, type APICheckProjectsOpt map[string]struct{}
+pkg tooldata, type Config struct
+pkg tooldata, type ConfigOpt interface, unexported methods
+pkg tooldata, type CopyrightCheckProjectsOpt map[string]struct{}
+pkg tooldata, type GoWorkspacesOpt []string
+pkg tooldata, type JenkinsMatrixJobInfo struct
+pkg tooldata, type JenkinsMatrixJobInfo struct, HasArch bool
+pkg tooldata, type JenkinsMatrixJobInfo struct, HasOS bool
+pkg tooldata, type JenkinsMatrixJobInfo struct, HasParts bool
+pkg tooldata, type JenkinsMatrixJobInfo struct, Name string
+pkg tooldata, type JenkinsMatrixJobInfo struct, ShowOS bool
+pkg tooldata, type JenkinsMatrixJobsOpt map[string]JenkinsMatrixJobInfo
+pkg tooldata, type OncallRotation struct
+pkg tooldata, type OncallRotation struct, Shifts []OncallShift
+pkg tooldata, type OncallRotation struct, XMLName xml.Name
+pkg tooldata, type OncallShift struct
+pkg tooldata, type OncallShift struct, Date string
+pkg tooldata, type OncallShift struct, Primary string
+pkg tooldata, type OncallShift struct, Secondary string
+pkg tooldata, type ProjectTestsOpt map[string][]string
+pkg tooldata, type TestDependenciesOpt map[string][]string
+pkg tooldata, type TestGroupsOpt map[string][]string
+pkg tooldata, type TestPartsOpt map[string][]string
+pkg tooldata, type VDLWorkspacesOpt []string
diff --git a/tooldata/config.go b/tooldata/config.go
new file mode 100644
index 0000000..25a5ee2
--- /dev/null
+++ b/tooldata/config.go
@@ -0,0 +1,458 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tooldata
+
+import (
+ "encoding/xml"
+ "fmt"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "v.io/jiri"
+ "v.io/jiri/project"
+ "v.io/x/lib/envvar"
+ "v.io/x/lib/set"
+)
+
+// Config holds configuration common to jiri tools.
+type Config struct {
+ // apiCheckProjects identifies the set of project names for which
+ // the API check is required.
+ apiCheckProjects map[string]struct{}
+ // copyrightCheckProjects identifies the set of project names for
+ // which the copyright check is required.
+ copyrightCheckProjects map[string]struct{}
+ // goWorkspaces identifies JIRI_ROOT subdirectories that contain a
+ // Go workspace.
+ goWorkspaces []string
+ // jenkinsMatrixJobs identifies the set of matrix (multi-configutation) jobs
+ // in Jenkins.
+ jenkinsMatrixJobs map[string]JenkinsMatrixJobInfo
+ // projectTests maps jiri projects to sets of tests that should be
+ // executed to test changes in the given project.
+ projectTests map[string][]string
+ // testDependencies maps tests to sets of tests that the given test
+ // depends on.
+ testDependencies map[string][]string
+ // testGroups maps test group labels to sets of tests that the label
+ // identifies.
+ testGroups map[string][]string
+ // testParts maps test names to lists of strings that identify
+ // different parts of a test. If a list L has n elements, then the
+ // corresponding test has n+1 parts: the first n parts are identified
+ // by L[0] to L[n-1]. The last part is whatever is left.
+ testParts map[string][]string
+ // vdlWorkspaces identifies JIRI_ROOT subdirectories that contain
+ // a VDL workspace.
+ vdlWorkspaces []string
+}
+
+// ConfigOpt is an interface for Config factory options.
+type ConfigOpt interface {
+ configOpt()
+}
+
+// APICheckProjectsOpt is the type that can be used to pass the Config
+// factory a API check projects option.
+type APICheckProjectsOpt map[string]struct{}
+
+func (APICheckProjectsOpt) configOpt() {}
+
+// CopyrightCheckProjectsOpt is the type that can be used to pass the
+// Config factory a copyright check projects option.
+type CopyrightCheckProjectsOpt map[string]struct{}
+
+func (CopyrightCheckProjectsOpt) configOpt() {}
+
+// GoWorkspacesOpt is the type that can be used to pass the Config
+// factory a Go workspace option.
+type GoWorkspacesOpt []string
+
+func (GoWorkspacesOpt) configOpt() {}
+
+// JenkinsMatrixJobsOpt is the type that can be used to pass the Config factory
+// a Jenkins matrix jobs option.
+type JenkinsMatrixJobsOpt map[string]JenkinsMatrixJobInfo
+
+func (JenkinsMatrixJobsOpt) configOpt() {}
+
+// ProjectTestsOpt is the type that can be used to pass the Config
+// factory a project tests option.
+type ProjectTestsOpt map[string][]string
+
+func (ProjectTestsOpt) configOpt() {}
+
+// TestDependenciesOpt is the type that can be used to pass the Config
+// factory a test dependencies option.
+type TestDependenciesOpt map[string][]string
+
+func (TestDependenciesOpt) configOpt() {}
+
+// TestGroupsOpt is the type that can be used to pass the Config
+// factory a test groups option.
+type TestGroupsOpt map[string][]string
+
+func (TestGroupsOpt) configOpt() {}
+
+// TestPartsOpt is the type that can be used to pass the Config
+// factory a test parts option.
+type TestPartsOpt map[string][]string
+
+func (TestPartsOpt) configOpt() {}
+
+// VDLWorkspacesOpt is the type that can be used to pass the Config
+// factory a VDL workspace option.
+type VDLWorkspacesOpt []string
+
+func (VDLWorkspacesOpt) configOpt() {}
+
+// NewConfig is the Config factory.
+func NewConfig(opts ...ConfigOpt) *Config {
+ var c Config
+ for _, opt := range opts {
+ switch typedOpt := opt.(type) {
+ case APICheckProjectsOpt:
+ c.apiCheckProjects = map[string]struct{}(typedOpt)
+ case CopyrightCheckProjectsOpt:
+ c.copyrightCheckProjects = map[string]struct{}(typedOpt)
+ case GoWorkspacesOpt:
+ c.goWorkspaces = []string(typedOpt)
+ case JenkinsMatrixJobsOpt:
+ c.jenkinsMatrixJobs = map[string]JenkinsMatrixJobInfo(typedOpt)
+ case ProjectTestsOpt:
+ c.projectTests = map[string][]string(typedOpt)
+ case TestDependenciesOpt:
+ c.testDependencies = map[string][]string(typedOpt)
+ case TestGroupsOpt:
+ c.testGroups = map[string][]string(typedOpt)
+ case TestPartsOpt:
+ c.testParts = map[string][]string(typedOpt)
+ case VDLWorkspacesOpt:
+ c.vdlWorkspaces = []string(typedOpt)
+ }
+ }
+ return &c
+}
+
+// APICheckProjects returns the set of project names for which the API
+// check is required.
+func (c Config) APICheckProjects() map[string]struct{} {
+ return c.apiCheckProjects
+}
+
+// CopyrightCheckProjects returns the set of project names for which
+// the copyright check is required.
+func (c Config) CopyrightCheckProjects() map[string]struct{} {
+ return c.copyrightCheckProjects
+}
+
+// GroupTests returns a list of Jenkins tests associated with the
+// given test groups.
+func (c Config) GroupTests(groups []string) []string {
+ testSet := map[string]struct{}{}
+ testGroups := c.testGroups
+ for _, group := range groups {
+ if testGroup, ok := testGroups[group]; ok {
+ set.String.Union(testSet, set.String.FromSlice(testGroup))
+ }
+ }
+ tests := set.String.ToSlice(testSet)
+ sort.Strings(tests)
+ return tests
+}
+
+// GoWorkspaces returns the Go workspaces included in the config.
+func (c Config) GoWorkspaces() []string {
+ return c.goWorkspaces
+}
+
+// JenkinsMatrixJobs returns the set of Jenkins matrix jobs.
+func (c Config) JenkinsMatrixJobs() map[string]JenkinsMatrixJobInfo {
+ return c.jenkinsMatrixJobs
+}
+
+// Projects returns a list of projects included in the config.
+func (c Config) Projects() []string {
+ var projects []string
+ for project, _ := range c.projectTests {
+ projects = append(projects, project)
+ }
+ sort.Strings(projects)
+ return projects
+}
+
+// ProjectTests returns a list of Jenkins tests associated with the
+// given projects by the config.
+func (c Config) ProjectTests(projects []string) []string {
+ testSet := map[string]struct{}{}
+ testGroups := c.testGroups
+ for _, project := range projects {
+ for _, test := range c.projectTests[project] {
+ if testGroup, ok := testGroups[test]; ok {
+ set.String.Union(testSet, set.String.FromSlice(testGroup))
+ } else {
+ testSet[test] = struct{}{}
+ }
+ }
+ }
+ tests := set.String.ToSlice(testSet)
+ sort.Strings(tests)
+ return tests
+}
+
+// TestDependencies returns a list of dependencies for the given test.
+func (c Config) TestDependencies(test string) []string {
+ return c.testDependencies[test]
+}
+
+// TestParts returns a list of strings that identify different test parts.
+func (c Config) TestParts(test string) []string {
+ return c.testParts[test]
+}
+
+// VDLWorkspaces returns the VDL workspaces included in the config.
+func (c Config) VDLWorkspaces() []string {
+ return c.vdlWorkspaces
+}
+
+// GoPath computes and returns the GOPATH environment variable based on the
+// current jiri configuration.
+func (c Config) GoPath(jirix *jiri.X) string {
+ projects, err := project.LocalProjects(jirix, project.FastScan)
+ if err != nil {
+ return ""
+ }
+ path := pathHelper(jirix, projects, c.goWorkspaces, "")
+ return "GOPATH=" + envvar.JoinTokens(path, ":")
+}
+
+// VDLPath computes and returns the VDLPATH environment variable based on the
+// current jiri configuration.
+func (c Config) VDLPath(jirix *jiri.X) string {
+ projects, err := project.LocalProjects(jirix, project.FastScan)
+ if err != nil {
+ return ""
+ }
+ path := pathHelper(jirix, projects, c.vdlWorkspaces, "src")
+ return "VDLPATH=" + envvar.JoinTokens(path, ":")
+}
+
+// pathHelper is a utility function for determining paths for project workspaces.
+func pathHelper(jirix *jiri.X, projects project.Projects, workspaces []string, suffix string) []string {
+ path := []string{}
+ for _, workspace := range workspaces {
+ absWorkspace := filepath.Join(jirix.Root, workspace, suffix)
+ // Only append an entry to the path if the workspace is rooted
+ // under a jiri project that exists locally or vice versa.
+ for _, project := range projects {
+ // We check if <project.Path> is a prefix of <absWorkspace> to
+ // account for Go workspaces nested under a single jiri project,
+ // such as: $JIRI_ROOT/release/projects/chat/go.
+ //
+ // We check if <absWorkspace> is a prefix of <project.Path> to
+ // account for Go workspaces that span multiple jiri projects,
+ // such as: $JIRI_ROOT/release/go.
+ if strings.HasPrefix(absWorkspace, project.Path) || strings.HasPrefix(project.Path, absWorkspace) {
+ if _, err := jirix.NewSeq().Stat(filepath.Join(absWorkspace)); err == nil {
+ path = append(path, absWorkspace)
+ break
+ }
+ }
+ }
+ }
+ return path
+}
+
+type configSchema struct {
+ APICheckProjects []string `xml:"apiCheckProjects>project"`
+ CopyrightCheckProjects []string `xml:"copyrightCheckProjects>project"`
+ GoWorkspaces []string `xml:"goWorkspaces>workspace"`
+ JenkinsMatrixJobs jenkinsMatrixJobsSchema `xml:"jenkinsMatrixJobs>job"`
+ ProjectTests testGroupSchemas `xml:"projectTests>project"`
+ TestDependencies dependencyGroupSchemas `xml:"testDependencies>test"`
+ TestGroups testGroupSchemas `xml:"testGroups>group"`
+ TestParts partGroupSchemas `xml:"testParts>test"`
+ VDLWorkspaces []string `xml:"vdlWorkspaces>workspace"`
+ XMLName xml.Name `xml:"config"`
+}
+
+type dependencyGroupSchema struct {
+ Name string `xml:"name,attr"`
+ Dependencies []string `xml:"dependency"`
+}
+
+type dependencyGroupSchemas []dependencyGroupSchema
+
+func (d dependencyGroupSchemas) Len() int { return len(d) }
+func (d dependencyGroupSchemas) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
+func (d dependencyGroupSchemas) Less(i, j int) bool { return d[i].Name < d[j].Name }
+
+type JenkinsMatrixJobInfo struct {
+ HasArch bool `xml:"arch,attr"`
+ HasOS bool `xml:"OS,attr"`
+ HasParts bool `xml:"parts,attr"`
+ // ShowOS determines whether to show OS label in job summary.
+ // It is possible that a job (e.g. jiri-go-race) has an OS axis but
+ // the axis only has a single value in order to constrain where its
+ // sub-builds run. In such cases, we do not want to show the OS label.
+ ShowOS bool `xml:"showOS,attr"`
+ Name string `xml:",chardata"`
+}
+
+type jenkinsMatrixJobsSchema []JenkinsMatrixJobInfo
+
+func (jobs jenkinsMatrixJobsSchema) Len() int { return len(jobs) }
+func (jobs jenkinsMatrixJobsSchema) Swap(i, j int) { jobs[i], jobs[j] = jobs[j], jobs[i] }
+func (jobs jenkinsMatrixJobsSchema) Less(i, j int) bool { return jobs[i].Name < jobs[j].Name }
+
+type partGroupSchema struct {
+ Name string `xml:"name,attr"`
+ Parts []string `xml:"part"`
+}
+
+type partGroupSchemas []partGroupSchema
+
+func (p partGroupSchemas) Len() int { return len(p) }
+func (p partGroupSchemas) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p partGroupSchemas) Less(i, j int) bool { return p[i].Name < p[j].Name }
+
+type testGroupSchema struct {
+ Name string `xml:"name,attr"`
+ Tests []string `xml:"test"`
+}
+
+type testGroupSchemas []testGroupSchema
+
+func (p testGroupSchemas) Len() int { return len(p) }
+func (p testGroupSchemas) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p testGroupSchemas) Less(i, j int) bool { return p[i].Name < p[j].Name }
+
+// LoadConfig returns the configuration stored in the tools
+// configuration file.
+func LoadConfig(jirix *jiri.X) (*Config, error) {
+ configPath, err := ConfigFilePath(jirix)
+ if err != nil {
+ return nil, err
+ }
+ return loadConfig(jirix, configPath)
+}
+
+func loadConfig(jirix *jiri.X, path string) (*Config, error) {
+ configBytes, err := jirix.NewSeq().ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ var data configSchema
+ if err := xml.Unmarshal(configBytes, &data); err != nil {
+ return nil, fmt.Errorf("Unmarshal(%v) failed: %v", string(configBytes), err)
+ }
+ config := &Config{
+ apiCheckProjects: map[string]struct{}{},
+ copyrightCheckProjects: map[string]struct{}{},
+ goWorkspaces: []string{},
+ jenkinsMatrixJobs: map[string]JenkinsMatrixJobInfo{},
+ projectTests: map[string][]string{},
+ testDependencies: map[string][]string{},
+ testGroups: map[string][]string{},
+ testParts: map[string][]string{},
+ vdlWorkspaces: []string{},
+ }
+ config.apiCheckProjects = set.String.FromSlice(data.APICheckProjects)
+ config.copyrightCheckProjects = set.String.FromSlice(data.CopyrightCheckProjects)
+ for _, workspace := range data.GoWorkspaces {
+ config.goWorkspaces = append(config.goWorkspaces, workspace)
+ }
+ sort.Strings(config.goWorkspaces)
+ for _, job := range data.JenkinsMatrixJobs {
+ config.jenkinsMatrixJobs[job.Name] = job
+ }
+ for _, project := range data.ProjectTests {
+ config.projectTests[project.Name] = project.Tests
+ }
+ for _, test := range data.TestDependencies {
+ config.testDependencies[test.Name] = test.Dependencies
+ }
+ for _, group := range data.TestGroups {
+ config.testGroups[group.Name] = group.Tests
+ }
+ for _, test := range data.TestParts {
+ config.testParts[test.Name] = test.Parts
+ }
+ for _, workspace := range data.VDLWorkspaces {
+ config.vdlWorkspaces = append(config.vdlWorkspaces, workspace)
+ }
+ sort.Strings(config.vdlWorkspaces)
+ return config, nil
+}
+
+// SaveConfig writes the given configuration to the tools
+// configuration file.
+func SaveConfig(jirix *jiri.X, config *Config) error {
+ configPath, err := ConfigFilePath(jirix)
+ if err != nil {
+ return err
+ }
+ return saveConfig(jirix, config, configPath)
+}
+
+func saveConfig(jirix *jiri.X, config *Config, path string) error {
+ var data configSchema
+ data.APICheckProjects = set.String.ToSlice(config.apiCheckProjects)
+ sort.Strings(data.APICheckProjects)
+ data.CopyrightCheckProjects = set.String.ToSlice(config.copyrightCheckProjects)
+ sort.Strings(data.CopyrightCheckProjects)
+ for _, workspace := range config.goWorkspaces {
+ data.GoWorkspaces = append(data.GoWorkspaces, workspace)
+ }
+ sort.Strings(data.GoWorkspaces)
+ for _, job := range config.jenkinsMatrixJobs {
+ data.JenkinsMatrixJobs = append(data.JenkinsMatrixJobs, job)
+ }
+ sort.Sort(data.JenkinsMatrixJobs)
+ for name, tests := range config.projectTests {
+ data.ProjectTests = append(data.ProjectTests, testGroupSchema{
+ Name: name,
+ Tests: tests,
+ })
+ }
+ sort.Sort(data.ProjectTests)
+ for name, dependencies := range config.testDependencies {
+ data.TestDependencies = append(data.TestDependencies, dependencyGroupSchema{
+ Name: name,
+ Dependencies: dependencies,
+ })
+ }
+ sort.Sort(data.TestDependencies)
+ for name, tests := range config.testGroups {
+ data.TestGroups = append(data.TestGroups, testGroupSchema{
+ Name: name,
+ Tests: tests,
+ })
+ }
+ sort.Sort(data.TestGroups)
+ for name, parts := range config.testParts {
+ data.TestParts = append(data.TestParts, partGroupSchema{
+ Name: name,
+ Parts: parts,
+ })
+ }
+ sort.Sort(data.TestParts)
+ for _, workspace := range config.vdlWorkspaces {
+ data.VDLWorkspaces = append(data.VDLWorkspaces, workspace)
+ }
+ sort.Strings(data.VDLWorkspaces)
+ bytes, err := xml.MarshalIndent(data, "", " ")
+ if err != nil {
+ return fmt.Errorf("MarshalIndent(%v) failed: %v", data, err)
+ }
+ s := jirix.NewSeq()
+ if err := s.MkdirAll(filepath.Dir(path), os.FileMode(0755)).
+ WriteFile(path, bytes, os.FileMode(0644)).Done(); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/tooldata/config_test.go b/tooldata/config_test.go
new file mode 100644
index 0000000..1b16de8
--- /dev/null
+++ b/tooldata/config_test.go
@@ -0,0 +1,197 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tooldata_test
+
+import (
+ "path/filepath"
+ "reflect"
+ "testing"
+
+ "v.io/jiri/jiritest"
+ "v.io/jiri/project"
+ "v.io/x/devtools/tooldata"
+)
+
+var (
+ apiCheckProjects = map[string]struct{}{
+ "projectA": struct{}{},
+ "projectB": struct{}{},
+ }
+ copyrightCheckProjects = map[string]struct{}{
+ "projectC": struct{}{},
+ "projectD": struct{}{},
+ }
+ goWorkspaces = []string{"test-go-workspace"}
+ jenkinsMatrixJobs = map[string]tooldata.JenkinsMatrixJobInfo{
+ "test-job-A": {
+ HasArch: false,
+ HasOS: true,
+ HasParts: true,
+ ShowOS: false,
+ Name: "test-job-A",
+ },
+ "test-job-B": {
+ HasArch: true,
+ HasOS: false,
+ HasParts: false,
+ ShowOS: false,
+ Name: "test-job-B",
+ },
+ }
+ projectTests = map[string][]string{
+ "test-project": []string{"test-test-A", "test-test-group"},
+ "test-project2": []string{"test-test-D"},
+ }
+ testDependencies = map[string][]string{
+ "test-test-A": []string{"test-test-B"},
+ "test-test-B": []string{"test-test-C"},
+ }
+ testGroups = map[string][]string{
+ "test-test-group": []string{"test-test-B", "test-test-C"},
+ }
+ testParts = map[string][]string{
+ "test-test-A": []string{"p1", "p2"},
+ }
+ vdlWorkspaces = []string{"test-vdl-workspace"}
+)
+
+func testConfigAPI(t *testing.T, c *tooldata.Config) {
+ if got, want := c.APICheckProjects(), apiCheckProjects; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected results: got %v, want %v", got, want)
+ }
+ if got, want := c.CopyrightCheckProjects(), copyrightCheckProjects; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected results: got %v, want %v", got, want)
+ }
+ if got, want := c.GoWorkspaces(), goWorkspaces; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.GroupTests([]string{"test-test-group"}), []string{"test-test-B", "test-test-C"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.JenkinsMatrixJobs(), jenkinsMatrixJobs; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.Projects(), []string{"test-project", "test-project2"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.ProjectTests([]string{"test-project"}), []string{"test-test-A", "test-test-B", "test-test-C"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.ProjectTests([]string{"test-project", "test-project2"}), []string{"test-test-A", "test-test-B", "test-test-C", "test-test-D"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.TestDependencies("test-test-A"), []string{"test-test-B"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.TestDependencies("test-test-B"), []string{"test-test-C"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.TestParts("test-test-A"), []string{"p1", "p2"}; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+ if got, want := c.VDLWorkspaces(), vdlWorkspaces; !reflect.DeepEqual(got, want) {
+ t.Fatalf("unexpected result: got %v, want %v", got, want)
+ }
+}
+
+func TestConfigAPI(t *testing.T) {
+ config := tooldata.NewConfig(
+ tooldata.APICheckProjectsOpt(apiCheckProjects),
+ tooldata.CopyrightCheckProjectsOpt(copyrightCheckProjects),
+ tooldata.GoWorkspacesOpt(goWorkspaces),
+ tooldata.JenkinsMatrixJobsOpt(jenkinsMatrixJobs),
+ tooldata.ProjectTestsOpt(projectTests),
+ tooldata.TestDependenciesOpt(testDependencies),
+ tooldata.TestGroupsOpt(testGroups),
+ tooldata.TestPartsOpt(testParts),
+ tooldata.VDLWorkspacesOpt(vdlWorkspaces),
+ )
+
+ testConfigAPI(t, config)
+}
+
+func TestConfigSerialization(t *testing.T) {
+ fake, cleanup := jiritest.NewFakeJiriRoot(t)
+ defer cleanup()
+
+ config := tooldata.NewConfig(
+ tooldata.APICheckProjectsOpt(apiCheckProjects),
+ tooldata.CopyrightCheckProjectsOpt(copyrightCheckProjects),
+ tooldata.GoWorkspacesOpt(goWorkspaces),
+ tooldata.JenkinsMatrixJobsOpt(jenkinsMatrixJobs),
+ tooldata.ProjectTestsOpt(projectTests),
+ tooldata.TestDependenciesOpt(testDependencies),
+ tooldata.TestGroupsOpt(testGroups),
+ tooldata.TestPartsOpt(testParts),
+ tooldata.VDLWorkspacesOpt(vdlWorkspaces),
+ )
+
+ if err := tooldata.SaveConfig(fake.X, config); err != nil {
+ t.Fatalf("%v", err)
+ }
+ gotConfig, err := tooldata.LoadConfig(fake.X)
+ if err != nil {
+ t.Fatalf("%v", err)
+ }
+
+ testConfigAPI(t, gotConfig)
+}
+
+func testSetPathHelper(t *testing.T, name string) {
+ fake, cleanup := jiritest.NewFakeJiriRoot(t)
+ defer cleanup()
+
+ // Create a test project and identify it as a Go workspace.
+ if err := fake.CreateRemoteProject("test"); err != nil {
+ t.Fatalf("%v", err)
+ }
+ if err := fake.AddProject(project.Project{
+ Name: "test",
+ Path: "test",
+ Remote: fake.Projects["test"],
+ }); err != nil {
+ t.Fatalf("%v", err)
+ }
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatalf("%v", err)
+ }
+ var config *tooldata.Config
+ switch name {
+ case "GOPATH":
+ config = tooldata.NewConfig(tooldata.GoWorkspacesOpt([]string{"test", "does/not/exist"}))
+ case "VDLPATH":
+ config = tooldata.NewConfig(tooldata.VDLWorkspacesOpt([]string{"test", "does/not/exist"}))
+ }
+
+ if err := tooldata.SaveConfig(fake.X, config); err != nil {
+ t.Fatalf("%v", err)
+ }
+
+ var got, want string
+ switch name {
+ case "GOPATH":
+ want = "GOPATH=" + filepath.Join(fake.X.Root, "test")
+ got = config.GoPath(fake.X)
+ case "VDLPATH":
+ // Make a fake src directory.
+ want = filepath.Join(fake.X.Root, "test", "src")
+ if err := fake.X.NewSeq().MkdirAll(want, 0755).Done(); err != nil {
+ t.Fatalf("%v", err)
+ }
+ want = "VDLPATH=" + want
+ got = config.VDLPath(fake.X)
+ }
+ if got != want {
+ t.Fatalf("unexpected value: got %v, want %v", got, want)
+ }
+}
+
+func TestGoPath(t *testing.T) {
+ testSetPathHelper(t, "GOPATH")
+}
+
+func TestVDLPath(t *testing.T) {
+ testSetPathHelper(t, "VDLPATH")
+}
diff --git a/tooldata/data/AUTHORS b/tooldata/data/AUTHORS
new file mode 100644
index 0000000..574583c
--- /dev/null
+++ b/tooldata/data/AUTHORS
@@ -0,0 +1,9 @@
+# This is the official list of Vanadium authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+# Name or Organization <email address>
+# The email address is not required for organizations.
+
+# Please keep the list sorted.
diff --git a/tooldata/data/CONTRIBUTING.md b/tooldata/data/CONTRIBUTING.md
new file mode 100644
index 0000000..de03ce0
--- /dev/null
+++ b/tooldata/data/CONTRIBUTING.md
@@ -0,0 +1,23 @@
+# Contributing to Vanadium
+
+Vanadium is an open source project.
+
+It is the work of many contributors. We appreciate your help!
+
+## Filing issues
+
+We use a single GitHub repository for [tracking all
+issues](https://github.com/vanadium/issues/issues) across all Vanadium
+repositories.
+
+## Contributing code
+
+Please read the [contribution
+guidelines](https://vanadium.github.io/community/contributing.html) before
+sending patches.
+
+**We do not accept GitHub pull requests.** (We use
+[Gerrit](https://www.gerritcodereview.com/) instead for code reviews.)
+
+Unless otherwise noted, the Vanadium source files are distributed under the
+BSD-style license found in the LICENSE file.
diff --git a/tooldata/data/CONTRIBUTORS b/tooldata/data/CONTRIBUTORS
new file mode 100644
index 0000000..b294e50
--- /dev/null
+++ b/tooldata/data/CONTRIBUTORS
@@ -0,0 +1,10 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people. For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+# Name <email address>
diff --git a/tooldata/data/COPYRIGHT b/tooldata/data/COPYRIGHT
new file mode 100644
index 0000000..a26470e
--- /dev/null
+++ b/tooldata/data/COPYRIGHT
@@ -0,0 +1,3 @@
+Copyright [YEAR] The Vanadium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file.
\ No newline at end of file
diff --git a/tooldata/data/LICENSE b/tooldata/data/LICENSE
new file mode 100644
index 0000000..411db13
--- /dev/null
+++ b/tooldata/data/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2015 The Vanadium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tooldata/data/PATENTS b/tooldata/data/PATENTS
new file mode 100644
index 0000000..d52cc55
--- /dev/null
+++ b/tooldata/data/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Vanadium project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Vanadium, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Vanadium. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Vanadium or any code incorporated within this
+implementation of Vanadium constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Vanadium
+shall terminate as of the date such litigation is filed.
diff --git a/tooldata/data/VERSION b/tooldata/data/VERSION
new file mode 100644
index 0000000..603150b
--- /dev/null
+++ b/tooldata/data/VERSION
@@ -0,0 +1 @@
+jiri-0.1
diff --git a/tooldata/data/aliases.v1.xml b/tooldata/data/aliases.v1.xml
new file mode 100644
index 0000000..d013d35
--- /dev/null
+++ b/tooldata/data/aliases.v1.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" ?>
+<aliases>
+ <email>
+ <canonical>aghassemi@google.com</canonical>
+ <alias>aghassemi@aghassemi-macbookpro.roam.corp.google.com</alias>
+ </email>
+ <email>
+ <canonical>sadovsky@google.com</canonical>
+ <alias>asadovsky@gmail.com</alias>
+ </email>
+ <email>
+ <canonical>nevenag@google.com</canonical>
+ <alias>nevena.golubovic@gmail.com</alias>
+ </email>
+ <email>
+ <canonical>jregan@google.com</canonical>
+ <alias>git-jregan.google.com</alias>
+ </email>
+ <email>
+ <canonical>rjkroege@google.com</canonical>
+ <alias>rjkroege@chromium.org</alias>
+ </email>
+ <email>
+ <canonical>sjr@google.com</canonical>
+ <alias>sjr@jdns.org</alias>
+ </email>
+ <name>
+ <canonical>Ali Ghassemi</canonical>
+ <alias>aghassemi</alias>
+ </name>
+ <name>
+ <canonical>Ankur Taly</canonical>
+ <alias>Ankur</alias>
+ </name>
+ <name>
+ <canonical>Benjamin Prosnitz</canonical>
+ <alias>Benj Prosnitz</alias>
+ </name>
+ <name>
+ <canonical>Dave Presotto</canonical>
+ <alias>David Why Use Two When One Will Do Presotto</alias>
+ <alias>David Presotto</alias>
+ </name>
+ <name>
+ <canonical>Gautham Thambidorai</canonical>
+ <alias>Gautham</alias>
+ <alias>gauthamt</alias>
+ </name>
+ <name>
+ <canonical>Elizabeth Churchill</canonical>
+ <alias>xeeliz</alias>
+ </name>
+ <name>
+ <canonical>Ellen Isaacs</canonical>
+ <alias>lnizix</alias>
+ </name>
+ <name>
+ <canonical>Jeffrey Regan</canonical>
+ <alias>jregan</alias>
+ </name>
+ <name>
+ <canonical>Nicolas LaCasse</canonical>
+ <alias>Nicolas Lacasse</alias>
+ </name>
+ <name>
+ <canonical>William Leler</canonical>
+ <alias>Wm Leler</alias>
+ <alias>wmleler</alias>
+ </name>
+</aliases>
diff --git a/tooldata/data/config.v1.xml b/tooldata/data/config.v1.xml
new file mode 100644
index 0000000..3862c5c
--- /dev/null
+++ b/tooldata/data/config.v1.xml
@@ -0,0 +1,275 @@
+<?xml version="1.0" ?>
+<config>
+ <apiCheckProjects>
+ <project>release.go.jiri</project>
+ <project>release.go.v23</project>
+ <project>release.go.x.devtools</project>
+ <project>release.go.x.lib</project>
+ </apiCheckProjects>
+ <copyrightCheckProjects>
+ <project>release.go.jiri</project>
+ <project>release.go.v23</project>
+ <project>release.go.x.devtools</project>
+ <project>release.go.x.jni</project>
+ <project>release.go.x.lib</project>
+ <project>release.go.x.ref</project>
+ <project>release.java</project>
+ <project>release.js.core</project>
+ <project>release.js.syncbase</project>
+ <project>release.mojo.discovery</project>
+ <project>release.mojo.shared</project>
+ <project>release.mojo.syncbase</project>
+ <project>release.mojo.v23proxy</project>
+ <project>release.projects.baku</project>
+ <project>release.projects.browser</project>
+ <project>release.projects.chat</project>
+ <project>release.projects.croupier</project>
+ <project>release.projects.media-sharing</project>
+ <project>release.projects.physical-lock</project>
+ <project>release.projects.pipe2browser</project>
+ <project>release.projects.playground</project>
+ <project>release.projects.reader</project>
+ <project>release.projects.sensorlog</project>
+ <project>release.projects.syncslides</project>
+ <project>release.projects.travel</project>
+ <project>release.projects.todos</project>
+ <project>website</project>
+ </copyrightCheckProjects>
+ <goWorkspaces>
+ <workspace>infrastructure/go</workspace>
+ <workspace>release/go</workspace>
+ <workspace>release/javascript/core/go</workspace>
+ <workspace>release/projects/physical-lock/go</workspace>
+ <workspace>release/projects/sensorlog/go</workspace>
+ <workspace>roadmap/go</workspace>
+ <workspace>third_party/go</workspace>
+ </goWorkspaces>
+ <jenkinsMatrixJobs>
+ <job arch="false" OS="true" parts="false" showOS="true">third_party-go-build</job>
+ <job arch="false" OS="true" parts="false" showOS="true">third_party-go-test</job>
+ <job arch="false" OS="true" parts="true" showOS="false">third_party-go-race</job>
+ <!-- TODO(spetrovic): this is flaky due to profile issues. Re-enable after fixing.
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-android-build</job>
+ -->
+ <job arch="false" OS="true" parts="false" showOS="false">vanadium-bootstrap</job>
+ <job arch="true" OS="true" parts="false" showOS="true">vanadium-go-build</job>
+ <job arch="true" OS="true" parts="false" showOS="true">vanadium-go-test</job>
+ <job arch="false" OS="true" parts="true" showOS="false">vanadium-go-race</job>
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-integration-test</job>
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-java-test</job>
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-website-site</job>
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-website-tutorials-core</job>
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-website-tutorials-external</job>
+ <job arch="false" OS="true" parts="false" showOS="true">vanadium-website-tutorials-java</job>
+ </jenkinsMatrixJobs>
+ <projectTests>
+ <project name="release.go.jiri">
+ <test>go</test>
+ <test>java</test>
+ <test>javascript</test>
+ <test>projects</test>
+ <test>vanadium-bootstrap</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.go.v23">
+ <test>go</test>
+ <test>java</test>
+ <test>javascript</test>
+ <test>mojo</test>
+ <test>projects</test>
+ <test>vanadium-bootstrap</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.go.x.devtools">
+ <test>go</test>
+ <test>java</test>
+ <test>javascript</test>
+ <test>mojo</test>
+ <test>projects</test>
+ <test>third_party-go</test>
+ <test>vanadium-bootstrap</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.go.x.jni">
+ <test>java</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.go.x.lib">
+ <test>go</test>
+ <test>java</test>
+ <test>javascript</test>
+ <test>mojo</test>
+ <test>projects</test>
+ <test>vanadium-bootstrap</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.go.x.ref">
+ <test>go</test>
+ <test>java</test>
+ <test>javascript</test>
+ <test>mojo</test>
+ <test>projects</test>
+ <test>vanadium-bootstrap</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.java">
+ <test>java</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.js.core">
+ <test>javascript</test>
+ <test>projects</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.mojo.discovery">
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.mojo.shared">
+ <test>mojo</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.mojo.syncbase">
+ <test>mojo</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.mojo.v23proxy">
+ <test>mojo</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.projects.baku">
+ <test>vanadium-copyright</test>
+ <test>vanadium-baku-test</test>
+ </project>
+ <project name="release.projects.croupier">
+ <test>vanadium-copyright</test>
+ <test>vanadium-croupier-unit</test>
+ </project>
+ <project name="release.projects.playground">
+ <test>vanadium-copyright</test>
+ <test>vanadium-playground-test</test>
+ </project>
+ <project name="release.projects.reader">
+ <test>vanadium-copyright</test>
+ <test>vanadium-reader-test</test>
+ </project>
+ <project name="release.projects.sensorlog">
+ <test>go</test>
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.projects.syncslides">
+ <test>vanadium-copyright</test>
+ </project>
+ <project name="release.projects.travel">
+ <test>vanadium-copyright</test>
+ <test>vanadium-travel-test</test>
+ </project>
+ <project name="third_party">
+ <test>go</test>
+ <test>javascript</test>
+ <test>projects</test>
+ <test>third_party-go</test>
+ </project>
+ <project name="website">
+ <test>vanadium-bootstrap</test>
+ <test>vanadium-copyright</test>
+ <test>vanadium-website-site</test>
+ <test>vanadium-website-tutorials-core</test>
+ </project>
+ </projectTests>
+ <testDependencies>
+ <test name="third_party-go-race">
+ <dependency>third_party-go-test</dependency>
+ </test>
+ <test name="third_party-go-test">
+ <dependency>third_party-go-build</dependency>
+ </test>
+ <test name="vanadium-playground-test">
+ <dependency>vanadium-go-build</dependency>
+ </test>
+ <test name="vanadium-go-race">
+ <dependency>vanadium-go-test</dependency>
+ </test>
+ <test name="vanadium-go-test">
+ <dependency>vanadium-go-build</dependency>
+ </test>
+ <test name="vanadium-integration-test">
+ <dependency>vanadium-go-build</dependency>
+ </test>
+ </testDependencies>
+ <testGroups>
+ <group name="go">
+ <test>vanadium-go-api</test>
+ <test>vanadium-go-build</test>
+ <test>vanadium-go-depcop</test>
+ <test>vanadium-go-format</test>
+ <test>vanadium-go-generate</test>
+ <test>vanadium-go-race</test>
+ <test>vanadium-go-test</test>
+ <test>vanadium-go-vdl</test>
+ <!-- TODO(sjr): figure out what to do with go vet. It currently produces
+ false positives which we can't workaround with CLs like
+ https://vanadium.googlesource.com/third_party/+/5e07c533eb2dfa525b5d0f3782112a2a5c4b6912,
+ because go vet moved back into core go as of Go 1.5.
+ <test>vanadium-go-vet</test>
+ -->
+ <test>vanadium-integration-test</test>
+ <test>vanadium-regression-test</test>
+ <test>vanadium-prod-services-test</test>
+ <test>vanadium-website-tutorials-core</test>
+ </group>
+ <group name="java">
+ <test>baku-android-build</test>
+ <test>baku-java-test</test>
+ <!-- TODO(spetrovic): this is flaky due to profile issues. Re-enable after fixing.
+ <test>vanadium-android-build</test>
+ -->
+ <test>vanadium-java-test</test>
+ </group>
+ <group name="javascript">
+ <test>vanadium-js-unit</test>
+ <test>vanadium-js-vdl</test>
+ <test>vanadium-js-vdl-audit</test>
+ <test>vanadium-js-vom</test>
+ </group>
+ <group name="mojo">
+ <!-- NOTE(caprita): this is flaky. See v.io/i/1240
+ <test>vanadium-mojo-discovery-test</test>
+ -->
+ <test>vanadium-mojo-syncbase-test</test>
+ <test>vanadium-mojo-v23proxy-unit-test</test>
+ <!-- NOTE(caprita): this is flaky. See v.io/i/1226
+ <test>vanadium-mojo-v23proxy-integration-test</test>
+ -->
+ </group>
+ <group name="projects">
+ <test>vanadium-playground-test</test>
+ </group>
+ <group name="third_party-go">
+ <test>third_party-go-build</test>
+ <test>third_party-go-race</test>
+ <test>third_party-go-test</test>
+ </group>
+ </testGroups>
+ <testParts>
+ <test name="vanadium-go-race">
+ <part>v.io/x/ref/services/device/...</part>
+ <part>v.io/x/ref/services/agent/...,v.io/x/ref/services/internal/...,v.io/x/ref/services/syncbase/...</part>
+ <part>v.io/x/ref/services/...</part>
+ <part>v.io/x/ref/runtime/...</part>
+ <part>v.io/x/ref/...</part>
+ <part>v.io/x/devtools/...</part>
+ </test>
+ <test name="third_party-go-race">
+ <part>golang.org/x/tools/go/ssa/...,golang.org/x/tools/go/pointer/...</part>
+ <part>golang.org/x/tools/...</part>
+ <part>golang.org/x/crypto/...</part>
+ </test>
+ </testParts>
+ <vdlWorkspaces>
+ <workspace>release/go</workspace>
+ <workspace>release/javascript/core/go</workspace>
+ <workspace>release/projects/physical-lock/go</workspace>
+ <workspace>release/projects/sensorlog/go</workspace>
+ <workspace>roadmap/go</workspace>
+ </vdlWorkspaces>
+</config>
diff --git a/tooldata/data/crosstool-ng-1.19.0.config b/tooldata/data/crosstool-ng-1.19.0.config
new file mode 100644
index 0000000..8808fd2
--- /dev/null
+++ b/tooldata/data/crosstool-ng-1.19.0.config
@@ -0,0 +1,538 @@
+#
+# Automatically generated make config: don't edit
+# crosstool-NG 1.19.0 Configuration
+# Sat Jul 12 19:46:11 2014
+#
+CT_CONFIGURE_has_xz=y
+CT_CONFIGURE_has_cvs=y
+CT_CONFIGURE_has_svn=y
+CT_MODULES=y
+
+#
+# Paths and misc options
+#
+
+#
+# crosstool-NG behavior
+#
+# CT_OBSOLETE is not set
+# CT_EXPERIMENTAL is not set
+# CT_DEBUG_CT is not set
+
+#
+# Paths
+#
+CT_LOCAL_TARBALLS_DIR=""
+CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_PREFIX_DIR="/usr/local/vanadium/xgcc/${CT_TARGET}"
+CT_INSTALL_DIR="${CT_PREFIX_DIR}"
+CT_RM_RF_PREFIX_DIR=y
+CT_REMOVE_DOCS=y
+CT_INSTALL_DIR_RO=y
+CT_STRIP_ALL_TOOLCHAIN_EXECUTABLES=y
+
+#
+# Downloading
+#
+# CT_FORBID_DOWNLOAD is not set
+# CT_FORCE_DOWNLOAD is not set
+CT_CONNECT_TIMEOUT=10
+# CT_ONLY_DOWNLOAD is not set
+# CT_USE_MIRROR is not set
+
+#
+# Extracting
+#
+# CT_FORCE_EXTRACT is not set
+CT_OVERIDE_CONFIG_GUESS_SUB=y
+# CT_ONLY_EXTRACT is not set
+CT_PATCH_BUNDLED=y
+# CT_PATCH_LOCAL is not set
+# CT_PATCH_BUNDLED_LOCAL is not set
+# CT_PATCH_LOCAL_BUNDLED is not set
+# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set
+# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set
+# CT_PATCH_NONE is not set
+CT_PATCH_ORDER="bundled"
+
+#
+# Build behavior
+#
+CT_PARALLEL_JOBS=0
+CT_LOAD=""
+CT_USE_PIPES=y
+CT_EXTRA_CFLAGS_FOR_BUILD=""
+CT_EXTRA_LDFLAGS_FOR_BUILD=""
+CT_EXTRA_CFLAGS_FOR_HOST=""
+CT_EXTRA_LDFLAGS_FOR_HOST=""
+# CT_CONFIG_SHELL_SH is not set
+# CT_CONFIG_SHELL_ASH is not set
+CT_CONFIG_SHELL_BASH=y
+# CT_CONFIG_SHELL_CUSTOM is not set
+CT_CONFIG_SHELL="${bash}"
+
+#
+# Logging
+#
+# CT_LOG_ERROR is not set
+# CT_LOG_WARN is not set
+CT_LOG_INFO=y
+# CT_LOG_EXTRA is not set
+# CT_LOG_ALL is not set
+# CT_LOG_DEBUG is not set
+CT_LOG_LEVEL_MAX="INFO"
+# CT_LOG_SEE_TOOLS_WARN is not set
+CT_LOG_PROGRESS_BAR=y
+CT_LOG_TO_FILE=y
+CT_LOG_FILE_COMPRESS=y
+
+#
+# Target options
+#
+CT_ARCH="arm"
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_SUPPORTS_BOTH_ENDIAN=y
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_CPU=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_SUPPORTS_WITH_FLOAT=y
+CT_ARCH_SUPPORTS_WITH_FPU=y
+CT_ARCH_SUPPORTS_SOFTFP=y
+CT_ARCH_DEFAULT_HAS_MMU=y
+CT_ARCH_DEFAULT_LE=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_ARCH=""
+CT_ARCH_CPU=""
+CT_ARCH_TUNE=""
+CT_ARCH_FPU=""
+# CT_ARCH_BE is not set
+CT_ARCH_LE=y
+CT_ARCH_32=y
+CT_ARCH_BITNESS=32
+CT_ARCH_FLOAT_HW=y
+# CT_ARCH_FLOAT_SW is not set
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
+# CT_ARCH_alpha is not set
+CT_ARCH_arm=y
+# CT_ARCH_avr32 is not set
+# CT_ARCH_blackfin is not set
+# CT_ARCH_m68k is not set
+# CT_ARCH_mips is not set
+# CT_ARCH_powerpc is not set
+# CT_ARCH_s390 is not set
+# CT_ARCH_sh is not set
+# CT_ARCH_sparc is not set
+# CT_ARCH_x86 is not set
+CT_ARCH_alpha_AVAILABLE=y
+CT_ARCH_arm_AVAILABLE=y
+CT_ARCH_avr32_AVAILABLE=y
+CT_ARCH_blackfin_AVAILABLE=y
+CT_ARCH_m68k_AVAILABLE=y
+CT_ARCH_microblaze_AVAILABLE=y
+CT_ARCH_mips_AVAILABLE=y
+CT_ARCH_powerpc_AVAILABLE=y
+CT_ARCH_s390_AVAILABLE=y
+CT_ARCH_sh_AVAILABLE=y
+CT_ARCH_sparc_AVAILABLE=y
+CT_ARCH_x86_AVAILABLE=y
+CT_ARCH_SUFFIX=""
+
+#
+# Generic target options
+#
+# CT_MULTILIB is not set
+CT_ARCH_USE_MMU=y
+CT_ARCH_ENDIAN="little"
+
+#
+# Target optimisations
+#
+# CT_ARCH_FLOAT_SOFTFP is not set
+CT_ARCH_FLOAT="hard"
+
+#
+# arm other options
+#
+CT_ARCH_ARM_MODE="arm"
+CT_ARCH_ARM_MODE_ARM=y
+# CT_ARCH_ARM_MODE_THUMB is not set
+# CT_ARCH_ARM_INTERWORKING is not set
+CT_ARCH_ARM_EABI_FORCE=y
+CT_ARCH_ARM_EABI=y
+
+#
+# Toolchain options
+#
+
+#
+# General toolchain options
+#
+CT_FORCE_SYSROOT=y
+CT_USE_SYSROOT=y
+CT_SYSROOT_NAME="sysroot"
+CT_SYSROOT_DIR_PREFIX=""
+CT_WANTS_STATIC_LINK=y
+# CT_STATIC_TOOLCHAIN is not set
+CT_TOOLCHAIN_PKGVERSION=""
+CT_TOOLCHAIN_BUGURL=""
+
+#
+# Tuple completion and aliasing
+#
+CT_TARGET_VENDOR="unknown"
+CT_TARGET_ALIAS_SED_EXPR=""
+CT_TARGET_ALIAS=""
+
+#
+# Toolchain type
+#
+CT_CROSS=y
+# CT_CANADIAN is not set
+CT_TOOLCHAIN_TYPE="cross"
+
+#
+# Build system
+#
+CT_BUILD=""
+CT_BUILD_PREFIX=""
+CT_BUILD_SUFFIX=""
+
+#
+# Misc options
+#
+# CT_TOOLCHAIN_ENABLE_NLS is not set
+
+#
+# Operating System
+#
+CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+CT_KERNEL="linux"
+CT_KERNEL_VERSION="3.10.2"
+# CT_KERNEL_bare_metal is not set
+CT_KERNEL_linux=y
+CT_KERNEL_bare_metal_AVAILABLE=y
+CT_KERNEL_linux_AVAILABLE=y
+CT_KERNEL_V_3_10=y
+# CT_KERNEL_V_3_9 is not set
+# CT_KERNEL_V_3_8 is not set
+# CT_KERNEL_V_3_7 is not set
+# CT_KERNEL_V_3_6 is not set
+# CT_KERNEL_V_3_5 is not set
+# CT_KERNEL_V_3_4 is not set
+# CT_KERNEL_V_3_3 is not set
+# CT_KERNEL_V_3_2 is not set
+# CT_KERNEL_V_3_1 is not set
+# CT_KERNEL_V_3_0 is not set
+# CT_KERNEL_V_2_6_39 is not set
+# CT_KERNEL_V_2_6_38 is not set
+# CT_KERNEL_V_2_6_37 is not set
+# CT_KERNEL_V_2_6_36 is not set
+# CT_KERNEL_V_2_6_33 is not set
+# CT_KERNEL_V_2_6_32 is not set
+# CT_KERNEL_V_2_6_31 is not set
+# CT_KERNEL_V_2_6_27 is not set
+# CT_KERNEL_LINUX_CUSTOM is not set
+CT_KERNEL_windows_AVAILABLE=y
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
+
+#
+# linux other options
+#
+CT_KERNEL_LINUX_VERBOSITY_0=y
+# CT_KERNEL_LINUX_VERBOSITY_1 is not set
+# CT_KERNEL_LINUX_VERBOSITY_2 is not set
+CT_KERNEL_LINUX_VERBOSE_LEVEL=0
+CT_KERNEL_LINUX_INSTALL_CHECK=y
+
+#
+# Binary utilities
+#
+CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS="binutils"
+CT_BINUTILS_binutils=y
+
+#
+# GNU binutils
+#
+CT_BINUTILS_V_2_22=y
+# CT_BINUTILS_V_2_21_53 is not set
+# CT_BINUTILS_V_2_21_1a is not set
+# CT_BINUTILS_V_2_20_1a is not set
+# CT_BINUTILS_V_2_19_1a is not set
+# CT_BINUTILS_V_2_18a is not set
+CT_BINUTILS_VERSION="2.22"
+CT_BINUTILS_2_22_or_later=y
+CT_BINUTILS_2_21_or_later=y
+CT_BINUTILS_2_20_or_later=y
+CT_BINUTILS_2_19_or_later=y
+CT_BINUTILS_2_18_or_later=y
+CT_BINUTILS_HAS_HASH_STYLE=y
+CT_BINUTILS_HAS_GOLD=y
+CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
+CT_BINUTILS_HAS_PLUGINS=y
+CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
+CT_BINUTILS_FORCE_LD_BFD=y
+CT_BINUTILS_LINKER_LD=y
+# CT_BINUTILS_LINKER_LD_GOLD is not set
+# CT_BINUTILS_LINKER_GOLD_LD is not set
+CT_BINUTILS_LINKERS_LIST="ld"
+CT_BINUTILS_LINKER_DEFAULT="bfd"
+# CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
+# CT_BINUTILS_FOR_TARGET is not set
+
+#
+# binutils other options
+#
+
+#
+# C compiler
+#
+CT_CC="gcc"
+CT_CC_VERSION="4.8.1"
+CT_CC_CORE_PASSES_NEEDED=y
+CT_CC_gcc=y
+# CT_CC_GCC_SHOW_LINARO is not set
+CT_CC_V_4_8_1=y
+# CT_CC_V_4_8_0 is not set
+# CT_CC_V_4_7_3 is not set
+# CT_CC_V_4_7_2 is not set
+# CT_CC_V_4_7_1 is not set
+# CT_CC_V_4_7_0 is not set
+# CT_CC_V_4_6_4 is not set
+# CT_CC_V_4_6_3 is not set
+# CT_CC_V_4_6_2 is not set
+# CT_CC_V_4_6_1 is not set
+# CT_CC_V_4_6_0 is not set
+# CT_CC_V_4_5_3 is not set
+# CT_CC_V_4_5_2 is not set
+# CT_CC_V_4_5_1 is not set
+# CT_CC_V_4_5_0 is not set
+# CT_CC_V_4_4_7 is not set
+# CT_CC_V_4_4_6 is not set
+# CT_CC_V_4_4_5 is not set
+# CT_CC_V_4_4_4 is not set
+# CT_CC_V_4_4_3 is not set
+# CT_CC_V_4_4_2 is not set
+# CT_CC_V_4_4_1 is not set
+# CT_CC_V_4_4_0 is not set
+# CT_CC_V_4_3_6 is not set
+# CT_CC_V_4_3_5 is not set
+# CT_CC_V_4_3_4 is not set
+# CT_CC_V_4_3_3 is not set
+# CT_CC_V_4_3_2 is not set
+# CT_CC_V_4_3_1 is not set
+# CT_CC_V_4_2_4 is not set
+# CT_CC_V_4_2_2 is not set
+CT_CC_GCC_4_2_or_later=y
+CT_CC_GCC_4_3_or_later=y
+CT_CC_GCC_4_4_or_later=y
+CT_CC_GCC_4_5_or_later=y
+CT_CC_GCC_4_6_or_later=y
+CT_CC_GCC_4_7_or_later=y
+CT_CC_GCC_4_8=y
+CT_CC_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_GRAPHITE=y
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_HAS_LTO=y
+CT_CC_GCC_USE_LTO=y
+CT_CC_GCC_HAS_PKGVERSION_BUGURL=y
+CT_CC_GCC_HAS_BUILD_ID=y
+CT_CC_GCC_HAS_LNK_HASH_STYLE=y
+CT_CC_GCC_USE_GMP_MPFR=y
+CT_CC_GCC_USE_MPC=y
+CT_CC_GCC_HAS_LIBQUADMATH=y
+# CT_CC_LANG_FORTRAN is not set
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_JAVA=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+
+#
+# Additional supported languages:
+#
+CT_CC_LANG_CXX=y
+# CT_CC_LANG_JAVA is not set
+
+#
+# gcc other options
+#
+CT_CC_ENABLE_CXX_FLAGS=""
+CT_CC_CORE_EXTRA_CONFIG_ARRAY=""
+CT_CC_EXTRA_CONFIG_ARRAY=""
+CT_CC_STATIC_LIBSTDCXX=y
+# CT_CC_GCC_SYSTEM_ZLIB is not set
+
+#
+# Optimisation features
+#
+
+#
+# Settings for libraries running on target
+#
+CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y
+# CT_CC_GCC_LIBMUDFLAP is not set
+# CT_CC_GCC_LIBGOMP is not set
+# CT_CC_GCC_LIBSSP is not set
+# CT_CC_GCC_LIBQUADMATH is not set
+
+#
+# Misc. obscure options.
+#
+CT_CC_CXA_ATEXIT=y
+# CT_CC_GCC_DISABLE_PCH is not set
+CT_CC_GCC_SJLJ_EXCEPTIONS=m
+CT_CC_GCC_LDBL_128=m
+# CT_CC_GCC_BUILD_ID is not set
+CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y
+# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
+# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
+# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
+CT_CC_GCC_LNK_HASH_STYLE=""
+
+#
+# C-library
+#
+CT_LIBC="eglibc"
+CT_LIBC_VERSION="2_17"
+CT_LIBC_eglibc=y
+# CT_LIBC_glibc is not set
+# CT_LIBC_uClibc is not set
+CT_LIBC_eglibc_AVAILABLE=y
+CT_LIBC_EGLIBC_V_2_17=y
+# CT_LIBC_EGLIBC_V_2_16 is not set
+# CT_LIBC_EGLIBC_V_2_15 is not set
+# CT_LIBC_EGLIBC_V_2_14 is not set
+# CT_LIBC_EGLIBC_V_2_13 is not set
+# CT_LIBC_EGLIBC_V_2_12 is not set
+# CT_LIBC_EGLIBC_V_2_11 is not set
+# CT_LIBC_EGLIBC_V_2_10 is not set
+# CT_LIBC_EGLIBC_V_2_9 is not set
+# CT_LIBC_EGLIBC_V_TRUNK is not set
+CT_LIBC_EGLIBC_2_16_or_later=y
+CT_EGLIBC_REVISION="HEAD"
+# CT_EGLIBC_HTTP is not set
+# CT_EGLIBC_CHECKOUT is not set
+# CT_EGLIBC_OPT_SIZE is not set
+# CT_EGLIBC_CUSTOM_CONFIG is not set
+CT_LIBC_glibc_AVAILABLE=y
+CT_LIBC_mingw_AVAILABLE=y
+CT_LIBC_newlib_AVAILABLE=y
+CT_LIBC_none_AVAILABLE=y
+CT_LIBC_uClibc_AVAILABLE=y
+CT_LIBC_SUPPORT_THREADS_ANY=y
+CT_LIBC_SUPPORT_NPTL=y
+CT_LIBC_SUPPORT_LINUXTHREADS=y
+CT_THREADS="nptl"
+
+#
+# Common C library options
+#
+CT_THREADS_NPTL=y
+# CT_THREADS_LINUXTHREADS is not set
+CT_LIBC_XLDD=y
+
+#
+# eglibc other options
+#
+CT_LIBC_GLIBC_MAY_FORCE_PORTS=y
+CT_LIBC_glibc_familly=y
+CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_LIBC_GLIBC_CONFIGPARMS=""
+CT_LIBC_GLIBC_EXTRA_CFLAGS=""
+CT_LIBC_EXTRA_CC_ARGS=""
+# CT_LIBC_DISABLE_VERSIONING is not set
+CT_LIBC_OLDEST_ABI=""
+CT_LIBC_GLIBC_FORCE_UNWIND=y
+CT_LIBC_GLIBC_USE_PORTS=y
+CT_LIBC_ADDONS_LIST=""
+
+#
+# WARNING !!!
+#
+
+#
+# For glibc >= 2.8, it can happen that the tarballs
+#
+
+#
+# for the addons are not available for download.
+#
+
+#
+# If that happens, bad luck... Try a previous version
+#
+
+#
+# or try again later... :-(
+#
+# CT_LIBC_LOCALES is not set
+# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set
+CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y
+# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_LIBC_GLIBC_MIN_KERNEL="3.10.2"
+
+#
+# Debug facilities
+#
+# CT_DEBUG_dmalloc is not set
+# CT_DEBUG_duma is not set
+# CT_DEBUG_gdb is not set
+# CT_DEBUG_ltrace is not set
+# CT_DEBUG_strace is not set
+
+#
+# Companion libraries
+#
+CT_COMPLIBS_NEEDED=y
+CT_GMP_NEEDED=y
+CT_MPFR_NEEDED=y
+CT_ISL_NEEDED=y
+CT_CLOOG_NEEDED=y
+CT_MPC_NEEDED=y
+CT_COMPLIBS=y
+CT_GMP=y
+CT_MPFR=y
+CT_ISL=y
+CT_CLOOG=y
+CT_MPC=y
+CT_GMP_V_5_1_1=y
+# CT_GMP_V_5_0_2 is not set
+# CT_GMP_V_5_0_1 is not set
+# CT_GMP_V_4_3_2 is not set
+# CT_GMP_V_4_3_1 is not set
+# CT_GMP_V_4_3_0 is not set
+CT_GMP_VERSION="5.1.1"
+CT_MPFR_V_3_1_2=y
+# CT_MPFR_V_3_1_0 is not set
+# CT_MPFR_V_3_0_1 is not set
+# CT_MPFR_V_3_0_0 is not set
+# CT_MPFR_V_2_4_2 is not set
+# CT_MPFR_V_2_4_1 is not set
+# CT_MPFR_V_2_4_0 is not set
+CT_MPFR_VERSION="3.1.2"
+CT_ISL_V_0_11_1=y
+CT_ISL_VERSION="0.11.1"
+CT_CLOOG_V_0_18_0=y
+CT_CLOOG_VERSION="0.18.0"
+CT_CLOOG_0_18_or_later=y
+CT_MPC_V_1_0_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_V_0_9 is not set
+# CT_MPC_V_0_8_2 is not set
+# CT_MPC_V_0_8_1 is not set
+# CT_MPC_V_0_7 is not set
+CT_MPC_VERSION="1.0.1"
+
+#
+# Companion libraries common options
+#
+# CT_COMPLIBS_CHECK is not set
diff --git a/tooldata/data/crosstool-ng-1.20.0.config b/tooldata/data/crosstool-ng-1.20.0.config
new file mode 100644
index 0000000..191cfb5
--- /dev/null
+++ b/tooldata/data/crosstool-ng-1.20.0.config
@@ -0,0 +1,633 @@
+#
+# Automatically generated make config: don't edit
+# crosstool-NG 1.20.0 Configuration
+# Wed Apr 29 23:28:05 2015
+#
+CT_CONFIGURE_has_make381=y
+CT_CONFIGURE_has_xz=y
+CT_CONFIGURE_has_cvs=y
+CT_CONFIGURE_has_svn=y
+CT_MODULES=y
+
+#
+# Paths and misc options
+#
+
+#
+# crosstool-NG behavior
+#
+# CT_OBSOLETE is not set
+# CT_EXPERIMENTAL is not set
+# CT_DEBUG_CT is not set
+
+#
+# Paths
+#
+CT_LOCAL_TARBALLS_DIR=""
+CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_PREFIX_DIR="/usr/local/vanadium/xgcc/${CT_TARGET}"
+CT_INSTALL_DIR="${CT_PREFIX_DIR}"
+CT_RM_RF_PREFIX_DIR=y
+CT_REMOVE_DOCS=y
+CT_INSTALL_DIR_RO=y
+CT_STRIP_ALL_TOOLCHAIN_EXECUTABLES=y
+
+#
+# Downloading
+#
+# CT_FORBID_DOWNLOAD is not set
+# CT_FORCE_DOWNLOAD is not set
+CT_CONNECT_TIMEOUT=10
+# CT_ONLY_DOWNLOAD is not set
+# CT_USE_MIRROR is not set
+
+#
+# Extracting
+#
+# CT_FORCE_EXTRACT is not set
+CT_OVERIDE_CONFIG_GUESS_SUB=y
+# CT_ONLY_EXTRACT is not set
+CT_PATCH_BUNDLED=y
+# CT_PATCH_LOCAL is not set
+# CT_PATCH_BUNDLED_LOCAL is not set
+# CT_PATCH_LOCAL_BUNDLED is not set
+# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set
+# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set
+# CT_PATCH_NONE is not set
+CT_PATCH_ORDER="bundled"
+
+#
+# Build behavior
+#
+CT_PARALLEL_JOBS=0
+CT_LOAD=""
+CT_USE_PIPES=y
+CT_EXTRA_CFLAGS_FOR_BUILD=""
+CT_EXTRA_LDFLAGS_FOR_BUILD=""
+CT_EXTRA_CFLAGS_FOR_HOST=""
+CT_EXTRA_LDFLAGS_FOR_HOST=""
+# CT_CONFIG_SHELL_SH is not set
+# CT_CONFIG_SHELL_ASH is not set
+CT_CONFIG_SHELL_BASH=y
+# CT_CONFIG_SHELL_CUSTOM is not set
+CT_CONFIG_SHELL="${bash}"
+
+#
+# Logging
+#
+# CT_LOG_ERROR is not set
+# CT_LOG_WARN is not set
+# CT_LOG_INFO is not set
+# CT_LOG_EXTRA is not set
+CT_LOG_ALL=y
+# CT_LOG_DEBUG is not set
+CT_LOG_LEVEL_MAX="ALL"
+# CT_LOG_SEE_TOOLS_WARN is not set
+CT_LOG_TO_FILE=y
+CT_LOG_FILE_COMPRESS=y
+
+#
+# Target options
+#
+CT_ARCH="arm"
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_SUPPORTS_BOTH_ENDIAN=y
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_CPU=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_SUPPORTS_WITH_FLOAT=y
+CT_ARCH_SUPPORTS_WITH_FPU=y
+CT_ARCH_SUPPORTS_SOFTFP=y
+CT_ARCH_DEFAULT_HAS_MMU=y
+CT_ARCH_DEFAULT_LE=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_ARCH=""
+CT_ARCH_CPU=""
+CT_ARCH_TUNE=""
+CT_ARCH_FPU=""
+# CT_ARCH_BE is not set
+CT_ARCH_LE=y
+CT_ARCH_32=y
+# CT_ARCH_64 is not set
+CT_ARCH_BITNESS=32
+CT_ARCH_FLOAT_HW=y
+# CT_ARCH_FLOAT_SW is not set
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
+# CT_ARCH_alpha is not set
+CT_ARCH_arm=y
+# CT_ARCH_avr32 is not set
+# CT_ARCH_blackfin is not set
+# CT_ARCH_m68k is not set
+# CT_ARCH_mips is not set
+# CT_ARCH_powerpc is not set
+# CT_ARCH_s390 is not set
+# CT_ARCH_sh is not set
+# CT_ARCH_sparc is not set
+# CT_ARCH_x86 is not set
+CT_ARCH_alpha_AVAILABLE=y
+CT_ARCH_arm_AVAILABLE=y
+CT_ARCH_avr32_AVAILABLE=y
+CT_ARCH_blackfin_AVAILABLE=y
+CT_ARCH_m68k_AVAILABLE=y
+CT_ARCH_microblaze_AVAILABLE=y
+CT_ARCH_mips_AVAILABLE=y
+CT_ARCH_powerpc_AVAILABLE=y
+CT_ARCH_s390_AVAILABLE=y
+CT_ARCH_sh_AVAILABLE=y
+CT_ARCH_sparc_AVAILABLE=y
+CT_ARCH_x86_AVAILABLE=y
+CT_ARCH_SUFFIX=""
+
+#
+# Generic target options
+#
+# CT_MULTILIB is not set
+CT_ARCH_USE_MMU=y
+CT_ARCH_ENDIAN="little"
+
+#
+# Target optimisations
+#
+# CT_ARCH_FLOAT_AUTO is not set
+# CT_ARCH_FLOAT_SOFTFP is not set
+CT_ARCH_FLOAT="hard"
+
+#
+# arm other options
+#
+CT_ARCH_ARM_MODE="arm"
+CT_ARCH_ARM_MODE_ARM=y
+# CT_ARCH_ARM_MODE_THUMB is not set
+# CT_ARCH_ARM_INTERWORKING is not set
+CT_ARCH_ARM_EABI_FORCE=y
+CT_ARCH_ARM_EABI=y
+
+#
+# Toolchain options
+#
+
+#
+# General toolchain options
+#
+CT_FORCE_SYSROOT=y
+CT_USE_SYSROOT=y
+CT_SYSROOT_NAME="sysroot"
+CT_SYSROOT_DIR_PREFIX=""
+CT_WANTS_STATIC_LINK=y
+# CT_STATIC_TOOLCHAIN is not set
+CT_TOOLCHAIN_PKGVERSION=""
+CT_TOOLCHAIN_BUGURL=""
+
+#
+# Tuple completion and aliasing
+#
+CT_TARGET_VENDOR="unknown"
+CT_TARGET_ALIAS_SED_EXPR=""
+CT_TARGET_ALIAS=""
+
+#
+# Toolchain type
+#
+CT_CROSS=y
+# CT_CANADIAN is not set
+CT_TOOLCHAIN_TYPE="cross"
+
+#
+# Build system
+#
+CT_BUILD=""
+CT_BUILD_PREFIX=""
+CT_BUILD_SUFFIX=""
+
+#
+# Misc options
+#
+# CT_TOOLCHAIN_ENABLE_NLS is not set
+
+#
+# Operating System
+#
+CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+CT_KERNEL="linux"
+CT_KERNEL_VERSION="3.10.47"
+# CT_KERNEL_bare_metal is not set
+CT_KERNEL_linux=y
+CT_KERNEL_bare_metal_AVAILABLE=y
+CT_KERNEL_linux_AVAILABLE=y
+# CT_KERNEL_V_3_15 is not set
+# CT_KERNEL_V_3_14 is not set
+# CT_KERNEL_V_3_13 is not set
+# CT_KERNEL_V_3_12 is not set
+# CT_KERNEL_V_3_11 is not set
+CT_KERNEL_V_3_10=y
+# CT_KERNEL_V_3_9 is not set
+# CT_KERNEL_V_3_8 is not set
+# CT_KERNEL_V_3_7 is not set
+# CT_KERNEL_V_3_6 is not set
+# CT_KERNEL_V_3_5 is not set
+# CT_KERNEL_V_3_4 is not set
+# CT_KERNEL_V_3_3 is not set
+# CT_KERNEL_V_3_2 is not set
+# CT_KERNEL_V_3_1 is not set
+# CT_KERNEL_V_3_0 is not set
+# CT_KERNEL_V_2_6_39 is not set
+# CT_KERNEL_V_2_6_38 is not set
+# CT_KERNEL_V_2_6_37 is not set
+# CT_KERNEL_V_2_6_36 is not set
+# CT_KERNEL_V_2_6_33 is not set
+# CT_KERNEL_V_2_6_32 is not set
+# CT_KERNEL_V_2_6_31 is not set
+# CT_KERNEL_V_2_6_27 is not set
+# CT_KERNEL_LINUX_CUSTOM is not set
+CT_KERNEL_windows_AVAILABLE=y
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
+
+#
+# linux other options
+#
+CT_KERNEL_LINUX_VERBOSITY_0=y
+# CT_KERNEL_LINUX_VERBOSITY_1 is not set
+# CT_KERNEL_LINUX_VERBOSITY_2 is not set
+CT_KERNEL_LINUX_VERBOSE_LEVEL=0
+CT_KERNEL_LINUX_INSTALL_CHECK=y
+
+#
+# Binary utilities
+#
+CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS="binutils"
+CT_BINUTILS_binutils=y
+
+#
+# GNU binutils
+#
+CT_BINUTILS_V_2_22=y
+# CT_BINUTILS_V_2_21_53 is not set
+# CT_BINUTILS_V_2_21_1a is not set
+# CT_BINUTILS_V_2_20_1a is not set
+# CT_BINUTILS_V_2_19_1a is not set
+# CT_BINUTILS_V_2_18a is not set
+CT_BINUTILS_VERSION="2.22"
+CT_BINUTILS_2_22_or_later=y
+CT_BINUTILS_2_21_or_later=y
+CT_BINUTILS_2_20_or_later=y
+CT_BINUTILS_2_19_or_later=y
+CT_BINUTILS_2_18_or_later=y
+CT_BINUTILS_HAS_HASH_STYLE=y
+CT_BINUTILS_HAS_GOLD=y
+CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
+CT_BINUTILS_HAS_PLUGINS=y
+CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
+CT_BINUTILS_FORCE_LD_BFD=y
+CT_BINUTILS_LINKER_LD=y
+# CT_BINUTILS_LINKER_LD_GOLD is not set
+# CT_BINUTILS_LINKER_GOLD_LD is not set
+CT_BINUTILS_LINKERS_LIST="ld"
+CT_BINUTILS_LINKER_DEFAULT="bfd"
+# CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
+# CT_BINUTILS_FOR_TARGET is not set
+
+#
+# binutils other options
+#
+
+#
+# C-library
+#
+CT_LIBC="glibc"
+CT_LIBC_VERSION="2.19"
+# CT_LIBC_eglibc is not set
+CT_LIBC_glibc=y
+# CT_LIBC_musl is not set
+# CT_LIBC_uClibc is not set
+CT_LIBC_eglibc_AVAILABLE=y
+CT_THREADS="nptl"
+CT_LIBC_glibc_AVAILABLE=y
+CT_LIBC_GLIBC_V_2_19=y
+# CT_LIBC_GLIBC_V_2_18 is not set
+# CT_LIBC_GLIBC_V_2_17 is not set
+# CT_LIBC_GLIBC_V_2_16_0 is not set
+# CT_LIBC_GLIBC_V_2_15 is not set
+# CT_LIBC_GLIBC_V_2_14_1 is not set
+# CT_LIBC_GLIBC_V_2_14 is not set
+# CT_LIBC_GLIBC_V_2_13 is not set
+# CT_LIBC_GLIBC_V_2_12_2 is not set
+# CT_LIBC_GLIBC_V_2_12_1 is not set
+# CT_LIBC_GLIBC_V_2_11_1 is not set
+# CT_LIBC_GLIBC_V_2_11 is not set
+# CT_LIBC_GLIBC_V_2_10_1 is not set
+# CT_LIBC_GLIBC_V_2_9 is not set
+# CT_LIBC_GLIBC_V_2_8 is not set
+CT_LIBC_mingw_AVAILABLE=y
+CT_LIBC_musl_AVAILABLE=y
+CT_LIBC_newlib_AVAILABLE=y
+CT_LIBC_none_AVAILABLE=y
+CT_LIBC_uClibc_AVAILABLE=y
+CT_LIBC_SUPPORT_THREADS_ANY=y
+CT_LIBC_SUPPORT_THREADS_NATIVE=y
+
+#
+# Common C library options
+#
+CT_THREADS_NATIVE=y
+CT_LIBC_XLDD=y
+# CT_LIBC_GLIBC_PORTS_EXTERNAL is not set
+CT_LIBC_GLIBC_MAY_FORCE_PORTS=y
+CT_LIBC_glibc_familly=y
+CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_LIBC_GLIBC_CONFIGPARMS=""
+CT_LIBC_GLIBC_EXTRA_CFLAGS=""
+CT_LIBC_EXTRA_CC_ARGS=""
+# CT_LIBC_DISABLE_VERSIONING is not set
+CT_LIBC_OLDEST_ABI=""
+CT_LIBC_GLIBC_FORCE_UNWIND=y
+CT_LIBC_GLIBC_USE_PORTS=y
+CT_LIBC_ADDONS_LIST=""
+# CT_LIBC_LOCALES is not set
+# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set
+CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y
+# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_LIBC_GLIBC_MIN_KERNEL="3.10.47"
+
+#
+# glibc other options
+#
+
+#
+# WARNING !!!
+#
+
+#
+# For glibc >= 2.8, it can happen that the tarballs
+#
+
+#
+# for the addons are not available for download.
+#
+
+#
+# If that happens, bad luck... Try a previous version
+#
+
+#
+# or try again later... :-(
+#
+
+#
+# C compiler
+#
+CT_CC="gcc"
+CT_CC_VERSION="4.8.1"
+CT_CC_CORE_PASSES_NEEDED=y
+CT_CC_CORE_PASS_1_NEEDED=y
+CT_CC_CORE_PASS_2_NEEDED=y
+CT_CC_gcc=y
+# CT_CC_GCC_SHOW_LINARO is not set
+# CT_CC_V_4_9_1 is not set
+# CT_CC_V_4_9_0 is not set
+# CT_CC_V_4_8_3 is not set
+# CT_CC_V_4_8_2 is not set
+CT_CC_V_4_8_1=y
+# CT_CC_V_4_8_0 is not set
+# CT_CC_V_4_7_4 is not set
+# CT_CC_V_4_7_3 is not set
+# CT_CC_V_4_7_2 is not set
+# CT_CC_V_4_7_1 is not set
+# CT_CC_V_4_7_0 is not set
+# CT_CC_V_4_6_4 is not set
+# CT_CC_V_4_6_3 is not set
+# CT_CC_V_4_6_2 is not set
+# CT_CC_V_4_6_1 is not set
+# CT_CC_V_4_6_0 is not set
+# CT_CC_V_4_5_3 is not set
+# CT_CC_V_4_5_2 is not set
+# CT_CC_V_4_5_1 is not set
+# CT_CC_V_4_5_0 is not set
+# CT_CC_V_4_4_7 is not set
+# CT_CC_V_4_4_6 is not set
+# CT_CC_V_4_4_5 is not set
+# CT_CC_V_4_4_4 is not set
+# CT_CC_V_4_4_3 is not set
+# CT_CC_V_4_4_2 is not set
+# CT_CC_V_4_4_1 is not set
+# CT_CC_V_4_4_0 is not set
+# CT_CC_V_4_3_6 is not set
+# CT_CC_V_4_3_5 is not set
+# CT_CC_V_4_3_4 is not set
+# CT_CC_V_4_3_3 is not set
+# CT_CC_V_4_3_2 is not set
+# CT_CC_V_4_3_1 is not set
+# CT_CC_V_4_2_4 is not set
+# CT_CC_V_4_2_2 is not set
+CT_CC_GCC_4_2_or_later=y
+CT_CC_GCC_4_3_or_later=y
+CT_CC_GCC_4_4_or_later=y
+CT_CC_GCC_4_5_or_later=y
+CT_CC_GCC_4_6_or_later=y
+CT_CC_GCC_4_7_or_later=y
+CT_CC_GCC_4_8=y
+CT_CC_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_GRAPHITE=y
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_HAS_LTO=y
+CT_CC_GCC_USE_LTO=y
+CT_CC_GCC_HAS_PKGVERSION_BUGURL=y
+CT_CC_GCC_HAS_BUILD_ID=y
+CT_CC_GCC_HAS_LNK_HASH_STYLE=y
+CT_CC_GCC_USE_GMP_MPFR=y
+CT_CC_GCC_USE_MPC=y
+CT_CC_GCC_HAS_LIBQUADMATH=y
+CT_CC_GCC_HAS_LIBSANITIZER=y
+# CT_CC_LANG_FORTRAN is not set
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_JAVA=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
+
+#
+# Additional supported languages:
+#
+CT_CC_LANG_CXX=y
+# CT_CC_LANG_JAVA is not set
+
+#
+# gcc other options
+#
+CT_CC_ENABLE_CXX_FLAGS=""
+CT_CC_CORE_EXTRA_CONFIG_ARRAY=""
+CT_CC_EXTRA_CONFIG_ARRAY=""
+CT_CC_STATIC_LIBSTDCXX=y
+# CT_CC_GCC_SYSTEM_ZLIB is not set
+
+#
+# Optimisation features
+#
+
+#
+# Settings for libraries running on target
+#
+CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y
+# CT_CC_GCC_LIBMUDFLAP is not set
+# CT_CC_GCC_LIBGOMP is not set
+# CT_CC_GCC_LIBSSP is not set
+# CT_CC_GCC_LIBQUADMATH is not set
+# CT_CC_GCC_LIBSANITIZER is not set
+
+#
+# Misc. obscure options.
+#
+CT_CC_CXA_ATEXIT=y
+# CT_CC_GCC_DISABLE_PCH is not set
+CT_CC_GCC_SJLJ_EXCEPTIONS=m
+CT_CC_GCC_LDBL_128=m
+# CT_CC_GCC_BUILD_ID is not set
+CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y
+# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
+# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
+# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
+CT_CC_GCC_LNK_HASH_STYLE=""
+CT_CC_GCC_DEC_FLOAT_AUTO=y
+# CT_CC_GCC_DEC_FLOAT_BID is not set
+# CT_CC_GCC_DEC_FLOAT_DPD is not set
+# CT_CC_GCC_DEC_FLOATS_NO is not set
+
+#
+# Debug facilities
+#
+CT_DEBUG_dmalloc=y
+CT_DMALLOC_V_5_5_2=y
+CT_DMALLOC_VERSION="5.5.2"
+CT_DEBUG_duma=y
+CT_DUMA_A=y
+CT_DUMA_SO=y
+CT_DUMA_V_2_5_15=y
+CT_DUMA_VERSION="2_5_15"
+CT_DEBUG_gdb=y
+CT_GDB_CROSS=y
+# CT_GDB_CROSS_STATIC is not set
+# CT_GDB_CROSS_SIM is not set
+# CT_GDB_CROSS_PYTHON is not set
+CT_GDB_CROSS_EXTRA_CONFIG_ARRAY=""
+CT_GDB_NATIVE=y
+# CT_GDB_NATIVE_STATIC is not set
+CT_GDB_GDBSERVER=y
+CT_GDB_GDBSERVER_HAS_IPA_LIB=y
+CT_GDB_GDBSERVER_STATIC=y
+
+#
+# gdb version
+#
+# CT_DEBUG_GDB_SHOW_LINARO is not set
+CT_GDB_V_7_8=y
+# CT_GDB_V_7_7_1 is not set
+# CT_GDB_V_7_7 is not set
+# CT_GDB_V_7_6_1 is not set
+# CT_GDB_V_7_5_1 is not set
+# CT_GDB_V_7_4_1 is not set
+# CT_GDB_V_7_4 is not set
+# CT_GDB_V_7_3_1 is not set
+# CT_GDB_V_7_3a is not set
+# CT_GDB_V_7_2a is not set
+# CT_GDB_V_7_1a is not set
+# CT_GDB_V_7_0_1a is not set
+# CT_GDB_V_7_0a is not set
+# CT_GDB_V_6_8a is not set
+CT_GDB_7_2_or_later=y
+CT_GDB_7_0_or_later=y
+CT_GDB_HAS_PKGVERSION_BUGURL=y
+CT_GDB_HAS_PYTHON=y
+CT_GDB_INSTALL_GDBINIT=y
+CT_GDB_VERSION="7.8"
+CT_DEBUG_ltrace=y
+CT_LTRACE_V_0_7_3=y
+# CT_LTRACE_V_0_5_3 is not set
+# CT_LTRACE_V_0_5_2 is not set
+CT_LTRACE_VERSION="0.7.3"
+CT_DEBUG_strace=y
+CT_STRACE_V_4_8=y
+# CT_STRACE_V_4_7 is not set
+# CT_STRACE_V_4_6 is not set
+# CT_STRACE_V_4_5_20 is not set
+# CT_STRACE_V_4_5_19 is not set
+# CT_STRACE_V_4_5_18 is not set
+CT_STRACE_VERSION="4.8"
+
+#
+# Companion libraries
+#
+CT_COMPLIBS_NEEDED=y
+CT_GMP_NEEDED=y
+CT_MPFR_NEEDED=y
+CT_ISL_NEEDED=y
+CT_CLOOG_NEEDED=y
+CT_MPC_NEEDED=y
+CT_COMPLIBS=y
+CT_GMP=y
+CT_MPFR=y
+CT_ISL=y
+CT_CLOOG=y
+CT_MPC=y
+CT_LIBELF_TARGET=y
+# CT_GMP_V_5_1_3 is not set
+CT_GMP_V_5_1_1=y
+# CT_GMP_V_5_0_2 is not set
+# CT_GMP_V_5_0_1 is not set
+# CT_GMP_V_4_3_2 is not set
+# CT_GMP_V_4_3_1 is not set
+# CT_GMP_V_4_3_0 is not set
+CT_GMP_VERSION="5.1.1"
+CT_MPFR_V_3_1_2=y
+# CT_MPFR_V_3_1_0 is not set
+# CT_MPFR_V_3_0_1 is not set
+# CT_MPFR_V_3_0_0 is not set
+# CT_MPFR_V_2_4_2 is not set
+# CT_MPFR_V_2_4_1 is not set
+# CT_MPFR_V_2_4_0 is not set
+CT_MPFR_VERSION="3.1.2"
+# CT_ISL_V_0_12_2 is not set
+CT_ISL_V_0_11_1=y
+CT_ISL_VERSION="0.11.1"
+# CT_CLOOG_V_0_18_1 is not set
+CT_CLOOG_V_0_18_0=y
+CT_CLOOG_VERSION="0.18.0"
+CT_CLOOG_0_18_or_later=y
+# CT_MPC_V_1_0_2 is not set
+CT_MPC_V_1_0_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_V_0_9 is not set
+# CT_MPC_V_0_8_2 is not set
+# CT_MPC_V_0_8_1 is not set
+# CT_MPC_V_0_7 is not set
+CT_MPC_VERSION="1.0.1"
+
+#
+# libelf version needed to build for target
+#
+CT_LIBELF_V_0_8_13=y
+# CT_LIBELF_V_0_8_12 is not set
+CT_LIBELF_VERSION="0.8.13"
+
+#
+# Companion libraries common options
+#
+# CT_COMPLIBS_CHECK is not set
+
+#
+# Companion tools
+#
+
+#
+# READ HELP before you say 'Y' below !!!
+#
+# CT_COMP_TOOLS is not set
diff --git a/tooldata/data/oncall.v1.xml b/tooldata/data/oncall.v1.xml
new file mode 100644
index 0000000..087f553
--- /dev/null
+++ b/tooldata/data/oncall.v1.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" ?>
+<!--
+ This file has been auto generated. Please don't edit manually.
+-->
+<rotation>
+ <shift>
+ <primary>jlodhia</primary>
+ <secondary>herbertc</secondary>
+ <startDate>Mar 07, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>razvanm</primary>
+ <secondary>hpucha</secondary>
+ <startDate>Mar 14, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>mattr</primary>
+ <secondary>jasoncampbell</secondary>
+ <startDate>Mar 21, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>afergan</primary>
+ <secondary>alexfandrianto</secondary>
+ <startDate>Mar 28, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>kash</primary>
+ <secondary>jingjin</secondary>
+ <startDate>Apr 04, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>herbertc</primary>
+ <secondary>razvanm</secondary>
+ <startDate>Apr 11, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>ivanpi</primary>
+ <secondary>kash</secondary>
+ <startDate>Apr 18, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>jasoncampbell</primary>
+ <secondary>m3b</secondary>
+ <startDate>Apr 25, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>caprita</primary>
+ <secondary>jlodhia</secondary>
+ <startDate>May 02, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>nlacasse</primary>
+ <secondary>suharshs</secondary>
+ <startDate>May 09, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>suharshs</primary>
+ <secondary>nlacasse</secondary>
+ <startDate>May 16, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>rdaoud</primary>
+ <secondary>ribrdb</secondary>
+ <startDate>May 23, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>cnicolaou</primary>
+ <secondary>caprita</secondary>
+ <startDate>May 30, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>ashankar</primary>
+ <secondary>mattr</secondary>
+ <startDate>Jun 06, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>jhahn</primary>
+ <secondary>rdaoud</secondary>
+ <startDate>Jun 13, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>ribrdb</primary>
+ <secondary>aghassemi</secondary>
+ <startDate>Jun 20, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>afergan</primary>
+ <secondary>cierniak</secondary>
+ <startDate>Jun 27, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>gauthamt</primary>
+ <secondary>jyh</secondary>
+ <startDate>Jul 04, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>rosswang</primary>
+ <secondary>rthellend</secondary>
+ <startDate>Jul 11, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>hpucha</primary>
+ <secondary>ivanpi</secondary>
+ <startDate>Jul 18, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>rthellend</primary>
+ <secondary>rosswang</secondary>
+ <startDate>Jul 25, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>sadovsky</primary>
+ <secondary>aghassemi</secondary>
+ <startDate>Aug 01, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>bprosnitz</primary>
+ <secondary>sadovsky</secondary>
+ <startDate>Aug 08, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>spetrovic</primary>
+ <secondary>suharshs</secondary>
+ <startDate>Aug 15, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>suharshs</primary>
+ <secondary>spetrovic</secondary>
+ <startDate>Aug 22, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>toddw</primary>
+ <secondary>youngseokyoon</secondary>
+ <startDate>Aug 29, 2016 08:00:00 AM</startDate>
+ </shift>
+ <shift>
+ <primary>youngseokyoon</primary>
+ <secondary>toddw</secondary>
+ <startDate>Sep 05, 2016 08:00:00 AM</startDate>
+ </shift>
+</rotation>
\ No newline at end of file
diff --git a/tooldata/datadir.go b/tooldata/datadir.go
new file mode 100644
index 0000000..edada0b
--- /dev/null
+++ b/tooldata/datadir.go
@@ -0,0 +1,16 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tooldata
+
+import (
+ "path/filepath"
+
+ "v.io/jiri"
+)
+
+// DataDirPath returns the path to the data directory of the given tool.
+func DataDirPath(jirix *jiri.X, toolName string) (string, error) {
+ return filepath.Join(jirix.Root, "release", "go", "src", "v.io", "x", "devtools", "tooldata", "data"), nil
+}
diff --git a/tooldata/doc.go b/tooldata/doc.go
new file mode 100644
index 0000000..aa20543
--- /dev/null
+++ b/tooldata/doc.go
@@ -0,0 +1,7 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// package tooldata provides routines for locating and reading tool
+// specific data.
+package tooldata
diff --git a/tooldata/oncall.go b/tooldata/oncall.go
new file mode 100644
index 0000000..b1dd61b
--- /dev/null
+++ b/tooldata/oncall.go
@@ -0,0 +1,66 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tooldata
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io/ioutil"
+ "time"
+
+ "v.io/jiri"
+)
+
+type OncallRotation struct {
+ Shifts []OncallShift `xml:"shift"`
+ XMLName xml.Name `xml:"rotation"`
+}
+
+type OncallShift struct {
+ Primary string `xml:"primary"`
+ Secondary string `xml:"secondary"`
+ Date string `xml:"startDate"`
+}
+
+// LoadOncallRotation parses the default oncall schedule file.
+func LoadOncallRotation(jirix *jiri.X) (*OncallRotation, error) {
+ oncallRotationsFile, err := OncallRotationPath(jirix)
+ if err != nil {
+ return nil, err
+ }
+ content, err := ioutil.ReadFile(oncallRotationsFile)
+ if err != nil {
+ return nil, fmt.Errorf("ReadFile(%q) failed: %v", oncallRotationsFile, err)
+ }
+ rotation := OncallRotation{}
+ if err := xml.Unmarshal(content, &rotation); err != nil {
+ return nil, fmt.Errorf("Unmarshal(%q) failed: %v", string(content), err)
+ }
+ return &rotation, nil
+}
+
+// Oncall finds the oncall shift at the given time from the
+// oncall configuration file by comparing timestamps.
+func Oncall(jirix *jiri.X, targetTime time.Time) (*OncallShift, error) {
+ // Parse oncall configuration file.
+ rotation, err := LoadOncallRotation(jirix)
+ if err != nil {
+ return nil, err
+ }
+
+ // Find the oncall at targetTime.
+ layout := "Jan 2, 2006 3:04:05 PM"
+ for i := len(rotation.Shifts) - 1; i >= 0; i-- {
+ shift := rotation.Shifts[i]
+ t, err := time.ParseInLocation(layout, shift.Date, targetTime.Location())
+ if err != nil {
+ return nil, fmt.Errorf("Parse(%q, %v) failed: %v", layout, shift.Date, err)
+ }
+ if targetTime.Unix() >= t.Unix() {
+ return &shift, nil
+ }
+ }
+ return nil, nil
+}
diff --git a/tooldata/oncall_test.go b/tooldata/oncall_test.go
new file mode 100644
index 0000000..32c1e56
--- /dev/null
+++ b/tooldata/oncall_test.go
@@ -0,0 +1,102 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tooldata_test
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+ "time"
+
+ "v.io/jiri"
+ "v.io/jiri/jiritest"
+ "v.io/x/devtools/tooldata"
+)
+
+func createOncallFile(t *testing.T, jirix *jiri.X) {
+ content := `<?xml version="1.0" ?>
+<rotation>
+ <shift>
+ <primary>spetrovic</primary>
+ <secondary>suharshs</secondary>
+ <startDate>Nov 5, 2014 12:00:00 PM</startDate>
+ </shift>
+ <shift>
+ <primary>suharshs</primary>
+ <secondary>jingjin</secondary>
+ <startDate>Nov 12, 2014 12:00:00 PM</startDate>
+ </shift>
+ <shift>
+ <primary>jsimsa</primary>
+ <secondary>toddw</secondary>
+ <startDate>Nov 19, 2014 12:00:00 PM</startDate>
+ </shift>
+</rotation>`
+ oncallRotationsFile, err := tooldata.OncallRotationPath(jirix)
+ if err != nil {
+ t.Fatalf("%v", err)
+ }
+ dir := filepath.Dir(oncallRotationsFile)
+ dirMode := os.FileMode(0700)
+ if err := jirix.NewSeq().MkdirAll(dir, dirMode).Done(); err != nil {
+ t.Fatalf("MkdirAll(%q, %v) failed: %v", dir, dirMode, err)
+ }
+ fileMode := os.FileMode(0644)
+ if err := ioutil.WriteFile(oncallRotationsFile, []byte(content), fileMode); err != nil {
+ t.Fatalf("WriteFile(%q, %q, %v) failed: %v", oncallRotationsFile, content, fileMode, err)
+ }
+}
+
+func TestOncall(t *testing.T) {
+ fake, cleanup := jiritest.NewFakeJiriRoot(t)
+ defer cleanup()
+
+ // Create a oncall.v1.xml file.
+ createOncallFile(t, fake.X)
+ testCases := []struct {
+ targetTime time.Time
+ expectedShift *tooldata.OncallShift
+ }{
+ {
+ time.Date(2013, time.November, 5, 12, 0, 0, 0, time.Local),
+ nil,
+ },
+ {
+ time.Date(2014, time.November, 5, 12, 0, 0, 0, time.Local),
+ &tooldata.OncallShift{
+ Primary: "spetrovic",
+ Secondary: "suharshs",
+ Date: "Nov 5, 2014 12:00:00 PM",
+ },
+ },
+ {
+ time.Date(2014, time.November, 5, 14, 0, 0, 0, time.Local),
+ &tooldata.OncallShift{
+ Primary: "spetrovic",
+ Secondary: "suharshs",
+ Date: "Nov 5, 2014 12:00:00 PM",
+ },
+ },
+ {
+ time.Date(2014, time.November, 20, 14, 0, 0, 0, time.Local),
+ &tooldata.OncallShift{
+ Primary: "jsimsa",
+ Secondary: "toddw",
+ Date: "Nov 19, 2014 12:00:00 PM",
+ },
+ },
+ }
+ for _, test := range testCases {
+ got, err := tooldata.Oncall(fake.X, test.targetTime)
+ if err != nil {
+ t.Fatalf("want no errors, got: %v", err)
+ }
+ if !reflect.DeepEqual(test.expectedShift, got) {
+ t.Fatalf("want %#v, got %#v", test.expectedShift, got)
+ }
+ }
+}
diff --git a/tooldata/paths.go b/tooldata/paths.go
new file mode 100644
index 0000000..14fffa3
--- /dev/null
+++ b/tooldata/paths.go
@@ -0,0 +1,49 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tooldata
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+
+ "v.io/jiri"
+ "v.io/jiri/tool"
+ "v.io/x/lib/host"
+)
+
+// ConfigFilePath returns the path to the tools configuration file.
+func ConfigFilePath(jirix *jiri.X) (string, error) {
+ dataDir, err := DataDirPath(jirix, tool.Name)
+ if err != nil {
+ return "", err
+ }
+ return filepath.Join(dataDir, "config.v1.xml"), nil
+}
+
+// OncallRotationPath returns the path to the oncall rotation file.
+func OncallRotationPath(jirix *jiri.X) (string, error) {
+ dataDir, err := DataDirPath(jirix, tool.Name)
+ if err != nil {
+ return "", err
+ }
+ return filepath.Join(dataDir, "oncall.v1.xml"), nil
+}
+
+// ThirdPartyBinPath returns the path to the given third-party tool
+// taking into account the host and the target Go architecture.
+func ThirdPartyBinPath(jirix *jiri.X, name string) (string, error) {
+ bin := filepath.Join(jirix.Root, "third_party", "go", "bin", name)
+ goArch := os.Getenv("GOARCH")
+ machineArch, err := host.Arch()
+ if err != nil {
+ return "", err
+ }
+ if goArch != "" && goArch != machineArch {
+ bin = filepath.Join(jirix.Root, "third_party", "go", "bin", fmt.Sprintf("%s_%s", runtime.GOOS, goArch), name)
+ }
+ return bin, nil
+}