Skip to content

Commit c76d153

Browse files
committed
Check others major versions of packages in estimate
Instead of immediately checking that the repo root path is in the list of packages in Debian, use the full import path (including the potential major version suffix), then check for other major versions if applicable, and finally, check for the repo root. This allows to display that another major version is currently packaged in Debian, and prevents hiding necessary major upgrades to already packaged Go modules with a mismatched version.
1 parent 7bc3609 commit c76d153

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

estimate.go

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ import (
77
"os"
88
"os/exec"
99
"path/filepath"
10+
"regexp"
11+
"strconv"
1012
"strings"
1113

1214
"golang.org/x/tools/go/vcs"
1315
)
1416

17+
// majorVersionRegexp checks if an import path contains a major version suffix.
18+
var majorVersionRegexp = regexp.MustCompile(`([/.])v([0-9]+)$`)
19+
1520
func clone(srcdir, repo string) error {
1621
done := make(chan struct{})
1722
defer close(done)
@@ -64,6 +69,24 @@ func removeVendor(gopath string) (found bool, _ error) {
6469
return found, err
6570
}
6671

72+
// otherVersions guesses the import paths of potential other major version
73+
// of the given module import path, based on [majorVersionRegex].
74+
func otherVersions(mod string) (mods []string) {
75+
matches := majorVersionRegexp.FindStringSubmatch(mod)
76+
if matches == nil {
77+
return
78+
}
79+
matchFull, matchSep, matchVer := matches[0], matches[1], matches[2]
80+
matchIndex := len(mod) - len(matchFull)
81+
prefix := mod[:matchIndex]
82+
version, _ := strconv.Atoi(matchVer)
83+
for v := version - 1; v > 1; v-- {
84+
mods = append(mods, prefix+matchSep+"v"+strconv.Itoa(v))
85+
}
86+
mods = append(mods, prefix)
87+
return
88+
}
89+
6790
func estimate(importpath string) error {
6891
removeTemp := func(path string) {
6992
if err := forceRemoveAll(path); err != nil {
@@ -167,7 +190,6 @@ func estimate(importpath string) error {
167190
// Analyse the dependency graph
168191
var lines []string
169192
seen := make(map[string]bool)
170-
rrseen := make(map[string]bool)
171193
var visit func(n *Node, indent int)
172194
visit = func(n *Node, indent int) {
173195
// Get the module name without its version, as go mod graph
@@ -183,19 +205,36 @@ func estimate(importpath string) error {
183205
if mod == "go" || mod == "toolchain" {
184206
return
185207
}
186-
rr, err := vcs.RepoRootForImportPath(mod, false)
187-
if err != nil {
188-
log.Printf("Could not determine repo path for import path %q: %v\n", mod, err)
189-
return
208+
if _, ok := golangBinaries[mod]; ok {
209+
return // already packaged in Debian
190210
}
191-
if rrseen[rr.Root] {
192-
return
211+
var debianVersion string
212+
// Check for potential other major versions already in Debian.
213+
for _, otherVersion := range otherVersions(mod) {
214+
if _, ok := golangBinaries[otherVersion]; ok {
215+
debianVersion = otherVersion
216+
break
217+
}
193218
}
194-
rrseen[rr.Root] = true
195-
if _, ok := golangBinaries[rr.Root]; ok {
196-
return // already packaged in Debian
219+
if debianVersion == "" {
220+
// When multiple modules are developped in the same repo,
221+
// the repo root is often used as the import path metadata
222+
// in Debian, so we do a last try with that.
223+
rr, err := vcs.RepoRootForImportPath(mod, false)
224+
if err != nil {
225+
log.Printf("Could not determine repo path for import path %q: %v\n", mod, err)
226+
} else if _, ok := golangBinaries[rr.Root]; ok {
227+
// Log info to indicate that it is an approximate match
228+
// but consider that it is packaged and skip the children.
229+
log.Printf("%s is packaged as %s in Debian", mod, rr.Root)
230+
return
231+
}
232+
}
233+
if debianVersion != "" {
234+
lines = append(lines, fmt.Sprintf("%s%s\t(%s in Debian)", strings.Repeat(" ", indent), mod, debianVersion))
235+
} else {
236+
lines = append(lines, fmt.Sprintf("%s%s", strings.Repeat(" ", indent), mod))
197237
}
198-
lines = append(lines, fmt.Sprintf("%s%s", strings.Repeat(" ", indent), rr.Root))
199238
for _, n := range n.children {
200239
visit(n, indent+1)
201240
}

0 commit comments

Comments
 (0)