@@ -121,7 +121,8 @@ import (
121121)
122122
123123var (
124- specifierRe = regexp .MustCompile (`^[A-Za-z0-9_-]+$` )
124+ specifierRe = regexp .MustCompile (`^[()A-Za-z0-9_.-]+$` )
125+ OSAndVersionFormat = "%s(%s)"
125126)
126127
127128// Platform is a type alias for convenience, so there is no need to import image-spec package everywhere.
@@ -174,9 +175,13 @@ func ParseAll(specifiers []string) ([]specs.Platform, error) {
174175
175176// Parse parses the platform specifier syntax into a platform declaration.
176177//
177- // Platform specifiers are in the format `<os>|<arch>|<os>/<arch>[/<variant>]`.
178+ // Platform specifiers are in the format `<os>[(<OSVersion>)] |<arch>|<os>[(<OSVersion>)] /<arch>[/<variant>]`.
178179// The minimum required information for a platform specifier is the operating
179- // system or architecture. If there is only a single string (no slashes), the
180+ // system or architecture. The OSVersion can be part of the OS like windows(10.0.17763)
181+ // Currently, the OS version is only used by windows. Therefore, if the OS is windows
182+ // and an os version is specified, then specs.Platform.OSVersion is populated. If not it
183+ // is left empty.
184+ // If there is only a single string (no slashes), the
180185// value will be matched against the known set of operating systems, then fall
181186// back to the known set of architectures. The missing component will be
182187// inferred based on the local environment.
@@ -197,23 +202,21 @@ func Parse(specifier string) (specs.Platform, error) {
197202 var p specs.Platform
198203 switch len (parts ) {
199204 case 1 :
200- // in this case, we will test that the value might be an OS, then look
201- // it up. If it is not known, we'll treat it as an architecture. Since
205+ // in this case, we will test that the value might be an OS (with or
206+ // without the optional osversion specified) and look it up.
207+ // If it is not known, we'll treat it as an architecture. Since
202208 // we have very little information about the platform here, we are
203209 // going to be a little more strict if we don't know about the argument
204210 // value.
205211 p .OS = normalizeOS (parts [0 ])
212+ p .OSVersion = normalizeOSVersion (parts [0 ])
206213 if isKnownOS (p .OS ) {
207214 // picks a default architecture
208215 p .Architecture = runtime .GOARCH
209216 if p .Architecture == "arm" && cpuVariant () != "v7" {
210217 p .Variant = cpuVariant ()
211218 }
212219
213- if p .OS == "windows" {
214- p .OSVersion = GetWindowsOsVersion ()
215- }
216-
217220 return p , nil
218221 }
219222
@@ -228,31 +231,25 @@ func Parse(specifier string) (specs.Platform, error) {
228231
229232 return specs.Platform {}, fmt .Errorf ("%q: unknown operating system or architecture: %w" , specifier , errInvalidArgument )
230233 case 2 :
231- // In this case, we treat as a regular os/arch pair. We don't care
234+ // In this case, we treat as a regular os[(osversion)] /arch pair. We don't care
232235 // about whether or not we know of the platform.
233236 p .OS = normalizeOS (parts [0 ])
237+ p .OSVersion = normalizeOSVersion (parts [0 ])
234238 p .Architecture , p .Variant = normalizeArch (parts [1 ], "" )
235239 if p .Architecture == "arm" && p .Variant == "v7" {
236240 p .Variant = ""
237241 }
238242
239- if p .OS == "windows" {
240- p .OSVersion = GetWindowsOsVersion ()
241- }
242-
243243 return p , nil
244244 case 3 :
245245 // we have a fully specified variant, this is rare
246246 p .OS = normalizeOS (parts [0 ])
247+ p .OSVersion = normalizeOSVersion (parts [0 ])
247248 p .Architecture , p .Variant = normalizeArch (parts [1 ], parts [2 ])
248249 if p .Architecture == "arm64" && p .Variant == "" {
249250 p .Variant = "v8"
250251 }
251252
252- if p .OS == "windows" {
253- p .OSVersion = GetWindowsOsVersion ()
254- }
255-
256253 return p , nil
257254 }
258255
@@ -275,6 +272,11 @@ func Format(platform specs.Platform) string {
275272 return "unknown"
276273 }
277274
275+ if strings .ToLower (platform .OS ) == "windows" && platform .OSVersion != "" {
276+ windowsOsVersion := fmt .Sprintf (OSAndVersionFormat , platform .OS , platform .OSVersion )
277+ return path .Join (windowsOsVersion , platform .Architecture , platform .Variant )
278+ }
279+
278280 return path .Join (platform .OS , platform .Architecture , platform .Variant )
279281}
280282
0 commit comments