Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5ad5bdb
[breaking] Split rpc Init and remove Rescan function
silvanocerza May 7, 2021
dbad881
[breaking] Refactored commands package to reflect gRPC changes
silvanocerza Jun 7, 2021
1e8764f
[breaking] Refactored cli package to reflect commands changes
silvanocerza Apr 23, 2021
93655a4
Fix instance creation for CLI commands that update indexes
silvanocerza Apr 23, 2021
9adeb3f
Fix unit tests
silvanocerza Apr 23, 2021
2079c0c
Change update indexes commands to not reload instance after
silvanocerza Jun 7, 2021
ced6b48
Fix installation of builtin tools
silvanocerza Apr 23, 2021
a9141cf
Fix integration tests
silvanocerza Apr 23, 2021
58821fd
Fix code for linting
silvanocerza Apr 23, 2021
61b40d2
Update i18n files
silvanocerza Apr 26, 2021
e0b20df
Update UPGRADING.md with breaking changes
silvanocerza Jun 7, 2021
29aacd4
Update comment with correct information
silvanocerza Apr 27, 2021
f4391fd
Using callback instead of channel+goroutine for Init
cmaglie Apr 27, 2021
0c0f8a5
Enhance platform loading step
silvanocerza Apr 27, 2021
410ecd7
Update client_example to reflect new gRPC changes
silvanocerza Apr 27, 2021
2e44c3b
Enhance Init docstring
silvanocerza Apr 29, 2021
1193930
Enhance builtin tools installation during Init
silvanocerza Apr 29, 2021
68871fc
Fix unit test
silvanocerza May 11, 2021
7b035d1
Fix integration tests
silvanocerza May 11, 2021
30280c2
[skip changelog] Fix after botched rebase
silvanocerza Jun 7, 2021
d6ed084
Fix issue when using Init to rescan installed core on already initial…
silvanocerza Jun 15, 2021
bee0970
Update generated file from .proto
silvanocerza Jun 16, 2021
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
Using callback instead of channel+goroutine for Init
  • Loading branch information
cmaglie authored and silvanocerza committed Jun 16, 2021
commit f4391fde202ea0700b7916716a94b2fb233340e6
14 changes: 6 additions & 8 deletions cli/instance/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,12 @@ func Init(instance *rpc.Instance) []*status.Status {
return append(errs, err)
}

initChan, err := commands.Init(&rpc.InitRequest{
Instance: instance,
})
if err != nil {
return append(errs, err)
}

downloadCallback := output.ProgressBar()
taskCallback := output.TaskProgress()

for res := range initChan {
err := commands.Init(&rpc.InitRequest{
Instance: instance,
}, func(res *rpc.InitResponse) {
if err := res.GetError(); err != nil {
errs = append(errs, status.FromProto(err))
}
Expand All @@ -91,6 +86,9 @@ func Init(instance *rpc.Instance) []*status.Status {
taskCallback(progress.TaskProgress)
}
}
})
if err != nil {
return append(errs, err)
}

return errs
Expand Down
2 changes: 1 addition & 1 deletion commands/core/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest,
return nil, err
}

_, status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: req.Instance.Id}})
status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil)
if status != nil {
return nil, status.Err()
}
Expand Down
2 changes: 1 addition & 1 deletion commands/core/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t
}
}

_, status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: req.Instance.Id}})
status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil)
if status != nil {
return nil, status.Err()
}
Expand Down
2 changes: 1 addition & 1 deletion commands/core/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest,
return nil, err
}

_, status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: req.Instance.Id}})
status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil)
if status != nil {
return nil, status.Err()
}
Expand Down
17 changes: 4 additions & 13 deletions commands/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,12 @@ func (s *ArduinoCoreServerImpl) Create(_ context.Context, req *rpc.CreateRequest

// Init FIXMEDOC
func (s *ArduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error {
messageChan, err := commands.Init(req)
err := commands.Init(req, func(message *rpc.InitResponse) {
stream.Send(message)
})
if err != nil {
return stream.Send(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: err.Proto(),
},
})
return err.Err()
}

for message := range messageChan {
if err := stream.Send(message); err != nil {
return err
}
}

return nil
}

Expand Down
246 changes: 122 additions & 124 deletions commands/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,172 +166,170 @@ func Create(req *rpc.CreateRequest) (*rpc.CreateResponse, *status.Status) {
// Failures don't stop the loading process, in case of loading failure the Platform or library
// is simply skipped and an error gRPC status is sent in the returned channel.
// Channel is closed when loading is finished.
func Init(req *rpc.InitRequest) (<-chan *rpc.InitResponse, *status.Status) {
func Init(req *rpc.InitRequest, resp func(r *rpc.InitResponse)) *status.Status {
if resp == nil {
resp = func(r *rpc.InitResponse) {}
}
instance := instances[req.Instance.Id]
if instance == nil {
return nil, status.Newf(codes.InvalidArgument, "Invalid instance ID")
return status.Newf(codes.InvalidArgument, "Invalid instance ID")
}

outChan := make(chan *rpc.InitResponse)
go func() {
defer close(outChan)

// Load Platforms
urls := []string{globals.DefaultIndexURL}
urls = append(urls, configuration.Settings.GetStringSlice("board_manager.additional_urls")...)
for _, u := range urls {
URL, err := utils.URLParse(u)
if err != nil {
s := status.Newf(codes.InvalidArgument, "Invalid additional URL: %v", err)
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
continue
}

if URL.Scheme == "file" {
indexFile := paths.New(URL.Path)
// Load Platforms
urls := []string{globals.DefaultIndexURL}
urls = append(urls, configuration.Settings.GetStringSlice("board_manager.additional_urls")...)
for _, u := range urls {
URL, err := utils.URLParse(u)
if err != nil {
s := status.Newf(codes.InvalidArgument, "Invalid additional URL: %v", err)
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
})
continue
}

_, err := instance.PackageManager.LoadPackageIndexFromFile(indexFile)
if err != nil {
s := status.Newf(codes.FailedPrecondition, "Loading index file: %v", err)
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
}
continue
}
if URL.Scheme == "file" {
indexFile := paths.New(URL.Path)

if err := instance.PackageManager.LoadPackageIndex(URL); err != nil {
_, err := instance.PackageManager.LoadPackageIndexFromFile(indexFile)
if err != nil {
s := status.Newf(codes.FailedPrecondition, "Loading index file: %v", err)
outChan <- &rpc.InitResponse{
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
})
}
continue
}

// We load hardware before verifying builtin tools are installed
// otherwise we wouldn't find them and reinstall them each time
// and they would never get reloaded.
for _, err := range instance.PackageManager.LoadHardware() {
outChan <- &rpc.InitResponse{
if err := instance.PackageManager.LoadPackageIndex(URL); err != nil {
s := status.Newf(codes.FailedPrecondition, "Loading index file: %v", err)
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: err.Proto(),
Error: s.Proto(),
},
}
})
}
}

taskCallback := func(msg *rpc.TaskProgress) {
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_InitProgress{
InitProgress: &rpc.InitResponse_Progress{
TaskProgress: msg,
},
// We load hardware before verifying builtin tools are installed
// otherwise we wouldn't find them and reinstall them each time
// and they would never get reloaded.
for _, err := range instance.PackageManager.LoadHardware() {
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: err.Proto(),
},
})
}

taskCallback := func(msg *rpc.TaskProgress) {
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_InitProgress{
InitProgress: &rpc.InitResponse_Progress{
TaskProgress: msg,
},
}
}
},
})
}

downloadCallback := func(msg *rpc.DownloadProgress) {
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_InitProgress{
InitProgress: &rpc.InitResponse_Progress{
DownloadProgress: msg,
},
downloadCallback := func(msg *rpc.DownloadProgress) {
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_InitProgress{
InitProgress: &rpc.InitResponse_Progress{
DownloadProgress: msg,
},
}
}
},
})
}

// Install tools if necessary
toolHasBeenInstalled := false
ctagsTool, err := getBuiltinCtagsTool(instance.PackageManager)
// Install tools if necessary
toolHasBeenInstalled := false
ctagsTool, err := getBuiltinCtagsTool(instance.PackageManager)
if err != nil {
s := status.Newf(codes.Internal, err.Error())
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
})
} else {
ctagsInstalled, err := instance.installToolIfMissing(ctagsTool, downloadCallback, taskCallback)
toolHasBeenInstalled = toolHasBeenInstalled || ctagsInstalled
if err != nil {
s := status.Newf(codes.Internal, err.Error())
outChan <- &rpc.InitResponse{
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
} else {
ctagsInstalled, err := instance.installToolIfMissing(ctagsTool, downloadCallback, taskCallback)
toolHasBeenInstalled = toolHasBeenInstalled || ctagsInstalled
if err != nil {
s := status.Newf(codes.Internal, err.Error())
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
}
})
}
}

serialDiscoveryTool, _ := getBuiltinSerialDiscoveryTool(instance.PackageManager)
serialDiscoveryTool, _ := getBuiltinSerialDiscoveryTool(instance.PackageManager)
if err != nil {
s := status.Newf(codes.Internal, err.Error())
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
})
} else {
serialDiscoveryToolInstalled, err := instance.installToolIfMissing(serialDiscoveryTool, downloadCallback, taskCallback)
toolHasBeenInstalled = toolHasBeenInstalled || serialDiscoveryToolInstalled
if err != nil {
s := status.Newf(codes.Internal, err.Error())
outChan <- &rpc.InitResponse{
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
} else {
serialDiscoveryToolInstalled, err := instance.installToolIfMissing(serialDiscoveryTool, downloadCallback, taskCallback)
toolHasBeenInstalled = toolHasBeenInstalled || serialDiscoveryToolInstalled
if err != nil {
s := status.Newf(codes.Internal, err.Error())
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
}
}
}

if toolHasBeenInstalled {
// We installed at least one new tool after loading hardware
// so we must reload again otherwise we would never found them.
for _, err := range instance.PackageManager.LoadHardware() {
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: err.Proto(),
},
}
}
}

// Load libraries
for _, pack := range instance.PackageManager.Packages {
for _, platform := range pack.Platforms {
if platformRelease := instance.PackageManager.GetInstalledPlatformRelease(platform); platformRelease != nil {
instance.lm.AddPlatformReleaseLibrariesDir(platformRelease, libraries.PlatformBuiltIn)
}
}
})
}
}

if err := instance.lm.LoadIndex(); err != nil {
s := status.Newf(codes.FailedPrecondition, "Loading index file: %v", err)
outChan <- &rpc.InitResponse{
if toolHasBeenInstalled {
// We installed at least one new tool after loading hardware
// so we must reload again otherwise we would never found them.
for _, err := range instance.PackageManager.LoadHardware() {
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
Error: err.Proto(),
},
}
})
}
}

for _, err := range instance.lm.RescanLibraries() {
s := status.Newf(codes.FailedPrecondition, "Loading libraries: %v", err)
outChan <- &rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
// Load libraries
for _, pack := range instance.PackageManager.Packages {
for _, platform := range pack.Platforms {
if platformRelease := instance.PackageManager.GetInstalledPlatformRelease(platform); platformRelease != nil {
instance.lm.AddPlatformReleaseLibrariesDir(platformRelease, libraries.PlatformBuiltIn)
}
}
}()
}

if err := instance.lm.LoadIndex(); err != nil {
s := status.Newf(codes.FailedPrecondition, "Loading index file: %v", err)
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
})
}

return outChan, nil
for _, err := range instance.lm.RescanLibraries() {
s := status.Newf(codes.FailedPrecondition, "Loading libraries: %v", err)
resp(&rpc.InitResponse{
Message: &rpc.InitResponse_Error{
Error: s.Proto(),
},
})
}

return nil
}

// Destroy FIXMEDOC
Expand Down
2 changes: 1 addition & 1 deletion commands/lib/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest,
}
}

_, status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: req.Instance.Id}})
status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil)
if status != nil {
return fmt.Errorf("rescanning libraries: %s", status.Err())
}
Expand Down
2 changes: 1 addition & 1 deletion commands/lib/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func LibraryUpgradeAll(instanceID int32, downloadCB commands.DownloadProgressCB,
return err
}

_, status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: instanceID}})
status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: instanceID}}, nil)
if status != nil {
return fmt.Errorf("rescanning libraries: %s", status.Err())
}
Expand Down