Skip to content

Commit d2c64f5

Browse files
committed
Reuse message across tag validation
1 parent ff03bd0 commit d2c64f5

3 files changed

Lines changed: 15 additions & 14 deletions

File tree

internal/api/client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
1515

16+
"github.com/localstack/lstk/internal/config"
1617
"github.com/localstack/lstk/internal/log"
1718
"github.com/localstack/lstk/internal/version"
1819
)
@@ -313,7 +314,7 @@ func (c *PlatformClient) GetLicense(ctx context.Context, licReq *LicenseRequest)
313314
if strings.Contains(detail, "licensing.license.format") {
314315
return nil, &LicenseError{
315316
Status: statusCode,
316-
Message: "unsupported image tag — check the tag in your config file",
317+
Message: config.UnsupportedTagMessage(),
317318
Detail: detail,
318319
}
319320
}

internal/config/containers.go

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

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"path/filepath"
@@ -112,6 +113,15 @@ func (c *ContainerConfig) VolumeDir() (string, error) {
112113
return filepath.Join(cacheDir, "lstk", "volume", c.Name()), nil
113114
}
114115

116+
func UnsupportedTagMessage() string {
117+
y, m, _ := time.Now().Date()
118+
m--
119+
if m == 0 {
120+
m, y = 12, y-1
121+
}
122+
return fmt.Sprintf("unsupported image tag — try a tag like %q or \"latest\" in your config file", fmt.Sprintf("%d.%d", y, int(m)))
123+
}
124+
115125
// zeroPaddedMonthTagRe matches calendar-versioned tags where the month is zero-padded
116126
// (e.g. "2026.04", "2026.04.1-amd64"), which the license API does not accept.
117127
var zeroPaddedMonthTagRe = regexp.MustCompile(`^(\d{4}\.)0([1-9].*)$`)
@@ -120,22 +130,12 @@ var zeroPaddedMonthTagRe = regexp.MustCompile(`^(\d{4}\.)0([1-9].*)$`)
120130
// must not start with a dot or hyphen; max 128 characters.
121131
var validTagRe = regexp.MustCompile(`^[a-zA-Z0-9_][a-zA-Z0-9._-]*$`)
122132

123-
// prevMonthExample returns the previous calendar month as a tag example, e.g. "2026.4".
124-
func prevMonthExample() string {
125-
y, m, _ := time.Now().Date()
126-
m--
127-
if m == 0 {
128-
m, y = 12, y-1
129-
}
130-
return fmt.Sprintf("%d.%d", y, int(m))
131-
}
132-
133133
func validateTag(tag string) error {
134134
if tag == "" {
135135
return nil
136136
}
137137
if len(tag) > 128 || !validTagRe.MatchString(tag) || zeroPaddedMonthTagRe.MatchString(tag) {
138-
return fmt.Errorf("tag %q is not supported — try a tag like %q or \"latest\" in your config file", tag, prevMonthExample())
138+
return errors.New(UnsupportedTagMessage())
139139
}
140140
return nil
141141
}

internal/config/containers_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestValidate_ZeroPaddedMonthTag_IsRejected(t *testing.T) {
5454
for _, tag := range []string{"2026.04", "2026.04.1", "2026.04.0-amd64", "2026.01", "2026.09.2"} {
5555
t.Run(tag, func(t *testing.T) {
5656
c := &ContainerConfig{Type: EmulatorAWS, Port: "4566", Tag: tag}
57-
assert.ErrorContains(t, c.Validate(), "not supported")
57+
assert.ErrorContains(t, c.Validate(), "unsupported")
5858
})
5959
}
6060
}
@@ -72,7 +72,7 @@ func TestValidate_InvalidDockerTag_IsRejected(t *testing.T) {
7272
t.Run(tag, func(t *testing.T) {
7373
c := &ContainerConfig{Type: EmulatorAWS, Port: "4566", Tag: tag}
7474
err := c.Validate()
75-
assert.ErrorContains(t, err, "not supported")
75+
assert.ErrorContains(t, err, "unsupported")
7676
})
7777
}
7878
}

0 commit comments

Comments
 (0)