Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func Init(cfg config.Configuration) {

var (
GetBricksIndex = sync.OnceValue(func() *bricksindex.BricksIndex {
return f.Must(bricksindex.Load(GetStaticStore().GetAssetsFolder()))
return f.Must(bricksindex.Load(GetStaticStore()))
})

GetModelsIndex = sync.OnceValue(func() *modelsindex.ModelsIndex {
Expand Down
2 changes: 1 addition & 1 deletion internal/api/handlers/app_ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func GetBrickPortInfoByID(bricks []app.Brick, bricksIndex *bricksindex.BricksInd
return nil, fmt.Errorf("brick %q not found in the index", brick.ID)
}
brickInfoByID[brick.ID] = BrickPortInfo{
Ports: brickData.Ports,
Ports: brickData.GetPorts(),
RequiresDisplay: brickData.RequiresDisplay,
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/e2e/daemon/brick_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestBricksList(t *testing.T) {
require.NotEmpty(t, response.JSON200.Bricks)

staticStore := store.NewStaticStore(paths.New("testdata", "assets", config.RunnerVersion).String())
brickIndex, err := bricksindex.Load(staticStore.GetAssetsFolder())
brickIndex, err := bricksindex.Load(staticStore)
require.NoError(t, err)

// Compare the response with the bricks index
Expand Down
3 changes: 2 additions & 1 deletion internal/orchestrator/archive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ import (
"github.com/arduino/arduino-app-cli/internal/orchestrator/app"
"github.com/arduino/arduino-app-cli/internal/orchestrator/bricksindex"
"github.com/arduino/arduino-app-cli/internal/orchestrator/config"
"github.com/arduino/arduino-app-cli/internal/store"
)

func TestExportAppZip(t *testing.T) {
bricksIndex, err := bricksindex.Load(paths.New("testdata", "archive"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata/assets"))
require.NoError(t, err)

type testCase struct {
Expand Down
12 changes: 6 additions & 6 deletions internal/orchestrator/bricks/bricks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
)

func TestBrickCreate(t *testing.T) {
bricksIndex, err := bricksindex.Load(paths.New("testdata"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata"))
require.Nil(t, err)
brickService := NewService(nil, bricksIndex, nil)

Expand Down Expand Up @@ -102,7 +102,7 @@ func TestBrickCreate(t *testing.T) {
require.Nil(t, err)
err = paths.New("testdata/dummy-app").CopyDirTo(tempDummyApp)
require.Nil(t, err)
bricksIndex, err := bricksindex.Load(paths.New("testdata"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata"))
require.Nil(t, err)
brickService := NewService(nil, bricksIndex, nil)

Expand All @@ -129,7 +129,7 @@ func TestBrickCreate(t *testing.T) {
}

func TestUpdateBrick(t *testing.T) {
bricksIndex, err := bricksindex.Load(paths.New("testdata"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata"))
require.Nil(t, err)
brickService := NewService(nil, bricksIndex, nil)

Expand Down Expand Up @@ -189,7 +189,7 @@ func TestUpdateBrick(t *testing.T) {
tempDummyApp := paths.New("testdata/dummy-app.temp")
require.Nil(t, tempDummyApp.RemoveAll())
require.Nil(t, paths.New("testdata/dummy-app").CopyDirTo(tempDummyApp))
bricksIndex, err := bricksindex.Load(paths.New("testdata"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata"))
require.Nil(t, err)
brickService := NewService(nil, bricksIndex, nil)

Expand Down Expand Up @@ -218,7 +218,7 @@ func TestUpdateBrick(t *testing.T) {
tempDummyApp := paths.New("testdata/dummy-app-for-update.temp")
require.Nil(t, tempDummyApp.RemoveAll())
require.Nil(t, paths.New("testdata/dummy-app-for-update").CopyDirTo(tempDummyApp))
bricksIndex, err := bricksindex.Load(paths.New("testdata"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata"))
require.Nil(t, err)
brickService := NewService(nil, bricksIndex, nil)

Expand Down Expand Up @@ -246,7 +246,7 @@ func TestUpdateBrick(t *testing.T) {
tempDummyApp := paths.New("testdata/dummy-app-for-model.temp")
require.Nil(t, tempDummyApp.RemoveAll())
require.Nil(t, paths.New("testdata/dummy-app-for-model").CopyDirTo(tempDummyApp))
bricksIndex, err := bricksindex.Load(paths.New("testdata"))
bricksIndex, err := bricksindex.Load(store.NewStaticStore("testdata"))
require.NoError(t, err)
modelsIndex, err := modelsindex.Load(paths.New("testdata"), paths.New("not_exixsting_path"))
require.NoError(t, err)
Expand Down
70 changes: 60 additions & 10 deletions internal/orchestrator/bricksindex/bricks_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
package bricksindex

import (
"io"
"iter"
"maps"
"slices"
"strings"

"github.com/arduino/go-paths-helper"
yaml "github.com/goccy/go-yaml"

"github.com/arduino/arduino-app-cli/internal/orchestrator/peripherals"
"github.com/arduino/arduino-app-cli/internal/store"
)

type BricksIndex struct {
Expand Down Expand Up @@ -62,6 +63,7 @@ type Brick struct {
RequireModel bool `yaml:"require_model"`
Variables []BrickVariable `yaml:"variables,omitempty"`
Ports []string `yaml:"ports,omitempty"`
containerPorts []string `yaml:"-"`
ModelName string `yaml:"model_name,omitempty"`
MountDevicesIntoContainer bool `yaml:"mount_devices_into_container,omitempty"`
RequiredDevices []peripherals.DeviceClass `yaml:"required_devices,omitempty"`
Expand All @@ -87,19 +89,67 @@ func (b Brick) GetDefaultVariables() iter.Seq2[string, string] {
}
}

func unmarshalBricksIndex(content io.Reader) (*BricksIndex, error) {
var index BricksIndex
if err := yaml.NewDecoder(content).Decode(&index); err != nil {
return nil, err
func (b Brick) GetPorts() []string {
portsSet := make(map[string]struct{}, len(b.Ports)+len(b.containerPorts))
for _, p := range b.Ports {
portsSet[p] = struct{}{}
}
return &index, nil
for _, p := range b.containerPorts {
portsSet[p] = struct{}{}
}
return slices.Collect(maps.Keys(portsSet))
}

func Load(dir *paths.Path) (*BricksIndex, error) {
content, err := dir.Join("bricks-list.yaml").Open()
func Load(staticstore *store.StaticStore) (*BricksIndex, error) {
content, err := staticstore.GetAssetsFolder().Join("bricks-list.yaml").Open()
if err != nil {
return nil, err
}
defer content.Close()
return unmarshalBricksIndex(content)

var index BricksIndex
if err := yaml.NewDecoder(content).Decode(&index); err != nil {
return nil, err
}

// Parse the compose file to read the extra ports.
for i := range index.Bricks {
composeFilePath, err := staticstore.GetBrickComposeFilePathFromID(index.Bricks[i].ID)
if err != nil {
return nil, err
}

if !index.Bricks[i].RequireContainer || composeFilePath.NotExist() {
continue
}

f, err := composeFilePath.Open()
if err != nil {
return nil, err
}
defer f.Close()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having a defer f.Close() inside the loop causes many pending f.Close() at the same time, since the defer will be called at the end of Load().
We could extract a helper function to get the ports: getComposePorts(composeFilePath *paths.Path) ([]string, error)


var compose struct {
Services map[string]struct {
Ports []string `yaml:"ports,omitempty"`
} `yaml:"services"`
}
if err := yaml.NewDecoder(f).Decode(&compose); err != nil {
return nil, err
}

for _, service := range compose.Services {
for _, portStr := range service.Ports {
if strings.Contains(portStr, ":") {
parts := strings.Split(portStr, ":")
hostPort := parts[len(parts)-2] // Extract the host port (the one before the last colon)
index.Bricks[i].containerPorts = append(index.Bricks[i].containerPorts, hostPort)
} else {
index.Bricks[i].containerPorts = append(index.Bricks[i].containerPorts, portStr)
}
}
Comment on lines +140 to +147
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a unit test for the port parsing
Currenlty we have this ${BIND_ADDRESS:-127.0.0.1}:1340:1337

}
}

return &index, nil
}
Loading