Merge "devtools: v.io/jiri: move v.io/jiri/jiri to v.io/jiri"
diff --git a/data/oncall.v1.xml b/data/oncall.v1.xml
index 4d53633..c46415f 100644
--- a/data/oncall.v1.xml
+++ b/data/oncall.v1.xml
@@ -4,11 +4,6 @@
 -->
 <rotation>
   <shift>
-    <primary>jingjin</primary>
-    <secondary>cnicolaou</secondary>
-    <startDate>Feb 22, 2016 08:00:00 AM</startDate>
-  </shift>
-  <shift>
     <primary>afergan</primary>
     <secondary>gauthamt</secondary>
     <startDate>Feb 29, 2016 08:00:00 AM</startDate>
diff --git a/internal/golib/go.go b/internal/golib/go.go
index d4592cc..a954aae 100644
--- a/internal/golib/go.go
+++ b/internal/golib/go.go
@@ -11,7 +11,6 @@
 	"bytes"
 	"fmt"
 	"os"
-	"os/exec"
 	"os/user"
 	"regexp"
 	"sort"
@@ -24,6 +23,7 @@
 	"v.io/jiri/project"
 	"v.io/jiri/runutil"
 	"v.io/x/devtools/internal/buildinfo"
+	"v.io/x/lib/lookpath"
 	"v.io/x/lib/metadata"
 	"v.io/x/lib/set"
 )
@@ -70,7 +70,7 @@
 // getPlatform identifies the target platform by querying the go tool
 // for the values of the GOARCH and GOOS environment variables.
 func getPlatform(jirix *jiri.X, env map[string]string) (string, error) {
-	goBin, err := runutil.LookPath("go", env)
+	goBin, err := lookpath.Look(env, "go")
 	if err != nil {
 		return "", err
 	}
@@ -172,7 +172,7 @@
 	// -ignore_unknown:  Silently ignore unknown package paths.
 	vdlArgs := []string{"-ignore_unknown", "generate", "-lang=go"}
 	vdlArgs = append(vdlArgs, goDeps...)
-	vdlBin, err := exec.LookPath("vdl")
+	vdlBin, err := lookpath.Look(env, "vdl")
 	if err != nil {
 		return err
 	}
@@ -350,7 +350,7 @@
 	if len(pkgs) == 0 {
 		pkgs = []string{"."}
 	}
-	goBin, err := runutil.LookPath("go", env)
+	goBin, err := lookpath.Look(env, "go")
 	if err != nil {
 		return nil, err
 	}
diff --git a/jiri-dockergo/go.go b/jiri-dockergo/go.go
index dbbb92f..ec5458e 100644
--- a/jiri-dockergo/go.go
+++ b/jiri-dockergo/go.go
@@ -21,6 +21,7 @@
 	"v.io/jiri/tool"
 	"v.io/x/devtools/internal/golib"
 	"v.io/x/lib/cmdline"
+	"v.io/x/lib/lookpath"
 )
 
 var cmd = &cmdline.Command{
@@ -107,8 +108,8 @@
 	if _, exists := envMap["GOARCH"]; !exists {
 		envMap["GOARCH"] = runtime.GOARCH
 	}
-	if _, err := runutil.LookPath(dockerBin, envMap); err != nil {
-		return fmt.Errorf("%v not found in path: %v", dockerBin, err)
+	if _, err := lookpath.Look(envMap, dockerBin); err != nil {
+		return err
 	}
 	img, err := image(envMap)
 	if err != nil {
diff --git a/jiri-go/go.go b/jiri-go/go.go
index 51573b0..55e37c5 100644
--- a/jiri-go/go.go
+++ b/jiri-go/go.go
@@ -20,6 +20,7 @@
 	"v.io/jiri/tool"
 	"v.io/x/devtools/internal/golib"
 	"v.io/x/lib/cmdline"
+	"v.io/x/lib/lookpath"
 )
 
 // cmdGo represents the "jiri go" command.
@@ -84,7 +85,7 @@
 		return err
 	}
 	// Run the go tool.
-	goBin, err := runutil.LookPath("go", envMap)
+	goBin, err := lookpath.Look(envMap, "go")
 	if err != nil {
 		return err
 	}
diff --git a/jiri-test/internal/test/javascript.go b/jiri-test/internal/test/javascript.go
index 2452e1f..9bed506 100644
--- a/jiri-test/internal/test/javascript.go
+++ b/jiri-test/internal/test/javascript.go
@@ -167,7 +167,7 @@
 	// lines will print chrome's log, which will hopefully give us some useful
 	// info.  Remove this line once the timeout has been fixed.
 	// See https://github.com/vanadium/issues/issues/1182
-	if res.Status == test.TimedOut {
+	if res != nil && res.Status == test.TimedOut {
 		if err := jirix.NewSeq().Last("cat", filepath.Join(jirix.Root, "release", "javascript", "core", "tmp", "chrome.log")); err != nil {
 			fmt.Printf("error catting chrome.log: %v\n", err)
 		}
diff --git a/jiridoc/doc.go b/jiridoc/doc.go
index 5950bf2..d4d9093 100644
--- a/jiridoc/doc.go
+++ b/jiridoc/doc.go
@@ -1960,43 +1960,119 @@
 logic.  This is the reason the shim script is recommended over running the
 binary directly.
 
-The binary is located at [root]/.jiri_root/bin/jiri
+The jiri binary is located at [root]/.jiri_root/bin/jiri
 
 Jiri manifest - Description of manifest files
 
-Jiri manifests are revisioned and stored in a "manifest" repository, that is
-available locally in $JIRI_ROOT/.manifest. The manifest uses the following XML
-schema:
+Jiri manifest files describe the set of projects that get synced and tools that
+get built when running "jiri update".
 
- <manifest>
-   <imports>
-     <import name="default"/>
-     ...
-   </imports>
-   <projects>
-     <project name="release.go.jiri"
-              path="release/go/src/v.io/jiri"
-              protocol="git"
-              name="https://vanadium.googlesource.com/release.go.jiri"
-              revision="HEAD"/>
-     ...
-   </projects>
-   <tools>
-     <tool name="jiri" package="v.io/jiri"/>
-     ...
-   </tools>
- </manifest>
+The first manifest file that jiri reads is in $JIRI_ROOT/.jiri_manifest.  This
+manifest **must** exist for the jiri tool to work.
 
-The <import> element can be used to share settings across multiple manifests.
-Import names are interpreted relative to the $JIRI_ROOT/.manifest/v2 directory.
-Import cycles are not allowed and if a project or a tool is specified multiple
-times, the last specification takes effect. In particular, the elements <project
-name="foo" exclude="true"/> and <tool name="bar" exclude="true"/> can be used to
-exclude previously included projects and tools.
+Usually the manifest in $JIRI_ROOT/.jiri_manifest will import other manifests
+from remote repositories via <import> tags, but it can contain its own list of
+projects and tools as well.
 
-The tool identifies which manifest to use using the following algorithm. If the
-$JIRI_ROOT/.local_manifest file exists, then it is used. Otherwise, the
-$JIRI_ROOT/.manifest/v2/<manifest>.xml file is used, where <manifest> is the
-value of the -manifest command-line flag, which defaults to "default".
+Manifests have the following XML schema:
+
+<manifest>
+  <imports>
+    <import remote="https://vanadium.googlesource.com/manifest"
+            manifest="public"
+            name="manifest"
+    />
+    <localimport file="/path/to/local/manifest"/>
+    ...
+  </imports>
+  <projects>
+    <project name="my-project"
+             path="path/where/project/lives"
+             protocol="git"
+             remote="https://github.com/myorg/foo"
+             revision="ed42c05d8688ab23"
+             remotebranch="my-branch"
+             gerrithost="https://myorg-review.googlesource.com"
+             githooks="path/to/githooks-dir"
+             runhook="path/to/runhook-script"
+    />
+    ...
+  </projects>
+  <tools>
+    <tool name="jiri"
+          package="v.io/jiri"
+          project="release.go.jiri"
+    />
+    ...
+  </tools>
+</manifest>
+
+The <import> and <localimport> tags can be used to share common projects and
+tools across multiple manifests.
+
+A <localimport> tag should be used when the manifest being imported and the
+importing manifest are both in the same repository, or when neither one is in a
+repository.  The "file" attribute is the path to the manifest file being
+imported.  It can be absolute, or relative to the importing manifest file.
+
+If the manifest being imported and the importing manifest are in different
+repositories then an <import> tag must be used, with the following attributes:
+
+* remote (required) - The remote url of the repository containing the manifest
+to be imported
+
+* manifest (required) - The path of the manifest file to be imported, relative
+to the repository root.
+
+* name (optional) - The name of the project corresponding to the manifest
+repository.  If your manifest contains a <project> with the same remote as the
+manifest remote, then the "name" attribute of on the <import> tag should match
+the "name" attribute on the <project>.  Otherwise, jiri will clone the manifest
+repository on every update.
+
+The <project> tags describe the projects to sync, and what state they should
+sync to, accoring to the following attributes:
+
+* name (required) - The name of the project.
+
+* path (required) - The location where the project will be located, relative to
+the jiri root.
+
+* remote (required) - The remote url of the project repository.
+
+* protocol (optional) - The protocol to use when cloning and syncing the repo.
+Currently "git" is the default and only supported protocol.
+
+* remotebranch (optional) - The remote branch that the project will sync to.
+Defaults to "master".  The "remotebranch" attribute is ignored if "revision" is
+specified.
+
+* revision (optional) - The specific revision (usually a git SHA) that the
+project will sync to.  If "revision" is  specified then the "remotebranch"
+attribute is ignored.
+
+* gerrithost (optional) - The url of the Gerrit host for the project.  If
+specified, then running "jiri cl mail" will upload a CL to this Gerrit host.
+
+* githooks (optional) - The path (relative to $JIRI_ROOT) of a directory
+containing git hooks that will be installed in the projects .git/hooks directory
+during each update.
+
+* runhook (optional) - The path (relate to $JIRI_ROOT) of a script that will be
+run during each update.
+
+The <tool> tags describe the tools that will be compiled and installed in
+$JIRI_ROOT/.jiri_root/bin after each update.  The tools must be written in go,
+and are identified by their package name and the project that contains their
+code.  They are configured via the following attributes:
+
+* name (required) - The name of the binary that will be installed in
+  JIRI_ROOT/.jiri_root/bin
+
+* package (required) - The name of the Go package that will be passed to "go
+  build".
+
+* project (required) - The name of the project that contains the source code
+  for the tool.
 */
 package main
diff --git a/presubmit/test.go b/presubmit/test.go
index a37e110..90fb559 100644
--- a/presubmit/test.go
+++ b/presubmit/test.go
@@ -500,7 +500,11 @@
 	path := os.Getenv("PATH")
 	path = strings.Replace(path, oldBinDir, tmpBinDir, -1)
 	path = strings.Replace(path, jirix.BinDir(), tmpBinDir, -1)
-	return map[string]string{"PATH": path}, nil
+	env := map[string]string{
+		"PATH":               path,
+		jiri.PreservePathEnv: "true",
+	}
+	return env, nil
 }
 
 // processTestPartSuffix extracts the test name without part suffix as well