MM-67793: Remove dependency on blang/semver/v4 (#35742)

* Remove dependency on blang/semver/v4

Instead, consolidate on the usage of Masterminds/semver/v3

* Remove empty line

* make modules-tidy
This commit is contained in:
Alejandro García Montoro
2026-03-25 14:41:33 +01:00
committed by GitHub
parent 7d6d834f1f
commit 4f16a29cb5
15 changed files with 50 additions and 54 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ import (
"strings"
"time"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/mlog"
@@ -2538,7 +2538,7 @@ func handleDeviceProps(c *Context, w http.ResponseWriter, r *http.Request) {
mobileVersion := receivedProps[model.SessionPropMobileVersion]
if mobileVersion != "" {
if _, err := semver.Parse(mobileVersion); err != nil {
if _, err := semver.StrictNewVersion(mobileVersion); err != nil {
c.SetInvalidParam(model.SessionPropMobileVersion)
return
}
+4 -4
View File
@@ -6,7 +6,7 @@ package app
import (
"net/http"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
agentclient "github.com/mattermost/mattermost-plugin-ai/public/bridgeclient"
"github.com/mattermost/mattermost/server/public/model"
@@ -45,7 +45,7 @@ func (a *App) GetAIPluginBridgeStatus(rctx request.CTX) (bool, string) {
plugins := pluginsEnvironment.Active()
for _, plugin := range plugins {
if plugin.Manifest != nil && plugin.Manifest.Id == aiPluginID {
pluginVersion, err := semver.Parse(plugin.Manifest.Version)
pluginVersion, err := semver.StrictNewVersion(plugin.Manifest.Version)
if err != nil {
rctx.Logger().Debug("AI plugin bridge not available - failed to parse plugin version",
mlog.String("plugin_id", aiPluginID),
@@ -55,12 +55,12 @@ func (a *App) GetAIPluginBridgeStatus(rctx request.CTX) (bool, string) {
return false, "app.agents.bridge.not_available.plugin_version_parse_failed"
}
minVersion, err := semver.Parse(minAIPluginVersionForBridge)
minVersion, err := semver.StrictNewVersion(minAIPluginVersionForBridge)
if err != nil {
return false, "app.agents.bridge.not_available.min_version_parse_failed"
}
if pluginVersion.LT(minVersion) {
if pluginVersion.LessThan(minVersion) {
rctx.Logger().Debug("AI plugin bridge not available - plugin version is too old",
mlog.String("plugin_id", aiPluginID),
mlog.String("current_version", plugin.Manifest.Version),
+7 -7
View File
@@ -16,7 +16,7 @@ import (
"strings"
"sync"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
svg "github.com/h2non/go-is-svg"
"github.com/pkg/errors"
@@ -687,18 +687,18 @@ func (a *App) mergePrepackagedPlugins(remoteMarketplacePlugins map[string]*model
}
// If available in the marketplace, only overwrite if newer.
prepackagedVersion, err := semver.Parse(prepackaged.Manifest.Version)
prepackagedVersion, err := semver.StrictNewVersion(prepackaged.Manifest.Version)
if err != nil {
return model.NewAppError("mergePrepackagedPlugins", "app.plugin.invalid_version.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
marketplacePlugin := remoteMarketplacePlugins[prepackaged.Manifest.Id]
marketplaceVersion, err := semver.Parse(marketplacePlugin.Manifest.Version)
marketplaceVersion, err := semver.StrictNewVersion(marketplacePlugin.Manifest.Version)
if err != nil {
return model.NewAppError("mergePrepackagedPlugins", "app.plugin.invalid_version.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
if prepackagedVersion.GT(marketplaceVersion) {
if prepackagedVersion.GreaterThan(marketplaceVersion) {
remoteMarketplacePlugins[prepackaged.Manifest.Id] = prepackagedMarketplace
}
}
@@ -1075,7 +1075,7 @@ func (ch *Channels) shouldPersistTransitionallyPrepackagedPlugin(availablePlugin
return true
}
prepackagedVersion, err := semver.Parse(p.Manifest.Version)
prepackagedVersion, err := semver.StrictNewVersion(p.Manifest.Version)
if err != nil {
logger.Error("Should not persist transitionally prepackged plugin: invalid prepackaged version", mlog.Err(err))
return false
@@ -1083,14 +1083,14 @@ func (ch *Channels) shouldPersistTransitionallyPrepackagedPlugin(availablePlugin
logger = logger.With(mlog.String("existing_version", existing.Manifest.Version))
existingVersion, err := semver.Parse(existing.Manifest.Version)
existingVersion, err := semver.StrictNewVersion(existing.Manifest.Version)
if err != nil {
// Consider this an old version and replace with the prepackaged version instead.
logger.Warn("Should persist transitionally prepackged plugin: invalid existing version", mlog.Err(err))
return true
}
if prepackagedVersion.GT(existingVersion) {
if prepackagedVersion.GreaterThan(existingVersion) {
logger.Info("Should persist transitionally prepackged plugin: newer version")
return true
}
+12 -14
View File
@@ -81,7 +81,7 @@ import (
"os"
"path/filepath"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/mlog"
@@ -301,21 +301,21 @@ func (ch *Channels) InstallMarketplacePlugin(request *model.InstallMarketplacePl
}
if plugin != nil {
var prepackagedVersion semver.Version
prepackagedVersion, _ := semver.StrictNewVersion("0.0.0")
if prepackagedPlugin != nil {
var err error
prepackagedVersion, err = semver.Parse(prepackagedPlugin.Manifest.Version)
prepackagedVersion, err = semver.StrictNewVersion(prepackagedPlugin.Manifest.Version)
if err != nil {
return nil, model.NewAppError("InstallMarketplacePlugin", "app.plugin.invalid_version.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
marketplaceVersion, err := semver.Parse(plugin.Manifest.Version)
marketplaceVersion, err := semver.StrictNewVersion(plugin.Manifest.Version)
if err != nil {
return nil, model.NewAppError("InstallMarketplacePlugin", "app.prepackged-plugin.invalid_version.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
if prepackagedVersion.LT(marketplaceVersion) { // Always true if no prepackaged plugin was found
if prepackagedVersion.LessThan(marketplaceVersion) { // Always true if no prepackaged plugin was found
logger.Debug("Found upgraded plugin from remote marketplace", mlog.String("version", plugin.Manifest.Version), mlog.String("download_url", plugin.DownloadURL))
downloadedPluginBytes, err := ch.srv.downloadFromURL(plugin.DownloadURL)
@@ -462,19 +462,17 @@ func (ch *Channels) installExtractedPlugin(manifest *model.Manifest, fromPluginD
// Skip installation if already installed and newer.
if installationStrategy == installPluginLocallyOnlyIfNewOrUpgrade {
var version, existingVersion semver.Version
version, err = semver.Parse(manifest.Version)
if err != nil {
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.invalid_version.app_error", nil, "", http.StatusBadRequest).Wrap(err)
version, vErr := semver.StrictNewVersion(manifest.Version)
if vErr != nil {
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.invalid_version.app_error", nil, "", http.StatusBadRequest).Wrap(vErr)
}
existingVersion, err = semver.Parse(existingManifest.Version)
if err != nil {
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.invalid_version.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
existingVersion, vErr := semver.StrictNewVersion(existingManifest.Version)
if vErr != nil {
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.invalid_version.app_error", nil, "", http.StatusInternalServerError).Wrap(vErr)
}
if version.LTE(existingVersion) {
if version.LessThanEqual(existingVersion) {
logger.Warn("Skipping local installation of plugin since not a newer version", mlog.String("version", version.String()), mlog.String("existing_version", existingVersion.String()))
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.skip_installation.app_error", map[string]any{"Id": manifest.Id}, "", http.StatusInternalServerError)
}
+4 -4
View File
@@ -8,8 +8,8 @@ import (
"path"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/avct/uasurfer"
"github.com/blang/semver/v4"
"github.com/gorilla/mux"
"github.com/mattermost/mattermost/server/public/model"
@@ -67,15 +67,15 @@ func CheckDesktopAppCompatibility(agentString string, minVersion *string) bool {
if !ok {
return true
}
clientVersion, err := semver.ParseTolerant(clientVersionStr)
clientVersion, err := semver.NewVersion(clientVersionStr)
if err != nil {
return true
}
required, err := semver.Parse(*minVersion)
required, err := semver.StrictNewVersion(*minVersion)
if err != nil {
return true
}
return clientVersion.GTE(required)
return clientVersion.GreaterThanEqual(required)
}
func Handle404(a *app.App, w http.ResponseWriter, r *http.Request) {
+2 -2
View File
@@ -13,7 +13,6 @@ require (
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.34.4
github.com/bep/imagemeta v0.12.0
github.com/blang/semver/v4 v4.0.0
github.com/cespare/xxhash/v2 v2.3.0
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a
@@ -76,6 +75,7 @@ require (
golang.org/x/sync v0.18.0
golang.org/x/sys v0.38.0
golang.org/x/term v0.37.0
golang.org/x/text v0.31.0
gopkg.in/mail.v2 v2.3.1
)
@@ -104,6 +104,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.24.1 // indirect
github.com/bits-and-blooms/bloom/v3 v3.7.0 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bodgit/plumbing v1.3.0 // indirect
github.com/bodgit/sevenzip v1.6.1 // indirect
github.com/bodgit/windows v1.0.1 // indirect
@@ -207,7 +208,6 @@ require (
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/tools v0.38.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff // indirect
google.golang.org/grpc v1.76.0 // indirect
-2
View File
@@ -407,8 +407,6 @@ github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 h1:Y1Tu/swM31pVwwb
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956/go.mod h1:SRl30Lb7/QoYyohYeVBuqYvvmXSZJxZgiV3Zf6VbxjI=
github.com/mattermost/logr/v2 v2.0.22 h1:npFkXlkAWR9J8payh8ftPcCZvLbHSI125mAM5/r/lP4=
github.com/mattermost/logr/v2 v2.0.22/go.mod h1:0sUKpO+XNMZApeumaid7PYaUZPBIydfuWZ0dqixXo+s=
github.com/mattermost/mattermost-plugin-ai v1.8.1 h1:qymxDayy3vJPhm59XA8q0oLR8uobPgx0SOB7IMG9ZMM=
github.com/mattermost/mattermost-plugin-ai v1.8.1/go.mod h1:Uco4K7ypsrZWcD256ezvgZDqolJfHYiExN2lYiHmVDo=
github.com/mattermost/mattermost-plugin-ai v1.12.0 h1:cwRE2jjlqN5W42O9Xp0ncyHk7HL/ayMeypuINPX0WJ0=
github.com/mattermost/mattermost-plugin-ai v1.12.0/go.mod h1:L/I/IpdWNGbxRfUduCstCYbhyX59OEftxcpDHtCT4EI=
github.com/mattermost/mattermost/server/public v0.1.22-0.20251105210629-8bf4a00724e2 h1:RJtCnj9nF/wb0Fb+O0qAPgUoWP5CTTDnHzHD5ciGlJ8=
+1 -1
View File
@@ -3,7 +3,7 @@ module github.com/mattermost/mattermost/server/public
go 1.24.13
require (
github.com/blang/semver/v4 v4.0.0
github.com/Masterminds/semver/v3 v3.4.0
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a
github.com/francoispqt/gojay v1.2.13
github.com/goccy/go-yaml v1.18.0
+2 -2
View File
@@ -10,13 +10,13 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE=
github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
+2 -2
View File
@@ -20,7 +20,7 @@ import (
"strings"
"time"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/mattermost/ldap"
"github.com/pkg/errors"
@@ -4664,7 +4664,7 @@ func (s *ServiceSettings) isValid() *AppError {
}
if *s.MinimumDesktopAppVersion != "" {
if _, err := semver.Parse(*s.MinimumDesktopAppVersion); err != nil {
if _, err := semver.StrictNewVersion(*s.MinimumDesktopAppVersion); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.minimum_desktop_app_version.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
+5 -5
View File
@@ -11,7 +11,7 @@ import (
"path/filepath"
"strings"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/goccy/go-yaml"
"github.com/pkg/errors"
)
@@ -299,12 +299,12 @@ func (m *Manifest) HasWebapp() bool {
}
func (m *Manifest) MeetMinServerVersion(serverVersion string) (bool, error) {
minServerVersion, err := semver.Parse(m.MinServerVersion)
minServerVersion, err := semver.StrictNewVersion(m.MinServerVersion)
if err != nil {
return false, errors.New("failed to parse MinServerVersion")
}
sv := semver.MustParse(serverVersion)
if sv.LT(minServerVersion) {
if sv.LessThan(minServerVersion) {
return false, nil
}
return true, nil
@@ -332,14 +332,14 @@ func (m *Manifest) IsValid() error {
}
if m.Version != "" {
_, err := semver.Parse(m.Version)
_, err := semver.StrictNewVersion(m.Version)
if err != nil {
return errors.Wrap(err, "failed to parse Version")
}
}
if m.MinServerVersion != "" {
_, err := semver.Parse(m.MinServerVersion)
_, err := semver.StrictNewVersion(m.MinServerVersion)
if err != nil {
return errors.Wrap(err, "failed to parse MinServerVersion")
}
+3 -3
View File
@@ -7,7 +7,7 @@ import (
"fmt"
"strings"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
)
type MetricType string
@@ -112,12 +112,12 @@ func (r *PerformanceReport) IsValid() error {
return fmt.Errorf("the report is nil")
}
reportVersion, err := semver.ParseTolerant(r.Version)
reportVersion, err := semver.NewVersion(r.Version)
if err != nil {
return fmt.Errorf("could not parse semver version: %s, %w", r.Version, err)
}
if reportVersion.Major != performanceReportVersion.Major || reportVersion.Minor > performanceReportVersion.Minor {
if reportVersion.Major() != performanceReportVersion.Major() || reportVersion.Minor() > performanceReportVersion.Minor() {
return fmt.Errorf("report version is not supported: server version: %s, report version: %s", performanceReportVersion.String(), r.Version)
}
+2 -2
View File
@@ -6,7 +6,7 @@ package model
import (
"fmt"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/goccy/go-yaml"
)
@@ -54,7 +54,7 @@ func (md *PacketMetadata) Validate() error {
return fmt.Errorf("generated_at should be a positive number")
}
if _, err := semver.ParseTolerant(md.ServerVersion); err != nil {
if _, err := semver.NewVersion(md.ServerVersion); err != nil {
return fmt.Errorf("could not parse server version: %w", err)
}
+2 -2
View File
@@ -1,7 +1,7 @@
package pluginapi
import (
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/mattermost/mattermost/server/public/plugin"
"github.com/pkg/errors"
)
@@ -73,7 +73,7 @@ func ensureServerVersion(api plugin.API, required string) error {
currentVersion := semver.MustParse(serverVersion)
requiredVersion := semver.MustParse(required)
if currentVersion.LT(requiredVersion) {
if currentVersion.LessThan(requiredVersion) {
return errors.Errorf("incompatible server version for plugin, minimum required version: %s, current version: %s", required, serverVersion)
}
+2 -2
View File
@@ -7,7 +7,7 @@ import (
filePath "path"
"time"
"github.com/blang/semver/v4"
"github.com/Masterminds/semver/v3"
"github.com/goccy/go-yaml"
"github.com/pkg/errors"
@@ -127,7 +127,7 @@ func (s *SystemService) RequestTrialLicense(requesterID string, users int, terms
currentVersion := semver.MustParse(s.api.GetServerVersion())
requiredVersion := semver.MustParse("5.36.0")
if currentVersion.LT(requiredVersion) {
if currentVersion.LessThan(requiredVersion) {
return errors.Errorf("current server version is lower than 5.36")
}