Cherrypicks for 0.3.4 release (#366)

Cherrypicked the following changes:

* #319 go_repository: add importpath and vcs flags. This allows us to have separate import paths and remote URLs for repositories.
* #362 Fetch buildifier from new location. This allows the buildifier zip to be extracted with the new name.
diff --git a/README.md b/README.md
index 0d8aeb3..5d38e33 100644
--- a/README.md
+++ b/README.md
@@ -146,13 +146,16 @@
 ## go\_repository
 
 ```bzl
-go_repository(name, importpath, remote, commit, tag)
+go_repository(name, importpath, remote, vcs, commit, tag)
 ```
 
 Fetches a remote repository of a Go project, expecting it contains `BUILD`
 files. It is an analogy to `git_repository` but it recognizes importpath
 redirection of Go.
 
+Either `importpath` or `remote` may be specified. To bypass importpath
+redirection, specify both `remote` and `vcs`.
+
 <table class="table table-condensed table-bordered table-params">
   <colgroup>
     <col class="col-param" />
@@ -174,7 +177,7 @@
     <tr>
       <td><code>importpath</code></td>
       <td>
-        <code>String, required</code>
+        <code>String, optional</code>
         <p>An import path in Go, which also provides a default value for the
 	root of the target remote repository</p>
       </td>
@@ -183,8 +186,16 @@
       <td><code>remote</code></td>
       <td>
         <code>String, optional</code>
-        <p>The root of the target remote repository, if this differs from the
-	value of <code>importpath</code></p>
+        <p>The URI of the target remote repository, if this cannot be determined
+        from the value of <code>importpath</code>.</p>
+      </td>
+    </tr>
+    <tr>
+      <td><code>vcs</code></td>
+      <td>
+        <code>String, optional</code>
+        <p>The version control system to use for fetching the repository. Useful
+        for disabling importpath redirection if necessary.</p>
       </td>
     </tr>
     <tr>
@@ -211,7 +222,7 @@
 ## new\_go\_repository
 
 ```bzl
-new_go_repository(name, importpath, remote, commit, tag)
+new_go_repository(name, importpath, remote, vcs, commit, tag)
 ```
 
 Fetches a remote repository of a Go project and automatically generates
@@ -239,7 +250,7 @@
     <tr>
       <td><code>importpath</code></td>
       <td>
-        <code>String, required</code>
+        <code>String, optional</code>
         <p>An import path in Go, which also provides a default value for the
 	root of the target remote repository</p>
       </td>
@@ -248,8 +259,15 @@
       <td><code>remote</code></td>
       <td>
         <code>String, optional</code>
-        <p>The root of the target remote repository, if this differs from the
-	value of <code>importpath</code></p>
+        <p>The URI of the target remote repository, if this differs from the
+        value of <code>importpath</code></p>
+      </td>
+    </tr>
+    <tr>
+      <td><code>vcs</code></td>
+      <td>
+        <code>String, optional</code>
+        <p>The version control system to use for fetching the repository.</p>
       </td>
     </tr>
     <tr>
diff --git a/go/private/go_repositories.bzl b/go/private/go_repositories.bzl
index cf9b82c..66aa86e 100644
--- a/go/private/go_repositories.bzl
+++ b/go/private/go_repositories.bzl
@@ -15,9 +15,9 @@
 load("//go/private:go_repository.bzl", "buildifier_repository_only_for_internal_use", "new_go_repository")
 
 repository_tool_deps = {
-    'buildifier': struct(
+    'buildtools': struct(
         importpath = 'github.com/bazelbuild/buildifier',
-        repo = 'https://github.com/bazelbuild/buildifier',
+        repo = 'https://github.com/bazelbuild/buildtools',
         commit = '4190564903f61ddc94bcfda3dc2cdd32d4b330e5',
     ),
     'tools': struct(
@@ -33,8 +33,10 @@
   # TODO(yugui) Simply use go_repository when we drop support of Bazel 0.3.2.
   buildifier_repository_only_for_internal_use(
       name = "io_bazel_buildifier",
-      commit = repository_tool_deps['buildifier'].commit,
-      importpath = repository_tool_deps['buildifier'].importpath,
+      commit = repository_tool_deps['buildtools'].commit,
+      importpath = repository_tool_deps['buildtools'].importpath,
+      remote = repository_tool_deps['buildtools'].repo,
+      vcs = 'git',
   )
 
   new_go_repository(
diff --git a/go/private/go_repository.bzl b/go/private/go_repository.bzl
index f2b5d7d..5d1b7f9 100644
--- a/go/private/go_repository.bzl
+++ b/go/private/go_repository.bzl
@@ -27,14 +27,18 @@
 
   # TODO(yugui): support submodule?
   # c.f. https://www.bazel.io/versions/master/docs/be/workspace.html#git_repository.init_submodules
-  remote = ctx.attr.remote if ctx.attr.remote else ctx.attr.importpath
+  remote = ctx.attr.remote
+  vcs = ctx.attr.vcs
+  importpath = ctx.attr.importpath
   result = ctx.execute([
       fetch_repo,
       '--dest', ctx.path(''),
       '--remote', remote,
-      '--rev', rev])
+      '--rev', rev,
+      '--vcs', vcs,
+      '--importpath', importpath])
   if result.return_code:
-    fail("failed to fetch %s: %s" % (remote, result.stderr))
+    fail("failed to fetch %s: %s" % (ctx.name, result.stderr))
 
 
 def _new_go_repository_impl(ctx):
@@ -58,8 +62,9 @@
 
 _go_repository_attrs = {
     "build_file_name": attr.string(),
-    "importpath": attr.string(mandatory = True),
+    "importpath": attr.string(),
     "remote": attr.string(),
+    "vcs": attr.string(default="", values=["", "git", "hg", "svn", "bzr"]),
     "commit": attr.string(),
     "tag": attr.string(),
     "build_tags": attr.string_list(),
diff --git a/go/tools/fetch_repo/BUILD b/go/tools/fetch_repo/BUILD
index af27089..acc536a 100644
--- a/go/tools/fetch_repo/BUILD
+++ b/go/tools/fetch_repo/BUILD
@@ -1,7 +1,20 @@
-load("//go:def.bzl", "go_binary")
+load("//go:def.bzl", "go_binary", "go_library", "go_test")
 
 go_binary(
     name = "fetch_repo",
+    library = ":go_default_library",
+)
+
+go_library(
+    name = "go_default_library",
     srcs = ["main.go"],
+    visibility = ["//visibility:private"],
+    deps = ["@org_golang_x_tools//go/vcs:go_default_library"],
+)
+
+go_test(
+    name = "go_default_test",
+    srcs = ["fetch_repo_test.go"],
+    library = ":go_default_library",
     deps = ["@org_golang_x_tools//go/vcs:go_default_library"],
 )
diff --git a/go/tools/fetch_repo/fetch_repo_test.go b/go/tools/fetch_repo/fetch_repo_test.go
new file mode 100644
index 0000000..d057349
--- /dev/null
+++ b/go/tools/fetch_repo/fetch_repo_test.go
@@ -0,0 +1,96 @@
+package main
+
+import (
+	"os"
+	"reflect"
+	"testing"
+
+	"golang.org/x/tools/go/vcs"
+)
+
+var (
+	root = &vcs.RepoRoot{
+		VCS:  vcs.ByCmd("git"),
+		Repo: "https://github.com/bazeltest/rules_go",
+		Root: "github.com/bazeltest/rules_go",
+	}
+)
+
+func TestMain(m *testing.M) {
+	// Replace vcs.RepoRootForImportPath to disable any network calls.
+	repoRootForImportPath = func(_ string, _ bool) (*vcs.RepoRoot, error) {
+		return root, nil
+	}
+	os.Exit(m.Run())
+}
+
+func TestGetRepoRoot(t *testing.T) {
+	for _, tc := range []struct {
+		label      string
+		remote     string
+		cmd        string
+		importpath string
+		r          *vcs.RepoRoot
+	}{
+		{
+			label:      "all",
+			remote:     "https://github.com/bazeltest/rules_go",
+			cmd:        "git",
+			importpath: "github.com/bazeltest/rules_go",
+			r:          root,
+		},
+		{
+			label:      "different remote",
+			remote:     "https://example.com/rules_go",
+			cmd:        "git",
+			importpath: "github.com/bazeltest/rules_go",
+			r: &vcs.RepoRoot{
+				VCS:  vcs.ByCmd("git"),
+				Repo: "https://example.com/rules_go",
+				Root: "github.com/bazeltest/rules_go",
+			},
+		},
+		{
+			label:      "only importpath",
+			importpath: "github.com/bazeltest/rules_go",
+			r:          root,
+		},
+	} {
+		r, err := getRepoRoot(tc.remote, tc.cmd, tc.importpath)
+		if err != nil {
+			t.Errorf("[%s] %v", tc.label, err)
+		}
+		if !reflect.DeepEqual(r, tc.r) {
+			t.Errorf("[%s] Expected %+v, got %+v", tc.label, tc.r, r)
+		}
+	}
+}
+
+func TestGetRepoRoot_error(t *testing.T) {
+	for _, tc := range []struct {
+		label      string
+		remote     string
+		cmd        string
+		importpath string
+	}{
+		{
+			label:  "importpath as remote",
+			remote: "github.com/bazeltest/rules_go",
+		},
+		{
+			label:      "missing vcs",
+			remote:     "https://github.com/bazeltest/rules_go",
+			importpath: "github.com/bazeltest/rules_go",
+		},
+		{
+			label:      "missing remote",
+			cmd:        "git",
+			importpath: "github.com/bazeltest/rules_go",
+		},
+	} {
+		r, err := getRepoRoot(tc.remote, tc.cmd, tc.importpath)
+		if err == nil {
+			t.Errorf("[%s] expected error. Got %+v", tc.label, r)
+		}
+	}
+}
diff --git a/go/tools/fetch_repo/main.go b/go/tools/fetch_repo/main.go
index 92e6d76..d399320 100644
--- a/go/tools/fetch_repo/main.go
+++ b/go/tools/fetch_repo/main.go
@@ -19,19 +19,50 @@
 )
 
 var (
-	remote = flag.String("remote", "", "Go importpath to the repository fetch")
-	rev    = flag.String("rev", "", "target revision")
-	dest   = flag.String("dest", "", "destination directory")
+	remote     = flag.String("remote", "", "The URI of the remote repository. Must be used with the --vcs flag.")
+	cmd        = flag.String("vcs", "", "Version control system to use to fetch the repository. Should be one of: git,hg,svn,bzr. Must be used with the --remote flag.")
+	rev        = flag.String("rev", "", "target revision")
+	dest       = flag.String("dest", "", "destination directory")
+	importpath = flag.String("importpath", "", "Go importpath to the repository fetch")
+
+	// Used for overriding in tests to disable network calls.
+	repoRootForImportPath = vcs.RepoRootForImportPath
 )
 
+func getRepoRoot(remote, cmd, importpath string) (*vcs.RepoRoot, error) {
+	if (cmd == "") != (remote == "") {
+		return nil, fmt.Errorf("--remote should be used with the --vcs flag. If this is an import path, use --importpath instead.")
+	}
+
+	if cmd != "" && remote != "" {
+		v := vcs.ByCmd(cmd)
+		if v == nil {
+			return nil, fmt.Errorf("invalid VCS type: %s", cmd)
+		}
+		return &vcs.RepoRoot{
+			VCS:  v,
+			Repo: remote,
+			Root: importpath,
+		}, nil
+	}
+
+	// User did not give us complete information for VCS / Remote.
+	// Try to figure out the information from the import path.
+	r, err := repoRootForImportPath(importpath, true)
+	if err != nil {
+		return nil, err
+	}
+	if importpath != r.Root {
+		return nil, fmt.Errorf("not a root of a repository: %s", importpath)
+	}
+	return r, nil
+}
+
 func run() error {
-	r, err := vcs.RepoRootForImportPath(*remote, true)
+	r, err := getRepoRoot(*remote, *cmd, *importpath)
 	if err != nil {
 		return err
 	}
-	if *remote != r.Root {
-		return fmt.Errorf("not a root of a repository: %s", *remote)
-	}
 	return r.VCS.CreateAtRev(*dest, r.Repo, *rev)
 }