@@ -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