diff --git a/pkg/plugin/name.go b/pkg/plugin/name.go index f6a31fb71..4b33ee7f9 100644 --- a/pkg/plugin/name.go +++ b/pkg/plugin/name.go @@ -72,18 +72,28 @@ func (fn FullName) PluginVersion() string { return PluginVersionLatest // default } -func (fn FullName) PluginVersionGreaterThan(other FullName) bool { +func (fn FullName) PluginVersionGreaterThan(right FullName) bool { leftVersion := fn.PluginVersion() - rightVersion := other.PluginVersion() - - leftSemver, err := semver.NewVersion(leftVersion) - if err != nil { + leftSemver, errLeft := semver.NewVersion(leftVersion) + + rightVersion := right.PluginVersion() + rightSemver, errRight := semver.NewVersion(rightVersion) + + switch { + case errLeft != nil && errRight != nil: + switch { + case leftVersion == PluginVersionLatest: + return false // latest could be anything, we prioritize explicit versions + case rightVersion == PluginVersionLatest: + return true // latest could be anything, we prioritize explicit versions + } + // both are invalid semvers, compare as strings + return leftVersion < rightVersion + case errRight != nil: + return true // right is an invalid semver, left is greater either way + case errLeft != nil: return false // left is an invalid semver, right is greater either way } - rightSemver, err := semver.NewVersion(rightVersion) - if err != nil { - return true // left is a valid semver, right is not, left is greater - } return leftSemver.GreaterThan(rightSemver) } diff --git a/pkg/plugin/name_test.go b/pkg/plugin/name_test.go index 86b8da75e..a3828ddac 100644 --- a/pkg/plugin/name_test.go +++ b/pkg/plugin/name_test.go @@ -28,6 +28,7 @@ func TestFullName(t *testing.T) { pn string // expected plugin name pv string // expected plugin version }{ + {fn: "", pt: "any", pn: "", pv: "latest"}, {fn: "my-plugin", pt: "any", pn: "my-plugin", pv: "latest"}, {fn: "builtin:my-plugin", pt: "builtin", pn: "my-plugin", pv: "latest"}, {fn: "my-plugin@v0.1.1", pt: "any", pn: "my-plugin", pv: "v0.1.1"}, @@ -46,11 +47,11 @@ func TestFullName(t *testing.T) { } } -func TestFullName_PluginVersionGreaterThanP(t *testing.T) { +func TestFullName_PluginVersionGreaterThan(t *testing.T) { testCases := []struct { v1 string // left version v2 string // right version - gt bool // want greater than + gt bool // is left greater than right }{ {v1: "v0.0.1", v2: "v0.0.1", gt: false}, {v1: "v0.1", v2: "v0.0.1", gt: true}, @@ -60,8 +61,13 @@ func TestFullName_PluginVersionGreaterThanP(t *testing.T) { {v1: "foo", v2: "v0.0.1", gt: false}, {v1: "v0.0.1", v2: "foo", gt: true}, {v1: "foo", v2: "bar", gt: false}, - {v1: "bar", v2: "foo", gt: false}, + {v1: "bar", v2: "foo", gt: true}, {v1: "v0.0.1", v2: "v0.0.1-dirty", gt: true}, + {v1: "zoo", v2: "", gt: true}, + {v1: "v1", v2: "", gt: true}, + {v1: "", v2: "zoo", gt: false}, + {v1: "", v2: "v1", gt: false}, + {v1: "", v2: "", gt: false}, } for _, tc := range testCases { @@ -70,6 +76,12 @@ func TestFullName_PluginVersionGreaterThanP(t *testing.T) { v1 := NewFullName("builtin", "test", tc.v1) v2 := NewFullName("builtin", "test", tc.v2) is.Equal(v1.PluginVersionGreaterThan(v2), tc.gt) + + // even if plugin type and plugin name are empty, the version + // comparison should still work the same + v1 = NewFullName("", "", tc.v1) + v2 = NewFullName("", "", tc.v2) + is.Equal(v1.PluginVersionGreaterThan(v2), tc.gt) }) } }