x/exp/cmd/gorelease: suggest a minor version increment if requirements increase
Fixes golang/go#37564
Change-Id: I1aa8a4178adfad99542a478c1cd0fd6a00e23428
Reviewed-on: https://go-review.googlesource.com/c/exp/+/255880
Trust: Jean de Klerk <deklerk@google.com>
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jean de Klerk <deklerk@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/cmd/gorelease/gorelease.go b/cmd/gorelease/gorelease.go
index cc65a28..380e25a 100644
--- a/cmd/gorelease/gorelease.go
+++ b/cmd/gorelease/gorelease.go
@@ -438,6 +438,19 @@
return moduleInfo{}, err
}
+ // Attempt to load the mod file, if it exists.
+ m.goModPath = filepath.Join(m.modRoot, "go.mod")
+ if m.goModData, err = ioutil.ReadFile(m.goModPath); err != nil && !os.IsNotExist(err) {
+ return moduleInfo{}, fmt.Errorf("reading go.mod: %v", err)
+ }
+ if err == nil {
+ m.goModFile, err = modfile.ParseLax(m.goModPath, m.goModData, nil)
+ if err != nil {
+ return moduleInfo{}, err
+ }
+ }
+ // The modfile might not exist, leading to err != nil. That's OK - continue.
+
return m, nil
}
diff --git a/cmd/gorelease/report.go b/cmd/gorelease/report.go
index 8985991..32311c4 100644
--- a/cmd/gorelease/report.go
+++ b/cmd/gorelease/report.go
@@ -231,7 +231,7 @@
if pre != "" {
// suggest non-prerelease version
- } else if r.haveCompatibleChanges || (r.haveIncompatibleChanges && major == "0") {
+ } else if r.haveCompatibleChanges || (r.haveIncompatibleChanges && major == "0") || r.requirementsChanged() {
minor = incDecimal(minor)
patch = "0"
} else {
@@ -240,6 +240,52 @@
setVersion(fmt.Sprintf("v%s.%s.%s", major, minor, patch))
}
+// requirementsChanged reports whether requirements have changed from base to
+// version.
+//
+// requirementsChanged reports true for,
+// - A requirement was upgraded to a higher minor version.
+// - A requirement was added.
+// - The version of Go was incremented.
+//
+// It does not report true when, for example, a requirement was downgraded or
+// remove. We care more about the former since that might force dependent
+// modules that have the same dependency to upgrade.
+func (r *report) requirementsChanged() bool {
+ if r.base.goModFile == nil {
+ // There wasn't a modfile before, and now there is.
+ return true
+ }
+
+ // baseReqs is a map of module path to MajorMinor of the base module
+ // requirements.
+ baseReqs := make(map[string]string)
+ for _, r := range r.base.goModFile.Require {
+ baseReqs[r.Mod.Path] = r.Mod.Version
+ }
+
+ for _, r := range r.release.goModFile.Require {
+ if _, ok := baseReqs[r.Mod.Path]; !ok {
+ // A module@version was added to the "require" block between base
+ // and release.
+ return true
+ }
+ if semver.Compare(semver.MajorMinor(r.Mod.Version), semver.MajorMinor(baseReqs[r.Mod.Path])) > 0 {
+ // The version of r.Mod.Path increased from base to release.
+ return true
+ }
+ }
+
+ if r.release.goModFile.Go != nil && r.base.goModFile.Go != nil {
+ if r.release.goModFile.Go.Version > r.base.goModFile.Go.Version {
+ // The Go version increased from base to release.
+ return true
+ }
+ }
+
+ return false
+}
+
// isSuccessful returns true the module appears to be safe to release at the
// proposed or suggested version.
func (r *report) isSuccessful() bool {
diff --git a/cmd/gorelease/testdata/mod/example.com_require_v0.0.1.txt b/cmd/gorelease/testdata/mod/example.com_require_v0.0.1.txt
new file mode 100644
index 0000000..bc7200f
--- /dev/null
+++ b/cmd/gorelease/testdata/mod/example.com_require_v0.0.1.txt
@@ -0,0 +1,6 @@
+-- go.mod --
+module example.com/require
+
+go 1.12
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/tidy/extra_req.test b/cmd/gorelease/testdata/mod/example.com_require_v0.1.0.txt
similarity index 76%
copy from cmd/gorelease/testdata/tidy/extra_req.test
copy to cmd/gorelease/testdata/mod/example.com_require_v0.1.0.txt
index 58973c3..8f858bf 100644
--- a/cmd/gorelease/testdata/tidy/extra_req.test
+++ b/cmd/gorelease/testdata/mod/example.com_require_v0.1.0.txt
@@ -1,9 +1,5 @@
-mod=example.com/tidy
-base=v0.0.1
--- want --
-Suggested version: v0.0.2
-- go.mod --
-module example.com/tidy
+module example.com/require
go 1.12
@@ -13,5 +9,6 @@
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
--- tidy.go --
-package tidy
+-- require.go --
+package require
+
diff --git a/cmd/gorelease/testdata/mod/example.com_require_v0.1.1.txt b/cmd/gorelease/testdata/mod/example.com_require_v0.1.1.txt
new file mode 100644
index 0000000..620bf66
--- /dev/null
+++ b/cmd/gorelease/testdata/mod/example.com_require_v0.1.1.txt
@@ -0,0 +1,13 @@
+-- go.mod --
+module example.com/require
+
+go 1.12
+
+require example.com/basic v1.1.0
+-- go.sum --
+example.com/basic v1.1.0/go.mod h1:pv9xTX7lhV6R1XNYo1EcI/DQqKxDyhNTN+K1DjHW2Oo=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/README.txt b/cmd/gorelease/testdata/require/README.txt
new file mode 100644
index 0000000..f905232
--- /dev/null
+++ b/cmd/gorelease/testdata/require/README.txt
@@ -0,0 +1,2 @@
+This directory contain tests that assert gorelease behavior when module
+requirements (and require statements in the go.mod) have changed.
\ No newline at end of file
diff --git a/cmd/gorelease/testdata/tidy/extra_req.test b/cmd/gorelease/testdata/require/add_requirement.test
similarity index 79%
rename from cmd/gorelease/testdata/tidy/extra_req.test
rename to cmd/gorelease/testdata/require/add_requirement.test
index 58973c3..3cbc78b 100644
--- a/cmd/gorelease/testdata/tidy/extra_req.test
+++ b/cmd/gorelease/testdata/require/add_requirement.test
@@ -1,9 +1,9 @@
-mod=example.com/tidy
+mod=example.com/require
base=v0.0.1
-- want --
-Suggested version: v0.0.2
+Suggested version: v0.1.0
-- go.mod --
-module example.com/tidy
+module example.com/require
go 1.12
@@ -13,5 +13,5 @@
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
--- tidy.go --
-package tidy
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/decrement_go_version.test b/cmd/gorelease/testdata/require/decrement_go_version.test
new file mode 100644
index 0000000..abcd56f
--- /dev/null
+++ b/cmd/gorelease/testdata/require/decrement_go_version.test
@@ -0,0 +1,11 @@
+mod=example.com/require
+base=v0.0.1
+-- want --
+Suggested version: v0.0.2
+-- go.mod --
+module example.com/require
+
+go 1.11
+-- go.sum --
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/decrement_requirement_minor.test b/cmd/gorelease/testdata/require/decrement_requirement_minor.test
new file mode 100644
index 0000000..02f3683
--- /dev/null
+++ b/cmd/gorelease/testdata/require/decrement_requirement_minor.test
@@ -0,0 +1,17 @@
+mod=example.com/require
+base=v0.1.1
+-- want --
+Suggested version: v0.1.2
+-- go.mod --
+module example.com/require
+
+go 1.12
+
+require example.com/basic v0.0.1
+-- go.sum --
+example.com/basic v0.0.1/go.mod h1:pv9xTX7lhV6R1XNYo1EcI/DQqKxDyhNTN+K1DjHW2Oo=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/increment_go_version.test b/cmd/gorelease/testdata/require/increment_go_version.test
new file mode 100644
index 0000000..2f7c993
--- /dev/null
+++ b/cmd/gorelease/testdata/require/increment_go_version.test
@@ -0,0 +1,11 @@
+mod=example.com/require
+base=v0.0.1
+-- want --
+Suggested version: v0.1.0
+-- go.mod --
+module example.com/require
+
+go 1.13
+-- go.sum --
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/increment_requirement_minor.test b/cmd/gorelease/testdata/require/increment_requirement_minor.test
new file mode 100644
index 0000000..a453b3e
--- /dev/null
+++ b/cmd/gorelease/testdata/require/increment_requirement_minor.test
@@ -0,0 +1,17 @@
+mod=example.com/require
+base=v0.1.0
+-- want --
+Suggested version: v0.2.0
+-- go.mod --
+module example.com/require
+
+go 1.12
+
+require example.com/basic v1.1.0
+-- go.sum --
+example.com/basic v1.1.0/go.mod h1:pv9xTX7lhV6R1XNYo1EcI/DQqKxDyhNTN+K1DjHW2Oo=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/increment_requirement_patch.test b/cmd/gorelease/testdata/require/increment_requirement_patch.test
new file mode 100644
index 0000000..0469ae4
--- /dev/null
+++ b/cmd/gorelease/testdata/require/increment_requirement_patch.test
@@ -0,0 +1,17 @@
+mod=example.com/require
+base=v0.1.1
+-- want --
+Suggested version: v0.1.2
+-- go.mod --
+module example.com/require
+
+go 1.12
+
+require example.com/basic v1.1.1
+-- go.sum --
+example.com/basic v1.1.1/go.mod h1:pv9xTX7lhV6R1XNYo1EcI/DQqKxDyhNTN+K1DjHW2Oo=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+-- require.go --
+package require
diff --git a/cmd/gorelease/testdata/require/remove_requirements.test b/cmd/gorelease/testdata/require/remove_requirements.test
new file mode 100644
index 0000000..f57d12a
--- /dev/null
+++ b/cmd/gorelease/testdata/require/remove_requirements.test
@@ -0,0 +1,11 @@
+mod=example.com/require
+base=v0.0.1
+-- want --
+Suggested version: v0.0.2
+-- go.mod --
+module example.com/require
+
+go 1.12
+-- go.sum --
+-- require.go --
+package require