+121
-15
lines changedFilter options
+121
-15
lines changed Original file line number Diff line number Diff line change
@@ -248,6 +248,11 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
248
248
s := &cmderrors.PlatformLoadingError{Cause: err}
249
249
responseError(s.GRPCStatus())
250
250
}
251
+
} else if profile.RequireSystemInstalledPlatform() {
252
+
for _, err := range pmb.LoadGlobalHardwareForProfile(profile) {
253
+
s := &cmderrors.PlatformLoadingError{Cause: err}
254
+
responseError(s.GRPCStatus())
255
+
}
251
256
} else {
252
257
// Load platforms from profile
253
258
errs := pmb.LoadHardwareForProfile(ctx, profile, true, downloadCallback, taskCallback, s.settings)
Original file line number Diff line number Diff line change
@@ -28,9 +28,9 @@ profiles:
28
28
fqbn: <FQBN>
29
29
programmer: <PROGRAMMER>
30
30
platforms:
31
-
- platform: <PLATFORM> (<PLATFORM_VERSION>)
31
+
- platform: <PLATFORM> [(<PLATFORM_VERSION>)]
32
32
platform_index_url: <3RD_PARTY_PLATFORM_URL>
33
-
- platform: <PLATFORM_DEPENDENCY> (<PLATFORM_DEPENDENCY_VERSION>)
33
+
- platform: <PLATFORM_DEPENDENCY> [(<PLATFORM_DEPENDENCY_VERSION>)]
34
34
platform_index_url: <3RD_PARTY_PLATFORM_DEPENDENCY_URL>
35
35
libraries:
36
36
- <INDEX_LIB_NAME> (<INDEX_LIB_VERSION>)
@@ -73,6 +73,14 @@ The following fields are available since Arduino CLI 1.1.0:
73
73
`baudrate: 115200`) but any setting/value can be specified. Multiple settings can be set. These fields are optional.
74
74
- `<PORT_PROTOCOL>` is the protocol for the port used to upload and monitor the board. This field is optional.
75
75
76
+
#### Using a system-installed platform.
77
+
78
+
The fields `<PLATFORM_VERSION>` and `<PLATFORM_DEPENDENCY_VERSION>` are optional, if they are omitted, the sketch
79
+
compilation will use the platforms installed system-wide. This could be helpful during the development of a platform
80
+
(where a specific release is not yet available), or if a specific version of a platform is not a strict requirement.
81
+
82
+
#### An example of a complete project file.
83
+
76
84
A complete example of a sketch project file may be the following:
77
85
78
86
```
Original file line number Diff line number Diff line change
@@ -33,6 +33,13 @@ import (
33
33
"github.com/sirupsen/logrus"
34
34
)
35
35
36
+
// LoadGlobalHardwareForProfile loads the hardware platforms for the given profile.
37
+
// It uses the global package manager and does not download or install any missing tools or platforms.
38
+
func (pmb *Builder) LoadGlobalHardwareForProfile(p *sketch.Profile) []error {
39
+
pmb.profile = p
40
+
return pmb.LoadHardware()
41
+
}
42
+
36
43
// LoadHardwareForProfile load the hardware platforms for the given profile.
37
44
// If installMissing is true then possibly missing tools and platforms will be downloaded and installed.
38
45
func (pmb *Builder) LoadHardwareForProfile(ctx context.Context, p *sketch.Profile, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) []error {
Original file line number Diff line number Diff line change
@@ -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 {
Original file line number Diff line number Diff line change
@@ -39,4 +39,17 @@ func TestProjectFileLoading(t *testing.T) {
39
39
require.NoError(t, err)
40
40
require.Equal(t, proj.AsYaml(), string(golden))
41
41
}
42
+
{
43
+
sketchProj := paths.New("testdata", "profiles", "profile_1.yml")
44
+
proj, err := LoadProjectFile(sketchProj)
45
+
require.NoError(t, err)
46
+
golden, err := sketchProj.ReadFile()
47
+
require.NoError(t, err)
48
+
require.Equal(t, string(golden), proj.AsYaml())
49
+
}
50
+
{
51
+
sketchProj := paths.New("testdata", "profiles", "bad_profile_1.yml")
52
+
_, err := LoadProjectFile(sketchProj)
53
+
require.Error(t, err)
54
+
}
42
55
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
1
+
profiles:
2
+
tiny:
3
+
notes: Invalid profile mixing versioned and non-versioned platforms.
4
+
fqbn: attiny:avr:ATtinyX5:cpu=attiny85,clock=internal16
5
+
platforms:
6
+
- platform: attiny:avr
7
+
platform_index_url: http://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
8
+
- platform: arduino:avr (1.8.3)
9
+
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
1
+
profiles:
2
+
giga:
3
+
fqbn: arduino:mbed_giga:giga
4
+
platforms:
5
+
- platform: arduino:mbed_giga (4.3.1)
6
+
7
+
giga_any:
8
+
fqbn: arduino:mbed_giga:giga
9
+
platforms:
10
+
- platform: arduino:mbed_giga
11
+
12
+
default_profile: giga_any
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4