11package config
22
33import (
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.
117127var 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.
121131var 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-
133133func 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}
0 commit comments