Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
803782c
cosmetic: renamed import
cmaglie Apr 27, 2022
e82a46d
Simplify function pm.DownloadPlatformRelease
cmaglie Mar 31, 2022
1b1867f
Implementation of the Profiles parser
cmaglie Mar 14, 2022
da64af5
Added methods to get profiles from sketch
cmaglie Mar 14, 2022
670c9f1
Added gRPC parameters to support profiles
cmaglie Mar 14, 2022
79eb7f4
Added function to load packages for profiles
cmaglie Mar 14, 2022
183a8bb
Added support for profiles in compile command
cmaglie Apr 26, 2022
1b53f59
Added progress callback and installMissing flag (stubs) in pm.Prepare…
cmaglie Mar 31, 2022
4f8244a
Added auto-install procedures for profiles
cmaglie Mar 31, 2022
c21147b
Handle platform not found errors
cmaglie Mar 31, 2022
8527015
Draft implementation of upload with profiles
cmaglie Mar 28, 2022
10d95b2
Made packagemamager.loadToolsFromPackage public
cmaglie Apr 29, 2022
6cc5d65
Simplified callbacks in commands.Init
cmaglie Apr 29, 2022
18b0d34
cosmetic: added shortcut variable for library manager
cmaglie Apr 29, 2022
4a26bd4
cosmetic: added shortcut variable for package manager; small readabil…
cmaglie Apr 29, 2022
5449677
Wiring profiles into arduino-cli and gRPC implementation
cmaglie May 2, 2022
5972501
Made gRPC Init return a full Profile structure
cmaglie May 2, 2022
efa8899
(tech debt) Disable profiles if compiling with --libraries/--library
cmaglie May 2, 2022
61081f1
Fixed some linter warnings
cmaglie May 2, 2022
6156a26
Apply suggestions from code review
cmaglie May 5, 2022
9d1ec03
Added profiles specification docs
cmaglie May 10, 2022
d998f7f
Allow both sketch.yaml and .yml (with priority for .yaml)
cmaglie May 10, 2022
be8b325
Correctly handle nil return value
cmaglie May 10, 2022
614d652
Apply suggestions from code review
cmaglie May 19, 2022
8cdb8cb
Apply suggestions from code review
cmaglie May 19, 2022
bae72d0
Provide `core install` suggestions only when compiling without profiles
cmaglie May 19, 2022
170382d
Remove stray comment
cmaglie May 19, 2022
633022f
Fixed some comments in protoc files
cmaglie May 19, 2022
1fdbce6
Apply suggestions from code review
cmaglie May 19, 2022
b206d47
Apply suggestions from code review
cmaglie May 20, 2022
453f750
Implemented missing AsYaml methods and added tests
cmaglie May 20, 2022
75f4117
Apply suggestions from code review
cmaglie May 20, 2022
8203266
run of prettier formatter
cmaglie May 20, 2022
e20117f
Preserve profiles ordering in profiles.yaml
cmaglie May 20, 2022
21e8e86
Apply suggestions from code review
cmaglie May 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implementation of the Profiles parser
  • Loading branch information
cmaglie committed May 20, 2022
commit 1b1867fac3a0b9e4a19a42fb73d19f9b59f76284
192 changes: 192 additions & 0 deletions arduino/sketch/profiles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// This file is part of arduino-cli.
//
// Copyright 2020-2022 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to [email protected].

package sketch

import (
"fmt"
"net/url"
"regexp"
"strings"

"github.com/arduino/go-paths-helper"
semver "go.bug.st/relaxed-semver"
"gopkg.in/yaml.v2"
)

// Project represents all the
type Project struct {
Profiles map[string]*Profile `yaml:"profiles"`
DefaultProfile string `yaml:"default_profile"`
}

// AsYaml outputs the project file as Yaml
func (p *Project) AsYaml() string {
res := "profiles:\n"
for name, profile := range p.Profiles {
res += fmt.Sprintf(" %s:\n", name)
res += profile.AsYaml()
res += "\n"
}
if p.DefaultProfile != "" {
res += fmt.Sprintf("default_profile: %s\n", p.DefaultProfile)
}
return res
}

// Profile is a sketch profile, it contains a reference to all the resources
// needed to build and upload a sketch
type Profile struct {
Notes string `yaml:"notes"`
FQBN string `yaml:"fqbn"`
Platforms ProfileRequiredPlatforms `yaml:"platforms"`
Libraries ProfileRequiredLibraries `yaml:"libraries"`
}

// AsYaml outputs the profile as Yaml
func (p *Profile) AsYaml() string {
res := ""
if p.Notes != "" {
res += fmt.Sprintf(" notes: %s\n", p.Notes)
}
res += fmt.Sprintf(" fqbn: %s\n", p.FQBN)
res += p.Platforms.AsYaml()
res += p.Libraries.AsYaml()
return res
}

// ProfileRequiredPlatforms is a list of ProfilePlatformReference (platforms
// required to build the sketch using this profile)
type ProfileRequiredPlatforms []*ProfilePlatformReference

// AsYaml outputs the required platforms as Yaml
func (p *ProfileRequiredPlatforms) AsYaml() string {
res := ""
for _, platform := range *p {
res += platform.AsYaml()
}
return res
}

// ProfileRequiredLibraries is a list of ProfileLibraryReference (libraries
// required to build the sketch using this profile)
type ProfileRequiredLibraries []*ProfileLibraryReference

// AsYaml outputs the required libraries as Yaml
func (p *ProfileRequiredLibraries) AsYaml() string {
return ""
}

// ProfilePlatformReference is a reference to a platform
type ProfilePlatformReference struct {
Packager string
Architecture string
Version *semver.Version
PlatformIndexURL *url.URL
}

func (p *ProfilePlatformReference) String() string {
res := fmt.Sprintf("%s:%s@%s", p.Packager, p.Architecture, p.Version)
if p.PlatformIndexURL != nil {
res += fmt.Sprintf(" (%s)", p.PlatformIndexURL)
}
return res
}

// AsYaml outputs the platform reference as Yaml
func (p *ProfilePlatformReference) AsYaml() string {
res := fmt.Sprintf(" - platform: %s:%s (%s)\n", p.Packager, p.Architecture, p.Version)
if p.PlatformIndexURL != nil {
res += fmt.Sprintf(" platform_index_url: %s\n", p.PlatformIndexURL)
}
return res
}

func parseNameAndVersion(in string) (string, string, bool) {
re := regexp.MustCompile(`^([a-zA-Z0-9.\-_ :]+) \((.+)\)$`)
split := re.FindAllStringSubmatch(in, -1)
if len(split) != 1 || len(split[0]) != 3 {
return "", "", false
}
return split[0][1], split[0][2], true
}

func (p *ProfilePlatformReference) UnmarshalYAML(unmarshal func(interface{}) error) error {
var data map[string]string
if err := unmarshal(&data); err != nil {
return err
}
if platformId, ok := data["platform"]; !ok {
return fmt.Errorf(tr("missing 'platform' directive"))
} else if platformId, platformVersion, ok := parseNameAndVersion(platformId); !ok {
return fmt.Errorf(tr("invalid 'platform' directive"))
} else if c, err := semver.Parse(platformVersion); err != nil {
return fmt.Errorf("%s: %w", tr("error parsing version constraints"), err)
} else if split := strings.SplitN(platformId, ":", 2); len(split) != 2 {
return fmt.Errorf("%s: %s", tr("invalid platform identifier"), platformId)
} else {
p.Packager = split[0]
p.Architecture = split[1]
p.Version = c
}

if rawIndexURL, ok := data["platform_index_url"]; ok {
if indexURL, err := url.Parse(rawIndexURL); err != nil {
return fmt.Errorf("%s: %w", tr("invlid platform index URL:"), err)
} else {
p.PlatformIndexURL = indexURL
}
}
return nil
}

// ProfileLibraryReference is a reference to a library
type ProfileLibraryReference struct {
Library string
Version *semver.Version
}

func (l *ProfileLibraryReference) UnmarshalYAML(unmarshal func(interface{}) error) error {
var data string
if err := unmarshal(&data); err != nil {
return err
}
if libName, libVersion, ok := parseNameAndVersion(data); !ok {
return fmt.Errorf("%s %s", tr("invalid library directive:"), data)
} else if v, err := semver.Parse(libVersion); err != nil {
return fmt.Errorf("%s %w", tr("invalid version:"), err)
} else {
l.Library = libName
l.Version = v
}
return nil
}

func (l *ProfileLibraryReference) String() string {
return fmt.Sprintf("%s@%s", l.Library, l.Version)
}

// LoadProjectFile reads a sketch project file
func LoadProjectFile(file *paths.Path) (*Project, error) {
data, err := file.ReadFile()
if err != nil {
return nil, err
}
res := &Project{}
if err := yaml.Unmarshal(data, &res); err != nil {
return nil, err
}
return res, nil
}
30 changes: 30 additions & 0 deletions arduino/sketch/profiles_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// This file is part of arduino-cli.
//
// Copyright 2020-2022 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to [email protected].

package sketch

import (
"fmt"
"testing"

"github.com/arduino/go-paths-helper"
"github.com/stretchr/testify/require"
)

func TestProjectFileLoading(t *testing.T) {
proj, err := LoadProjectFile(paths.New("testdata", "SketchWithProfiles", "sketch.yml"))
require.NoError(t, err)
fmt.Println(proj)
}
43 changes: 43 additions & 0 deletions arduino/sketch/testdata/SketchWithProfiles/sketch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
profiles:
nanorp:
fqbn: arduino:mbed_nano:nanorp2040connect
platforms:
- platform: arduino:mbed_nano (2.1.0)
libraries:
- ArduinoIoTCloud (1.0.2)
- Arduino_ConnectionHandler (0.6.4)
- TinyDHT sensor library (1.1.0)

another_profile_name:
notes: testing the limit of the AVR platform, may be unstable
fqbn: arduino:avr:uno
platforms:
- platform: arduino:avr (1.8.4)
libraries:
- VitconMQTT (1.0.1)
- Arduino_ConnectionHandler (0.6.4)
- TinyDHT sensor library (1.1.0)

tiny:
notes: testing the very limit of the AVR platform, it will be very unstable
fqbn: attiny:avr:ATtinyX5:cpu=attiny85,clock=internal16
platforms:
- platform: attiny:avr (1.0.2)
platform_index_url: http://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
- platform: arduino:avr (1.8.3)
libraries:
- ArduinoIoTCloud (1.0.2)
- Arduino_ConnectionHandler (0.6.4)
- TinyDHT sensor library (1.1.0)

feather:
fqbn: adafruit:samd:adafruit_feather_m0
platforms:
- platform: adafruit:samd (1.6.0)
platform_index_url: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
libraries:
- ArduinoIoTCloud (1.0.2)
- Arduino_ConnectionHandler (0.6.4)
- TinyDHT sensor library (1.1.0)

default_profile: nanorp