@@ -120,6 +120,11 @@ type Profile struct {
120120	Libraries   ProfileRequiredLibraries  `yaml:"libraries"` 
121121}
122122
123+ // UsesSystemPlatform checks if this profile requires a system installed platform. 
124+ func  (p  * Profile ) RequireSystemInstalledPlatform () bool  {
125+ 	return  p .Platforms [0 ].RequireSystemInstalledPlatform ()
126+ }
127+ 
123128// ToRpc converts this Profile to an rpc.SketchProfile 
124129func  (p  * Profile ) ToRpc () * rpc.SketchProfile  {
125130	var  portConfig  * rpc.MonitorPortConfiguration 
@@ -182,6 +187,20 @@ func (p *ProfileRequiredPlatforms) AsYaml() string {
182187	return  res 
183188}
184189
190+ func  (p  * ProfileRequiredPlatforms ) UnmarshalYAML (unmarshal  func (interface {}) error ) error  {
191+ 	_p  :=  (* []* ProfilePlatformReference )(p )
192+ 	if  err  :=  unmarshal (_p ); err  !=  nil  {
193+ 		return  err 
194+ 	}
195+ 	requireSystemPlatform  :=  (* _p )[0 ].RequireSystemInstalledPlatform ()
196+ 	for  _ , platform  :=  range  * _p  {
197+ 		if  platform .RequireSystemInstalledPlatform () !=  requireSystemPlatform  {
198+ 			return  errors .New (i18n .Tr ("all platforms in a profile must either require a specific version or not" ))
199+ 		}
200+ 	}
201+ 	return  nil 
202+ }
203+ 
185204// ProfileRequiredLibraries is a list of ProfileLibraryReference (libraries 
186205// required to build the sketch using this profile) 
187206type  ProfileRequiredLibraries  []* ProfileLibraryReference 
@@ -206,6 +225,12 @@ type ProfilePlatformReference struct {
206225	PlatformIndexURL  * url.URL 
207226}
208227
228+ // RequireSystemInstalledPlatform returns true if the platform reference 
229+ // does not specify a version, meaning it requires the system installed platform. 
230+ func  (p  * ProfilePlatformReference ) RequireSystemInstalledPlatform () bool  {
231+ 	return  p .Version  ==  nil 
232+ }
233+ 
209234// InternalUniqueIdentifier returns the unique identifier for this object 
210235func  (p  * ProfilePlatformReference ) InternalUniqueIdentifier () string  {
211236	id  :=  p .String ()
@@ -224,20 +249,38 @@ func (p *ProfilePlatformReference) String() string {
224249
225250// AsYaml outputs the platform reference as Yaml 
226251func  (p  * ProfilePlatformReference ) AsYaml () string  {
227- 	res  :=  fmt .Sprintf ("      - platform: %s:%s (%s)\n " , p .Packager , p .Architecture , p .Version )
252+ 	res  :=  "" 
253+ 	if  p .Version  !=  nil  {
254+ 		res  +=  fmt .Sprintf ("      - platform: %s:%s (%s)\n " , p .Packager , p .Architecture , p .Version )
255+ 	} else  {
256+ 		res  +=  fmt .Sprintf ("      - platform: %s:%s\n " , p .Packager , p .Architecture )
257+ 	}
228258	if  p .PlatformIndexURL  !=  nil  {
229259		res  +=  fmt .Sprintf ("        platform_index_url: %s\n " , p .PlatformIndexURL )
230260	}
231261	return  res 
232262}
233263
234264func  parseNameAndVersion (in  string ) (string , string , bool ) {
235- 	re  :=  regexp .MustCompile (`^([a-zA-Z0-9.\-_ :]+) \((.+)\)$` )
236- 	split  :=  re .FindAllStringSubmatch (in , - 1 )
237- 	if  len (split ) !=  1  ||  len (split [0 ]) !=  3  {
238- 		return  "" , "" , false 
265+ 	{
266+ 		// Try to parse the input string in the format "VENDOR:ARCH (VERSION)" 
267+ 		re  :=  regexp .MustCompile (`^([a-zA-Z0-9.\-_ :]+) \((.+)\)$` )
268+ 		split  :=  re .FindAllStringSubmatch (in , - 1 )
269+ 		if  len (split ) ==  1  &&  len (split [0 ]) ==  3  {
270+ 			return  split [0 ][1 ], split [0 ][2 ], true 
271+ 		}
272+ 	}
273+ 
274+ 	{
275+ 		// Try to parse the input string in the format "VENDOR:ARCH" 
276+ 		re  :=  regexp .MustCompile (`^([a-zA-Z0-9.\-_ :]+)$` )
277+ 		split  :=  re .FindAllStringSubmatch (in , - 1 )
278+ 		if  len (split ) ==  1  &&  len (split [0 ]) ==  2  {
279+ 			return  split [0 ][1 ], "" , true 
280+ 		}
239281	}
240- 	return  split [0 ][1 ], split [0 ][2 ], true 
282+ 
283+ 	return  "" , "" , false 
241284}
242285
243286// UnmarshalYAML decodes a ProfilePlatformReference from YAML source. 
@@ -250,14 +293,23 @@ func (p *ProfilePlatformReference) UnmarshalYAML(unmarshal func(interface{}) err
250293		return  errors .New (i18n .Tr ("missing '%s' directive" , "platform" ))
251294	} else  if  platformID , platformVersion , ok  :=  parseNameAndVersion (platformID ); ! ok  {
252295		return  errors .New (i18n .Tr ("invalid '%s' directive" , "platform" ))
253- 	} else  if  c , err  :=  semver .Parse (platformVersion ); err  !=  nil  {
254- 		return  fmt .Errorf ("%s: %w" , i18n .Tr ("error parsing version constraints" ), err )
255- 	} else  if  split  :=  strings .SplitN (platformID , ":" , 2 ); len (split ) !=  2  {
256- 		return  fmt .Errorf ("%s: %s" , i18n .Tr ("invalid platform identifier" ), platformID )
257296	} else  {
258- 		p .Packager  =  split [0 ]
259- 		p .Architecture  =  split [1 ]
260- 		p .Version  =  c 
297+ 		var  version  * semver.Version 
298+ 		if  platformVersion  !=  ""  {
299+ 			if  v , err  :=  semver .Parse (platformVersion ); err  !=  nil  {
300+ 				return  fmt .Errorf ("%s: %w" , i18n .Tr ("error parsing version constraints" ), err )
301+ 			} else  {
302+ 				version  =  v 
303+ 			}
304+ 		}
305+ 
306+ 		if  split  :=  strings .SplitN (platformID , ":" , 2 ); len (split ) !=  2  {
307+ 			return  fmt .Errorf ("%s: %s" , i18n .Tr ("invalid platform identifier" ), platformID )
308+ 		} else  {
309+ 			p .Packager  =  split [0 ]
310+ 			p .Architecture  =  split [1 ]
311+ 			p .Version  =  version 
312+ 		}
261313	}
262314
263315	if  rawIndexURL , ok  :=  data ["platform_index_url" ]; ok  {
0 commit comments