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)
+ }
+ })
+ }
+}