Skip to content

Commit 2d4ae91

Browse files
committed
Merge branch '5-fix-ruby-needs-to-be-the-last-runtime-installed'
2 parents c5263f7 + 8b7c3f7 commit 2d4ae91

File tree

2 files changed

+140
-7
lines changed

2 files changed

+140
-7
lines changed

internal/grpcserver/install_runtimes.go

+50-7
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ import (
99
"os"
1010
"os/exec"
1111
"path"
12+
"sort"
1213

1314
"github.com/eleven-sh/agent/config"
1415
"github.com/eleven-sh/agent/internal/env"
1516
"github.com/eleven-sh/agent/proto"
1617
)
1718

19+
type runtime struct {
20+
name string
21+
version string
22+
}
23+
1824
//go:embed runtimes/*
1925
var runtimeScripts embed.FS
2026

@@ -23,12 +29,14 @@ func (*agentServer) InstallRuntimes(
2329
stream proto.Agent_InstallRuntimesServer,
2430
) error {
2531

26-
for runtime, runtimeVersion := range req.Runtimes {
32+
sortedRuntimes := sortRuntimes(req.Runtimes)
33+
34+
for _, runtime := range sortedRuntimes {
2735
err := stream.Send(&proto.InstallRuntimesReply{
2836
LogLineHeader: fmt.Sprintf(
2937
"Installing %s@%s",
30-
runtime,
31-
runtimeVersion,
38+
runtime.name,
39+
runtime.version,
3240
),
3341
})
3442

@@ -37,7 +45,7 @@ func (*agentServer) InstallRuntimes(
3745
}
3846

3947
installRuntimeScriptFilePath, err := createInstallRuntimeScriptFile(
40-
runtime,
48+
runtime.name,
4149
)
4250

4351
if err != nil {
@@ -48,7 +56,7 @@ func (*agentServer) InstallRuntimes(
4856

4957
installRuntimeCmd := buildInstallRuntimeCmd(
5058
installRuntimeScriptFilePath,
51-
runtimeVersion,
59+
runtime.version,
5260
)
5361

5462
stdoutReader, err := buildInstallRuntimeCmdStdoutReader(installRuntimeCmd)
@@ -102,8 +110,8 @@ func (*agentServer) InstallRuntimes(
102110
if err := installRuntimeCmd.Wait(); err != nil {
103111
return fmt.Errorf(
104112
"error installing %s@%s (%v)",
105-
runtime,
106-
runtimeVersion,
113+
runtime.name,
114+
runtime.version,
107115
err,
108116
)
109117
}
@@ -125,6 +133,41 @@ func (*agentServer) InstallRuntimes(
125133
)
126134
}
127135

136+
func sortRuntimes(runtimes map[string]string) []runtime {
137+
runtimeNames := []string{}
138+
for runtimeName := range runtimes {
139+
runtimeNames = append(runtimeNames, runtimeName)
140+
}
141+
sort.Strings(runtimeNames)
142+
143+
sortedRuntimes := []runtime{}
144+
var rubyRuntime *runtime
145+
146+
for _, runtimeName := range runtimeNames {
147+
runtimeVersion := runtimes[runtimeName]
148+
149+
if runtimeName == "ruby" {
150+
rubyRuntime = &runtime{
151+
name: runtimeName,
152+
version: runtimeVersion,
153+
}
154+
continue
155+
}
156+
157+
sortedRuntimes = append(sortedRuntimes, runtime{
158+
name: runtimeName,
159+
version: runtimeVersion,
160+
})
161+
}
162+
163+
// RVM needs to be the last change to the $PATH env var
164+
if rubyRuntime != nil {
165+
sortedRuntimes = append(sortedRuntimes, *rubyRuntime)
166+
}
167+
168+
return sortedRuntimes
169+
}
170+
128171
func createInstallRuntimeScriptFile(runtime string) (string, error) {
129172
installRuntimeScriptFile, err := os.CreateTemp("", "eleven_install_runtime_*")
130173

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package grpcserver
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestSortRuntimes(t *testing.T) {
9+
testCases := []struct {
10+
test string
11+
runtimes map[string]string
12+
expectedRuntimes []runtime
13+
}{
14+
{
15+
test: "with no runtimes",
16+
runtimes: map[string]string{},
17+
expectedRuntimes: []runtime{},
18+
},
19+
20+
{
21+
test: "with ruby runtime",
22+
runtimes: map[string]string{
23+
"docker": "latest",
24+
"ruby": "3.1.2",
25+
"python": "2.4.0",
26+
"rust": "1.0.1",
27+
},
28+
expectedRuntimes: []runtime{
29+
{
30+
name: "docker",
31+
version: "latest",
32+
},
33+
34+
{
35+
name: "python",
36+
version: "2.4.0",
37+
},
38+
39+
{
40+
name: "rust",
41+
version: "1.0.1",
42+
},
43+
44+
{
45+
name: "ruby",
46+
version: "3.1.2",
47+
},
48+
},
49+
},
50+
51+
{
52+
test: "without ruby runtime",
53+
runtimes: map[string]string{
54+
"docker": "latest",
55+
"python": "2.4.0",
56+
"node": "1.0.1",
57+
},
58+
expectedRuntimes: []runtime{
59+
{
60+
name: "docker",
61+
version: "latest",
62+
},
63+
64+
{
65+
name: "node",
66+
version: "1.0.1",
67+
},
68+
69+
{
70+
name: "python",
71+
version: "2.4.0",
72+
},
73+
},
74+
},
75+
}
76+
77+
for _, tc := range testCases {
78+
t.Run(tc.test, func(t *testing.T) {
79+
sortedRuntimes := sortRuntimes(tc.runtimes)
80+
81+
if !reflect.DeepEqual(sortedRuntimes, tc.expectedRuntimes) {
82+
t.Fatalf(
83+
"expected runtimes to equal '%+v', got '%+v'",
84+
tc.expectedRuntimes,
85+
sortedRuntimes,
86+
)
87+
}
88+
})
89+
}
90+
}

0 commit comments

Comments
 (0)