internal/repos: handle pseudo-versions in imported go.mod (#344)

Fixes #343
diff --git a/internal/repos/modules.go b/internal/repos/modules.go
index 27751d8..f70c7c9 100644
--- a/internal/repos/modules.go
+++ b/internal/repos/modules.go
@@ -18,12 +18,12 @@
 import (
 	"bytes"
 	"encoding/json"
-	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
+	"regexp"
 	"runtime"
 	"strings"
 
@@ -35,6 +35,25 @@
 	Main          bool
 }
 
+var regexMixedVersioning = regexp.MustCompile(`^(.*?)-([0-9]{14})-([a-fA-F0-9]{12})$`)
+
+func toRepoRule(mod module) Repo {
+	var tag, commit string
+
+	if gr := regexMixedVersioning.FindStringSubmatch(mod.Version); gr != nil {
+		commit = gr[3]
+	} else {
+		tag = strings.TrimSuffix(mod.Version, "+incompatible")
+	}
+
+	return Repo{
+		Name:     label.ImportPathToBazelRepoName(mod.Path),
+		GoPrefix: mod.Path,
+		Commit:   commit,
+		Tag:      tag,
+	}
+}
+
 func importRepoRulesModules(filename string) (repos []Repo, err error) {
 	tempDir, err := copyGoModToTemp(filename)
 	if err != nil {
@@ -57,22 +76,7 @@
 			continue
 		}
 
-		var tag, commit string
-		if strings.HasPrefix(mod.Version, "v0.0.0-") {
-			if i := strings.LastIndex(mod.Version, "-"); i < 0 {
-				return nil, fmt.Errorf("failed to parse version for %s: %q", mod.Path, mod.Version)
-			} else {
-				commit = mod.Version[i+1:]
-			}
-		} else {
-			tag = mod.Version
-		}
-		repos = append(repos, Repo{
-			Name:     label.ImportPathToBazelRepoName(mod.Path),
-			GoPrefix: mod.Path,
-			Commit:   commit,
-			Tag:      tag,
-		})
+		repos = append(repos, toRepoRule(mod))
 	}
 
 	return repos, nil
diff --git a/internal/repos/modules_test.go b/internal/repos/modules_test.go
new file mode 100644
index 0000000..1d3ed42
--- /dev/null
+++ b/internal/repos/modules_test.go
@@ -0,0 +1,38 @@
+/* Copyright 2018 The Bazel Authors. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package repos
+
+import "testing"
+
+func TestGoModuleSpecialCases(t *testing.T) {
+	for _, tc := range []struct {
+		in, wantCommit, wantTag string
+	}{
+		{in: "v0.30.0", wantTag: "v0.30.0"},
+		{in: "v0.0.0-20180718195005-e651d75abec6", wantCommit: "e651d75abec6"},
+		{in: "v2.0.0+incompatible", wantTag: "v2.0.0"},
+		{in: "v1.0.0-20170511165959-379148ca0225", wantCommit: "379148ca0225"},
+	} {
+		t.Run(tc.in, func(t *testing.T) {
+			repo := toRepoRule(module{Version: tc.in})
+			if repo.Commit != tc.wantCommit {
+				t.Errorf("commit for %q: got %q; want %q", tc.in, repo.Commit, tc.wantCommit)
+			} else if repo.Tag != tc.wantTag {
+				t.Errorf("tag for %q: got %q; want %q", tc.in, repo.Tag, tc.wantTag)
+			}
+		})
+	}
+}