Skip to content

Commit cdcec9b

Browse files
committed
Removed global *viper.Viper settings instance
Now the configuration is kept inside the arduinoCoreServiceImpl struct. No more direct access to the configuration, the required config values are passed as arguments or available trough struct fields. Viper object is now embedded into a new configuration.Setting object. This would allow to make better getters and setters methods in the next commits. HTTP downloader configuration is generated using the configuration.
1 parent 888a931 commit cdcec9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+460
-441
lines changed

Diff for: commands/instances.go

+50-29
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ import (
4949
func installTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error {
5050
pme, release := pm.NewExplorer()
5151
defer release()
52+
5253
taskCB(&rpc.TaskProgress{Name: tr("Downloading missing tool %s", tool)})
53-
if err := pme.DownloadToolRelease(tool, nil, downloadCB); err != nil {
54+
if err := pme.DownloadToolRelease(tool, downloadCB); err != nil {
5455
return fmt.Errorf(tr("downloading %[1]s tool: %[2]s"), tool, err)
5556
}
5657
taskCB(&rpc.TaskProgress{Completed: true})
@@ -62,16 +63,16 @@ func installTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, dow
6263

6364
// Create a new Instance ready to be initialized, supporting directories are also created.
6465
func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) {
65-
var userAgent []string
66+
var userAgent string
6667
if md, ok := metadata.FromIncomingContext(ctx); ok {
67-
userAgent = md.Get("user-agent")
68+
userAgent = strings.Join(md.Get("user-agent"), " ")
6869
}
69-
if len(userAgent) == 0 {
70-
userAgent = []string{"gRPCClientUnknown/0.0.0"}
70+
if userAgent == "" {
71+
userAgent = "gRPCClientUnknown/0.0.0"
7172
}
7273

7374
// Setup downloads directory
74-
downloadsDir := configuration.DownloadsDir(configuration.Settings)
75+
downloadsDir := configuration.DownloadsDir(s.settings)
7576
if downloadsDir.NotExist() {
7677
err := downloadsDir.MkdirAll()
7778
if err != nil {
@@ -80,16 +81,20 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque
8081
}
8182

8283
// Setup data directory
83-
dataDir := configuration.DataDir(configuration.Settings)
84-
packagesDir := configuration.PackagesDir(configuration.Settings)
84+
dataDir := configuration.DataDir(s.settings)
85+
packagesDir := configuration.PackagesDir(s.settings)
8586
if packagesDir.NotExist() {
8687
err := packagesDir.MkdirAll()
8788
if err != nil {
8889
return nil, &cmderrors.PermissionDeniedError{Message: tr("Failed to create data directory"), Cause: err}
8990
}
9091
}
9192

92-
inst, err := instances.Create(dataDir, packagesDir, downloadsDir, userAgent...)
93+
config, err := s.settings.DownloaderConfig()
94+
if err != nil {
95+
return nil, err
96+
}
97+
inst, err := instances.Create(dataDir, packagesDir, downloadsDir, userAgent, config)
9398
if err != nil {
9499
return nil, err
95100
}
@@ -108,6 +113,8 @@ func InitStreamResponseToCallbackFunction(ctx context.Context, cb func(r *rpc.In
108113
// Failures don't stop the loading process, in case of loading failure the Platform or library
109114
// is simply skipped and an error gRPC status is sent to responseCallback.
110115
func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error {
116+
ctx := stream.Context()
117+
111118
instance := req.GetInstance()
112119
if !instances.IsValid(instance) {
113120
return &cmderrors.InvalidInstanceError{}
@@ -170,7 +177,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
170177
defaultIndexURL, _ := utils.URLParse(globals.DefaultIndexURL)
171178
allPackageIndexUrls := []*url.URL{defaultIndexURL}
172179
if profile == nil {
173-
for _, u := range configuration.Settings.GetStringSlice("board_manager.additional_urls") {
180+
for _, u := range s.settings.GetStringSlice("board_manager.additional_urls") {
174181
URL, err := utils.URLParse(u)
175182
if err != nil {
176183
e := &cmderrors.InitFailedError{
@@ -185,7 +192,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
185192
}
186193
}
187194

188-
if err := firstUpdate(context.Background(), s, req.GetInstance(), downloadCallback, allPackageIndexUrls); err != nil {
195+
if err := firstUpdate(ctx, s, req.GetInstance(), configuration.DataDir(s.settings), downloadCallback, allPackageIndexUrls); err != nil {
189196
e := &cmderrors.InitFailedError{
190197
Code: codes.InvalidArgument,
191198
Cause: err,
@@ -238,15 +245,13 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
238245

239246
// Load Platforms
240247
if profile == nil {
241-
for _, err := range pmb.LoadHardware() {
248+
for _, err := range pmb.LoadHardware(s.settings) {
242249
s := &cmderrors.PlatformLoadingError{Cause: err}
243250
responseError(s.GRPCStatus())
244251
}
245252
} else {
246253
// Load platforms from profile
247-
errs := pmb.LoadHardwareForProfile(
248-
profile, true, downloadCallback, taskCallback,
249-
)
254+
errs := pmb.LoadHardwareForProfile(profile, true, downloadCallback, taskCallback, s.settings)
250255
for _, err := range errs {
251256
s := &cmderrors.PlatformLoadingError{Cause: err}
252257
responseError(s.GRPCStatus())
@@ -344,7 +349,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
344349

345350
if profile == nil {
346351
// Add directories of libraries bundled with IDE
347-
if bundledLibsDir := configuration.IDEBuiltinLibrariesDir(configuration.Settings); bundledLibsDir != nil {
352+
if bundledLibsDir := configuration.IDEBuiltinLibrariesDir(s.settings); bundledLibsDir != nil {
348353
lmb.AddLibrariesDir(librariesmanager.LibrariesDir{
349354
Path: bundledLibsDir,
350355
Location: libraries.IDEBuiltIn,
@@ -353,14 +358,14 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
353358

354359
// Add libraries directory from config file
355360
lmb.AddLibrariesDir(librariesmanager.LibrariesDir{
356-
Path: configuration.LibrariesDir(configuration.Settings),
361+
Path: configuration.LibrariesDir(s.settings),
357362
Location: libraries.User,
358363
})
359364
} else {
360365
// Load libraries required for profile
361366
for _, libraryRef := range profile.Libraries {
362367
uid := libraryRef.InternalUniqueIdentifier()
363-
libRoot := configuration.ProfilesCacheDir(configuration.Settings).Join(uid)
368+
libRoot := configuration.ProfilesCacheDir(s.settings).Join(uid)
364369
libDir := libRoot.Join(libraryRef.Library)
365370

366371
if !libDir.IsDir() {
@@ -373,7 +378,14 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
373378
responseError(err.GRPCStatus())
374379
continue
375380
}
376-
if err := libRelease.Resource.Download(pme.DownloadDir, nil, libRelease.String(), downloadCallback, ""); err != nil {
381+
config, err := s.settings.DownloaderConfig()
382+
if err != nil {
383+
taskCallback(&rpc.TaskProgress{Name: tr("Error downloading library %s", libraryRef)})
384+
e := &cmderrors.FailedLibraryInstallError{Cause: err}
385+
responseError(e.GRPCStatus())
386+
continue
387+
}
388+
if err := libRelease.Resource.Download(pme.DownloadDir, config, libRelease.String(), downloadCallback, ""); err != nil {
377389
taskCallback(&rpc.TaskProgress{Name: tr("Error downloading library %s", libraryRef)})
378390
e := &cmderrors.FailedLibraryInstallError{Cause: err}
379391
responseError(e.GRPCStatus())
@@ -409,7 +421,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
409421
// Refreshes the locale used, this will change the
410422
// language of the CLI if the locale is different
411423
// after started.
412-
i18n.Init(configuration.Settings.GetString("locale"))
424+
i18n.Init(s.settings.GetString("locale"))
413425

414426
return nil
415427
}
@@ -487,7 +499,11 @@ func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd
487499
// Perform index update
488500
// TODO: pass context
489501
// ctx := stream.Context()
490-
if err := globals.LibrariesIndexResource.Download(indexDir, downloadCB); err != nil {
502+
config, err := s.settings.DownloaderConfig()
503+
if err != nil {
504+
return err
505+
}
506+
if err := globals.LibrariesIndexResource.Download(indexDir, downloadCB, config); err != nil {
491507
resultCB(rpc.IndexUpdateReport_STATUS_FAILED)
492508
return err
493509
}
@@ -532,11 +548,11 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream
532548
Message: &rpc.UpdateIndexResponse_DownloadProgress{DownloadProgress: p},
533549
})
534550
}
535-
indexpath := configuration.DataDir(configuration.Settings)
551+
indexpath := configuration.DataDir(s.settings)
536552

537553
urls := []string{globals.DefaultIndexURL}
538554
if !req.GetIgnoreCustomPackageIndexes() {
539-
urls = append(urls, configuration.Settings.GetStringSlice("board_manager.additional_urls")...)
555+
urls = append(urls, s.settings.GetStringSlice("board_manager.additional_urls")...)
540556
}
541557

542558
failed := false
@@ -593,11 +609,18 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream
593609
}
594610
}
595611

612+
config, err := s.settings.DownloaderConfig()
613+
if err != nil {
614+
downloadCB.Start(u, tr("Downloading index: %s", filepath.Base(URL.Path)))
615+
downloadCB.End(false, tr("Invalid network configuration: %s", err))
616+
failed = true
617+
}
618+
596619
if strings.HasSuffix(URL.Host, "arduino.cc") && strings.HasSuffix(URL.Path, ".json") {
597620
indexResource.SignatureURL, _ = url.Parse(u) // should not fail because we already parsed it
598621
indexResource.SignatureURL.Path += ".sig"
599622
}
600-
if err := indexResource.Download(indexpath, downloadCB); err != nil {
623+
if err := indexResource.Download(indexpath, downloadCB, config); err != nil {
601624
failed = true
602625
result.UpdatedIndexes = append(result.GetUpdatedIndexes(), report(URL, rpc.IndexUpdateReport_STATUS_FAILED))
603626
} else {
@@ -615,10 +638,8 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream
615638

616639
// firstUpdate downloads libraries and packages indexes if they don't exist.
617640
// This ideally is only executed the first time the CLI is run.
618-
func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error {
619-
// Gets the data directory to verify if library_index.json and package_index.json exist
620-
dataDir := configuration.DataDir(configuration.Settings)
621-
libraryIndex := dataDir.Join("library_index.json")
641+
func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, indexDir *paths.Path, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error {
642+
libraryIndex := indexDir.Join("library_index.json")
622643

623644
if libraryIndex.NotExist() {
624645
// The library_index.json file doesn't exists, that means the CLI is run for the first time
@@ -640,7 +661,7 @@ func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance
640661
Message: tr("Error downloading index '%s'", URL),
641662
Cause: &cmderrors.InvalidURLError{}}
642663
}
643-
packageIndexFile := dataDir.Join(packageIndexFileName)
664+
packageIndexFile := indexDir.Join(packageIndexFileName)
644665
if packageIndexFile.NotExist() {
645666
// The index file doesn't exists, that means the CLI is run for the first time,
646667
// or the 3rd party package index URL has just been added. Similarly to the

Diff for: commands/internal/instances/instances.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2626
"github.com/arduino/arduino-cli/version"
2727
"github.com/arduino/go-paths-helper"
28+
"go.bug.st/downloader/v2"
2829
)
2930

3031
// coreInstance is an instance of the Arduino Core Services. The user can
@@ -133,15 +134,15 @@ func SetLibraryManager(inst *rpc.Instance, lm *librariesmanager.LibrariesManager
133134
}
134135

135136
// Create a new *rpc.Instance ready to be initialized
136-
func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent ...string) (*rpc.Instance, error) {
137+
func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent string, downloaderConfig downloader.Config) (*rpc.Instance, error) {
137138
// Create package manager
138139
userAgent := "arduino-cli/" + version.VersionInfo.VersionString
139-
for _, ua := range extraUserAgent {
140-
userAgent += " " + ua
140+
if extraUserAgent != "" {
141+
userAgent += " " + extraUserAgent
141142
}
142143
tempDir := dataDir.Join("tmp")
143144

144-
pm := packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent).Build()
145+
pm := packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent, downloaderConfig).Build()
145146
lm, _ := librariesmanager.NewBuilder().Build()
146147

147148
instance := &coreInstance{

Diff for: commands/service.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,26 @@ package commands
1818
import (
1919
"context"
2020

21+
"github.com/arduino/arduino-cli/internal/cli/configuration"
2122
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2223
)
2324

2425
// NewArduinoCoreServer returns an implementation of the ArduinoCoreService gRPC service
2526
// that uses the provided version string.
26-
func NewArduinoCoreServer(version string) rpc.ArduinoCoreServiceServer {
27+
func NewArduinoCoreServer(version string, settings *configuration.Settings) rpc.ArduinoCoreServiceServer {
2728
return &arduinoCoreServerImpl{
2829
versionString: version,
30+
settings: settings,
2931
}
3032
}
3133

3234
type arduinoCoreServerImpl struct {
3335
rpc.UnsafeArduinoCoreServiceServer // Force compile error for unimplemented methods
3436

3537
versionString string
38+
39+
// Settings holds configurations of the CLI and the gRPC consumers
40+
settings *configuration.Settings
3641
}
3742

3843
// Version returns the version of the Arduino CLI

Diff for: commands/service_board_list.go

+11-14
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232
f "github.com/arduino/arduino-cli/internal/algorithms"
3333
"github.com/arduino/arduino-cli/internal/arduino/cores"
3434
"github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager"
35-
"github.com/arduino/arduino-cli/internal/arduino/httpclient"
35+
"github.com/arduino/arduino-cli/internal/cli/configuration"
3636
"github.com/arduino/arduino-cli/internal/inventory"
3737
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3838
"github.com/arduino/go-properties-orderedmap"
@@ -45,7 +45,7 @@ var (
4545
validVidPid = regexp.MustCompile(`0[xX][a-fA-F\d]{4}`)
4646
)
4747

48-
func cachedAPIByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
48+
func cachedAPIByVidPid(vid, pid string, settings *configuration.Settings) ([]*rpc.BoardListItem, error) {
4949
var resp []*rpc.BoardListItem
5050

5151
cacheKey := fmt.Sprintf("cache.builder-api.v3/boards/byvid/pid/%s/%s", vid, pid)
@@ -59,7 +59,7 @@ func cachedAPIByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
5959
}
6060
}
6161

62-
resp, err := apiByVidPid(vid, pid) // Perform API requrest
62+
resp, err := apiByVidPid(vid, pid, settings) // Perform API requrest
6363

6464
if err == nil {
6565
if cachedResp, err := json.Marshal(resp); err == nil {
@@ -71,7 +71,7 @@ func cachedAPIByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
7171
return resp, err
7272
}
7373

74-
func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
74+
func apiByVidPid(vid, pid string, settings *configuration.Settings) ([]*rpc.BoardListItem, error) {
7575
// ensure vid and pid are valid before hitting the API
7676
if !validVidPid.MatchString(vid) {
7777
return nil, errors.New(tr("Invalid vid value: '%s'", vid))
@@ -84,10 +84,7 @@ func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
8484
req, _ := http.NewRequest("GET", url, nil)
8585
req.Header.Set("Content-Type", "application/json")
8686

87-
// TODO: use proxy if set
88-
89-
httpClient, err := httpclient.New()
90-
87+
httpClient, err := settings.NewHttpClient()
9188
if err != nil {
9289
return nil, fmt.Errorf("%s: %w", tr("failed to initialize http client"), err)
9390
}
@@ -130,18 +127,18 @@ func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
130127
}, nil
131128
}
132129

133-
func identifyViaCloudAPI(props *properties.Map) ([]*rpc.BoardListItem, error) {
130+
func identifyViaCloudAPI(props *properties.Map, settings *configuration.Settings) ([]*rpc.BoardListItem, error) {
134131
// If the port is not USB do not try identification via cloud
135132
if !props.ContainsKey("vid") || !props.ContainsKey("pid") {
136133
return nil, nil
137134
}
138135

139136
logrus.Debug("Querying builder API for board identification...")
140-
return cachedAPIByVidPid(props.Get("vid"), props.Get("pid"))
137+
return cachedAPIByVidPid(props.Get("vid"), props.Get("pid"), settings)
141138
}
142139

143140
// identify returns a list of boards checking first the installed platforms or the Cloud API
144-
func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardListItem, error) {
141+
func identify(pme *packagemanager.Explorer, port *discovery.Port, settings *configuration.Settings) ([]*rpc.BoardListItem, error) {
145142
boards := []*rpc.BoardListItem{}
146143
if port.Properties == nil {
147144
return boards, nil
@@ -173,7 +170,7 @@ func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardL
173170
// if installed cores didn't recognize the board, try querying
174171
// the builder API if the board is a USB device port
175172
if len(boards) == 0 {
176-
items, err := identifyViaCloudAPI(port.Properties)
173+
items, err := identifyViaCloudAPI(port.Properties, settings)
177174
if err != nil {
178175
// this is bad, but keep going
179176
logrus.WithError(err).Debug("Error querying builder API")
@@ -227,7 +224,7 @@ func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardLis
227224

228225
ports := []*rpc.DetectedPort{}
229226
for _, port := range dm.List() {
230-
boards, err := identify(pme, port)
227+
boards, err := identify(pme, port, s.settings)
231228
if err != nil {
232229
warnings = append(warnings, err.Error())
233230
}
@@ -306,7 +303,7 @@ func (s *arduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s
306303

307304
boardsError := ""
308305
if event.Type == "add" {
309-
boards, err := identify(pme, event.Port)
306+
boards, err := identify(pme, event.Port, s.settings)
310307
if err != nil {
311308
boardsError = err.Error()
312309
}

0 commit comments

Comments
 (0)