Skip to content

Commit 0b71938

Browse files
committed
Added upload command
1 parent 280b19e commit 0b71938

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed

commands/root/root.go

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"github.com/bcmi-labs/arduino-cli/commands/login"
4545
"github.com/bcmi-labs/arduino-cli/commands/logout"
4646
"github.com/bcmi-labs/arduino-cli/commands/sketch"
47+
"github.com/bcmi-labs/arduino-cli/commands/upload"
4748
"github.com/bcmi-labs/arduino-cli/commands/validate"
4849
"github.com/bcmi-labs/arduino-cli/commands/version"
4950
"github.com/bcmi-labs/arduino-cli/common/formatter"
@@ -107,6 +108,7 @@ func Init(_isTesting bool) {
107108
login.Init(Command)
108109
logout.Init(Command)
109110
sketch.Init(Command)
111+
upload.Init(Command)
110112
validate.Init(Command)
111113
version.Init(Command)
112114
}

commands/upload/upload.go

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* This file is part of arduino-cli.
3+
*
4+
* arduino-cli is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*
18+
* As a special exception, you may use this file as part of a free software
19+
* library without restriction. Specifically, if other files instantiate
20+
* templates or use macros or inline functions from this file, or you compile
21+
* this file and link it with other files to produce an executable, this
22+
* file does not by itself cause the resulting executable to be covered by
23+
* the GNU General Public License. This exception does not however
24+
* invalidate any other reasons why the executable file might be covered by
25+
* the GNU General Public License.
26+
*
27+
* Copyright 2017-2018 ARDUINO AG (http://www.arduino.cc/)
28+
*/
29+
30+
package upload
31+
32+
import (
33+
"fmt"
34+
"os"
35+
"path/filepath"
36+
"strings"
37+
38+
properties "github.com/arduino/go-properties-map"
39+
"github.com/bcmi-labs/arduino-cli/commands"
40+
"github.com/bcmi-labs/arduino-cli/common/formatter"
41+
"github.com/bcmi-labs/arduino-cli/cores"
42+
"github.com/bcmi-labs/arduino-cli/sketches"
43+
"github.com/spf13/cobra"
44+
)
45+
46+
// Init prepares the command.
47+
func Init(rootCommand *cobra.Command) {
48+
rootCommand.AddCommand(command)
49+
command.Flags().StringVarP(&flags.fqbn, "fqbn", "b", "", "Fully Qualified Board Name, e.g.: arduino:avr:uno")
50+
command.Flags().StringVarP(&flags.port, "port", "p", "", "Upload port, e.g.: COM10 or /dev/ttyACM0")
51+
command.Flags().BoolVarP(&flags.verbose, "verbose", "v", false, "Optional, turns on verbose mode.")
52+
}
53+
54+
var flags struct {
55+
fqbn string
56+
port string
57+
verbose bool
58+
}
59+
60+
var command = &cobra.Command{
61+
Use: "upload",
62+
Short: "Upload Arduino sketches.",
63+
Long: "Upload Arduino sketches.",
64+
Example: "arduino upload [sketchName]",
65+
Args: cobra.ExactArgs(0),
66+
Run: run,
67+
}
68+
69+
func run(cmd *cobra.Command, args []string) {
70+
// FIXME: factorize a general way to determine current sketch
71+
var sketchName string
72+
if len(args) == 0 {
73+
sketchName, err := os.Getwd()
74+
if err != nil {
75+
formatter.PrintError(err, "Could not determine current working directory")
76+
os.Exit(commands.ErrGeneric)
77+
}
78+
sketchName = filepath.Base(sketchName)
79+
} else {
80+
sketchName = args[0]
81+
}
82+
83+
// FIXME: make a specification on how a port is specified via command line
84+
port := flags.port
85+
if port == "" {
86+
formatter.PrintErrorMessage("No port provided.")
87+
os.Exit(commands.ErrBadCall)
88+
}
89+
90+
fqbn := flags.fqbn
91+
if fqbn == "" {
92+
sketch, err := sketches.GetSketch(sketchName)
93+
if err == nil && sketch != nil {
94+
fqbn = sketch.Metadata.CPU.Fqbn
95+
}
96+
}
97+
if fqbn == "" {
98+
formatter.PrintErrorMessage("No Fully Qualified Board Name provided.")
99+
os.Exit(commands.ErrBadCall)
100+
}
101+
fqbnParts := strings.Split(fqbn, ":")
102+
if len(fqbnParts) < 3 || len(fqbnParts) > 4 {
103+
formatter.PrintErrorMessage("Fully Qualified Board Name has incorrect format.")
104+
os.Exit(commands.ErrBadCall)
105+
}
106+
packageName := fqbnParts[0]
107+
coreName := fqbnParts[1]
108+
boardName := fqbnParts[2]
109+
110+
pm := commands.InitPackageManager()
111+
if err := pm.LoadHardware(); err != nil {
112+
fmt.Printf("Error loading hardware: %s", err)
113+
os.Exit(commands.ErrCoreConfig)
114+
}
115+
116+
// Find target board
117+
// TODO: Make a packagemanager function to do this
118+
targetPackage := pm.GetPackages().Packages[packageName]
119+
if targetPackage == nil {
120+
formatter.PrintErrorMessage("Unknown package " + packageName + ".")
121+
os.Exit(commands.ErrBadCall)
122+
}
123+
platform := targetPackage.Platforms[coreName]
124+
if platform == nil {
125+
formatter.PrintErrorMessage("Unknown platform " + packageName + ":" + coreName + ".")
126+
os.Exit(commands.ErrBadCall)
127+
}
128+
platformRelease := platform.GetInstalled()
129+
if platformRelease == nil {
130+
formatter.PrintErrorMessage("Platform " + packageName + ":" + coreName + " is not installed.")
131+
os.Exit(commands.ErrBadCall)
132+
}
133+
board := platformRelease.Boards[boardName]
134+
if board == nil {
135+
formatter.PrintErrorMessage("Unknown board " + packageName + ":" + coreName + ":" + boardName + ".")
136+
os.Exit(commands.ErrBadCall)
137+
}
138+
139+
// Create board configuration
140+
var boardProperties properties.Map
141+
if len(fqbnParts) == 3 {
142+
boardProperties = board.Properties
143+
} else {
144+
if props, err := board.GeneratePropertiesForConfiguration(fqbnParts[3]); err != nil {
145+
formatter.PrintError(err, "Invalid FQBN.")
146+
os.Exit(commands.ErrBadCall)
147+
} else {
148+
boardProperties = props
149+
}
150+
}
151+
152+
// Load programmer tool
153+
var referencedPackage *cores.Package
154+
var referencedPlatform *cores.Platform
155+
var referencedPlatformRelease *cores.PlatformRelease
156+
uploadToolID, have := boardProperties["upload.tool"]
157+
if !have || uploadToolID == "" {
158+
formatter.PrintErrorMessage("The board defines an invalid 'upload.tool': " + uploadToolID)
159+
os.Exit(commands.ErrGeneric)
160+
}
161+
var uploadTool *cores.Tool
162+
if split := strings.Split(uploadToolID, ":"); len(split) == 1 {
163+
uploadTool = targetPackage.Tools[uploadToolID]
164+
} else if len(split) == 2 {
165+
referencedPackage = pm.GetPackages().Packages[split[0]]
166+
if referencedPackage == nil {
167+
formatter.PrintErrorMessage("The board requires a tool from package '" + split[0] + "' that is not installed: " + uploadToolID)
168+
os.Exit(commands.ErrGeneric)
169+
}
170+
uploadTool = referencedPackage.Tools[split[1]]
171+
172+
referencedPlatform = referencedPackage.Platforms[coreName]
173+
if referencedPlatform != nil {
174+
referencedPlatformRelease = referencedPlatform.GetInstalled()
175+
}
176+
} else {
177+
formatter.PrintErrorMessage("The board defines an invalid 'upload.tool': " + uploadToolID)
178+
os.Exit(commands.ErrGeneric)
179+
}
180+
if uploadTool == nil {
181+
formatter.PrintErrorMessage("Upload tool '" + uploadToolID + "' not found.")
182+
os.Exit(commands.ErrGeneric)
183+
}
184+
// FIXME: Look into index if the platform requires a specific version
185+
uploadToolInstance := uploadTool.GetLatestInstalled()
186+
if uploadToolInstance == nil {
187+
formatter.PrintErrorMessage("Upload tool '" + uploadToolID + "' not installed.")
188+
os.Exit(commands.ErrGeneric)
189+
}
190+
fmt.Println(boardProperties.Dump())
191+
fmt.Println(uploadToolInstance)
192+
193+
}

0 commit comments

Comments
 (0)