Allow platforms without fixed version in profiles. (#2940) · arduino/arduino-cli@3db4ad8 (original) (raw)
`@@ -120,6 +120,11 @@ type Profile struct {
`
120
120
`` Libraries ProfileRequiredLibraries yaml:"libraries"
``
121
121
`}
`
122
122
``
``
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
+
123
128
`// ToRpc converts this Profile to an rpc.SketchProfile
`
124
129
`func (p *Profile) ToRpc() *rpc.SketchProfile {
`
125
130
`var portConfig *rpc.MonitorPortConfiguration
`
`@@ -182,6 +187,20 @@ func (p *ProfileRequiredPlatforms) AsYaml() string {
`
182
187
`return res
`
183
188
`}
`
184
189
``
``
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
+
185
204
`// ProfileRequiredLibraries is a list of ProfileLibraryReference (libraries
`
186
205
`// required to build the sketch using this profile)
`
187
206
`type ProfileRequiredLibraries []*ProfileLibraryReference
`
`@@ -206,6 +225,12 @@ type ProfilePlatformReference struct {
`
206
225
`PlatformIndexURL *url.URL
`
207
226
`}
`
208
227
``
``
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
+
209
234
`// InternalUniqueIdentifier returns the unique identifier for this object
`
210
235
`func (p *ProfilePlatformReference) InternalUniqueIdentifier() string {
`
211
236
`id := p.String()
`
`@@ -224,20 +249,38 @@ func (p *ProfilePlatformReference) String() string {
`
224
249
``
225
250
`// AsYaml outputs the platform reference as Yaml
`
226
251
`func (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
`+
}
`
228
258
`if p.PlatformIndexURL != nil {
`
229
259
`res += fmt.Sprintf(" platform_index_url: %s\n", p.PlatformIndexURL)
`
230
260
` }
`
231
261
`return res
`
232
262
`}
`
233
263
``
234
264
`func 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
`+
}
`
239
281
` }
`
240
``
`-
return split[0][1], split[0][2], true
`
``
282
+
``
283
`+
return "", "", false
`
241
284
`}
`
242
285
``
243
286
`// UnmarshalYAML decodes a ProfilePlatformReference from YAML source.
`
`@@ -250,14 +293,23 @@ func (p *ProfilePlatformReference) UnmarshalYAML(unmarshal func(interface{}) err
`
250
293
`return errors.New(i18n.Tr("missing '%s' directive", "platform"))
`
251
294
` } else if platformID, platformVersion, ok := parseNameAndVersion(platformID); !ok {
`
252
295
`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)
`
257
296
` } 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
`+
}
`
261
313
` }
`
262
314
``
263
315
`if rawIndexURL, ok := data["platform_index_url"]; ok {
`