Skip to content

Commit abe8884

Browse files
retlehsclaude
andcommitted
Derive current_version from tagged wp.org versions instead of plugin header
The wp.org API "version" field reflects the latest code in SVN trunk, but some authors release to trunk without creating an SVN tag. Since our version list is built from tags, the reported version may not exist as a downloadable release. Use the highest tagged version instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 83bc7dd commit abe8884

File tree

3 files changed

+49
-26
lines changed

3 files changed

+49
-26
lines changed

internal/http/handlers.go

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package http
22

33
import (
4-
"cmp"
54
"context"
65
"crypto/sha256"
76
"database/sql"
@@ -26,6 +25,7 @@ import (
2625
"github.com/roots/wp-composer/internal/config"
2726
"github.com/roots/wp-composer/internal/deploy"
2827
"github.com/roots/wp-composer/internal/og"
28+
"github.com/roots/wp-composer/internal/version"
2929
)
3030

3131
const perPage = 12
@@ -842,35 +842,11 @@ func parseVersions(pkg *packageDetail) []versionRow {
842842
}
843843
return 1
844844
}
845-
return compareVersions(b.Version, a.Version)
845+
return version.Compare(b.Version, a.Version)
846846
})
847847
return rows
848848
}
849849

850-
// compareVersions compares two version strings numerically by segment.
851-
// Returns -1, 0, or 1.
852-
func compareVersions(a, b string) int {
853-
aParts := strings.Split(a, ".")
854-
bParts := strings.Split(b, ".")
855-
maxLen := len(aParts)
856-
if len(bParts) > maxLen {
857-
maxLen = len(bParts)
858-
}
859-
for i := range maxLen {
860-
var av, bv int
861-
if i < len(aParts) {
862-
av, _ = strconv.Atoi(aParts[i])
863-
}
864-
if i < len(bParts) {
865-
bv, _ = strconv.Atoi(bParts[i])
866-
}
867-
if c := cmp.Compare(av, bv); c != 0 {
868-
return c
869-
}
870-
}
871-
return 0
872-
}
873-
874850
func queryDashboardStats(ctx context.Context, db *sql.DB) map[string]any {
875851
stats := map[string]any{
876852
"Stats": struct {

internal/packages/package.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type Package struct {
4343
}
4444

4545
// NormalizeAndStoreVersions normalizes raw versions and serializes to VersionsJSON.
46+
// It also sets CurrentVersion to the highest available version.
4647
// Returns the number of valid versions.
4748
func (p *Package) NormalizeAndStoreVersions() (int, error) {
4849
if p.RawVersions == nil {
@@ -57,6 +58,11 @@ func (p *Package) NormalizeAndStoreVersions() (int, error) {
5758
return 0, fmt.Errorf("marshaling versions: %w", err)
5859
}
5960
p.VersionsJSON = string(data)
61+
62+
if latest := version.Latest(normalized); latest != "" {
63+
p.CurrentVersion = &latest
64+
}
65+
6066
return len(normalized), nil
6167
}
6268

internal/version/normalize.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package version
22

33
import (
4+
"cmp"
45
"regexp"
6+
"strconv"
57
"strings"
68
)
79

@@ -49,3 +51,42 @@ func NormalizeVersions(versions map[string]string) map[string]string {
4951
}
5052
return result
5153
}
54+
55+
// Compare compares two version strings numerically by segment.
56+
// Returns -1, 0, or 1.
57+
func Compare(a, b string) int {
58+
aParts := strings.Split(a, ".")
59+
bParts := strings.Split(b, ".")
60+
maxLen := len(aParts)
61+
if len(bParts) > maxLen {
62+
maxLen = len(bParts)
63+
}
64+
for i := range maxLen {
65+
var av, bv int
66+
if i < len(aParts) {
67+
av, _ = strconv.Atoi(aParts[i])
68+
}
69+
if i < len(bParts) {
70+
bv, _ = strconv.Atoi(bParts[i])
71+
}
72+
if c := cmp.Compare(av, bv); c != 0 {
73+
return c
74+
}
75+
}
76+
return 0
77+
}
78+
79+
// Latest returns the highest version from a map of version -> download URL,
80+
// excluding dev-trunk. Returns empty string if no versions are present.
81+
func Latest(versions map[string]string) string {
82+
var latest string
83+
for v := range versions {
84+
if v == "dev-trunk" {
85+
continue
86+
}
87+
if latest == "" || Compare(v, latest) > 0 {
88+
latest = v
89+
}
90+
}
91+
return latest
92+
}

0 commit comments

Comments
 (0)