Skip to content

Commit f7c2dc1

Browse files
committed
chore: extract option defaults to options package (#283)
Signed-off-by: Cian Johnston <[email protected]> (cherry picked from commit 09ce456)
1 parent 6fc1cfa commit f7c2dc1

File tree

5 files changed

+174
-130
lines changed

5 files changed

+174
-130
lines changed

envbuilder.go

+2-57
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"github.com/GoogleContainerTools/kaniko/pkg/creds"
3333
"github.com/GoogleContainerTools/kaniko/pkg/executor"
3434
"github.com/GoogleContainerTools/kaniko/pkg/util"
35-
giturls "github.com/chainguard-dev/git-urls"
3635
"github.com/coder/envbuilder/devcontainer"
3736
"github.com/coder/envbuilder/internal/ebutil"
3837
"github.com/coder/envbuilder/internal/log"
@@ -42,8 +41,6 @@ import (
4241
_ "github.com/distribution/distribution/v3/registry/storage/driver/filesystem"
4342
"github.com/docker/cli/cli/config/configfile"
4443
"github.com/fatih/color"
45-
"github.com/go-git/go-billy/v5"
46-
"github.com/go-git/go-billy/v5/osfs"
4744
"github.com/go-git/go-git/v5/plumbing/transport"
4845
v1 "github.com/google/go-containerregistry/pkg/v1"
4946
"github.com/google/go-containerregistry/pkg/v1/remote"
@@ -62,23 +59,8 @@ type DockerConfig configfile.ConfigFile
6259
// Filesystem is the filesystem to use for all operations.
6360
// Defaults to the host filesystem.
6461
func Run(ctx context.Context, opts options.Options) error {
65-
// Temporarily removed these from the default settings to prevent conflicts
66-
// between current and legacy environment variables that add default values.
67-
// Once the legacy environment variables are phased out, this can be
68-
// reinstated to the previous default values.
69-
if len(opts.IgnorePaths) == 0 {
70-
opts.IgnorePaths = []string{
71-
"/var/run",
72-
// KinD adds these paths to pods, so ignore them by default.
73-
"/product_uuid", "/product_name",
74-
}
75-
}
76-
if opts.InitScript == "" {
77-
opts.InitScript = "sleep infinity"
78-
}
79-
if opts.InitCommand == "" {
80-
opts.InitCommand = "/bin/sh"
81-
}
62+
opts.SetDefaults()
63+
8264
if opts.CacheRepo == "" && opts.PushImage {
8365
return fmt.Errorf("--cache-repo must be set when using --push-image")
8466
}
@@ -91,16 +73,6 @@ func Run(ctx context.Context, opts options.Options) error {
9173
return fmt.Errorf("parse init args: %w", err)
9274
}
9375
}
94-
if opts.Filesystem == nil {
95-
opts.Filesystem = &osfsWithChmod{osfs.New("/")}
96-
}
97-
if opts.WorkspaceFolder == "" {
98-
f, err := DefaultWorkspaceFolder(opts.GitURL)
99-
if err != nil {
100-
return err
101-
}
102-
opts.WorkspaceFolder = f
103-
}
10476

10577
stageNumber := 0
10678
startStage := func(format string, args ...any) func(format string, args ...any) {
@@ -930,25 +902,6 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
930902
return nil
931903
}
932904

933-
// DefaultWorkspaceFolder returns the default workspace folder
934-
// for a given repository URL.
935-
func DefaultWorkspaceFolder(repoURL string) (string, error) {
936-
if repoURL == "" {
937-
return constants.EmptyWorkspaceDir, nil
938-
}
939-
parsed, err := giturls.Parse(repoURL)
940-
if err != nil {
941-
return "", err
942-
}
943-
name := strings.Split(parsed.Path, "/")
944-
hasOwnerAndRepo := len(name) >= 2
945-
if !hasOwnerAndRepo {
946-
return constants.EmptyWorkspaceDir, nil
947-
}
948-
repo := strings.TrimSuffix(name[len(name)-1], ".git")
949-
return fmt.Sprintf("/workspaces/%s", repo), nil
950-
}
951-
952905
type userInfo struct {
953906
uid int
954907
gid int
@@ -1077,14 +1030,6 @@ func newColor(value ...color.Attribute) *color.Color {
10771030
return c
10781031
}
10791032

1080-
type osfsWithChmod struct {
1081-
billy.Filesystem
1082-
}
1083-
1084-
func (fs *osfsWithChmod) Chmod(name string, mode os.FileMode) error {
1085-
return os.Chmod(name, mode)
1086-
}
1087-
10881033
func findDevcontainerJSON(options options.Options) (string, string, error) {
10891034
// 0. Check if custom devcontainer directory or path is provided.
10901035
if options.DevcontainerDir != "" || options.DevcontainerJSONPath != "" {

envbuilder_test.go

-73
Original file line numberDiff line numberDiff line change
@@ -1,74 +1 @@
11
package envbuilder_test
2-
3-
import (
4-
"testing"
5-
6-
"github.com/coder/envbuilder"
7-
"github.com/coder/envbuilder/constants"
8-
9-
"github.com/stretchr/testify/require"
10-
)
11-
12-
func TestDefaultWorkspaceFolder(t *testing.T) {
13-
t.Parallel()
14-
15-
successTests := []struct {
16-
name string
17-
gitURL string
18-
expected string
19-
}{
20-
{
21-
name: "HTTP",
22-
gitURL: "https://github.com/coder/envbuilder.git",
23-
expected: "/workspaces/envbuilder",
24-
},
25-
{
26-
name: "SSH",
27-
gitURL: "[email protected]:coder/envbuilder.git",
28-
expected: "/workspaces/envbuilder",
29-
},
30-
{
31-
name: "username and password",
32-
gitURL: "https://username:[email protected]/coder/envbuilder.git",
33-
expected: "/workspaces/envbuilder",
34-
},
35-
{
36-
name: "fragment",
37-
gitURL: "https://github.com/coder/envbuilder.git#feature-branch",
38-
expected: "/workspaces/envbuilder",
39-
},
40-
{
41-
name: "empty",
42-
gitURL: "",
43-
expected: constants.EmptyWorkspaceDir,
44-
},
45-
}
46-
for _, tt := range successTests {
47-
t.Run(tt.name, func(t *testing.T) {
48-
dir, err := envbuilder.DefaultWorkspaceFolder(tt.gitURL)
49-
require.NoError(t, err)
50-
require.Equal(t, tt.expected, dir)
51-
})
52-
}
53-
54-
invalidTests := []struct {
55-
name string
56-
invalidURL string
57-
}{
58-
{
59-
name: "simple text",
60-
invalidURL: "not a valid URL",
61-
},
62-
{
63-
name: "website URL",
64-
invalidURL: "www.google.com",
65-
},
66-
}
67-
for _, tt := range invalidTests {
68-
t.Run(tt.name, func(t *testing.T) {
69-
dir, err := envbuilder.DefaultWorkspaceFolder(tt.invalidURL)
70-
require.NoError(t, err)
71-
require.Equal(t, constants.EmptyWorkspaceDir, dir)
72-
})
73-
}
74-
}

internal/chmodfs/chmodfs.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package chmodfs
2+
3+
import (
4+
"os"
5+
6+
"github.com/go-git/go-billy/v5"
7+
)
8+
9+
func New(fs billy.Filesystem) billy.Filesystem {
10+
return &osfsWithChmod{
11+
Filesystem: fs,
12+
}
13+
}
14+
15+
type osfsWithChmod struct {
16+
billy.Filesystem
17+
}
18+
19+
func (fs *osfsWithChmod) Chmod(name string, mode os.FileMode) error {
20+
return os.Chmod(name, mode)
21+
}

options/defaults.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package options
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/go-git/go-billy/v5/osfs"
8+
9+
giturls "github.com/chainguard-dev/git-urls"
10+
"github.com/coder/envbuilder/constants"
11+
"github.com/coder/envbuilder/internal/chmodfs"
12+
)
13+
14+
// DefaultWorkspaceFolder returns the default workspace folder
15+
// for a given repository URL.
16+
func DefaultWorkspaceFolder(repoURL string) string {
17+
if repoURL == "" {
18+
return constants.EmptyWorkspaceDir
19+
}
20+
parsed, err := giturls.Parse(repoURL)
21+
if err != nil {
22+
return constants.EmptyWorkspaceDir
23+
}
24+
name := strings.Split(parsed.Path, "/")
25+
hasOwnerAndRepo := len(name) >= 2
26+
if !hasOwnerAndRepo {
27+
return constants.EmptyWorkspaceDir
28+
}
29+
repo := strings.TrimSuffix(name[len(name)-1], ".git")
30+
return fmt.Sprintf("/workspaces/%s", repo)
31+
}
32+
33+
func (o *Options) SetDefaults() {
34+
// Temporarily removed these from the default settings to prevent conflicts
35+
// between current and legacy environment variables that add default values.
36+
// Once the legacy environment variables are phased out, this can be
37+
// reinstated to the previous default values.
38+
if len(o.IgnorePaths) == 0 {
39+
o.IgnorePaths = []string{
40+
"/var/run",
41+
// KinD adds these paths to pods, so ignore them by default.
42+
"/product_uuid", "/product_name",
43+
}
44+
}
45+
if o.InitScript == "" {
46+
o.InitScript = "sleep infinity"
47+
}
48+
if o.InitCommand == "" {
49+
o.InitCommand = "/bin/sh"
50+
}
51+
52+
if o.Filesystem == nil {
53+
o.Filesystem = chmodfs.New(osfs.New("/"))
54+
}
55+
if o.WorkspaceFolder == "" {
56+
o.WorkspaceFolder = DefaultWorkspaceFolder(o.GitURL)
57+
}
58+
}

options/defaults_test.go

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package options_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/coder/envbuilder/internal/chmodfs"
7+
"github.com/go-git/go-billy/v5/osfs"
8+
9+
"github.com/stretchr/testify/assert"
10+
11+
"github.com/coder/envbuilder/constants"
12+
"github.com/coder/envbuilder/options"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func TestDefaultWorkspaceFolder(t *testing.T) {
17+
t.Parallel()
18+
19+
successTests := []struct {
20+
name string
21+
gitURL string
22+
expected string
23+
}{
24+
{
25+
name: "HTTP",
26+
gitURL: "https://github.com/coder/envbuilder.git",
27+
expected: "/workspaces/envbuilder",
28+
},
29+
{
30+
name: "SSH",
31+
gitURL: "[email protected]:coder/envbuilder.git",
32+
expected: "/workspaces/envbuilder",
33+
},
34+
{
35+
name: "username and password",
36+
gitURL: "https://username:[email protected]/coder/envbuilder.git",
37+
expected: "/workspaces/envbuilder",
38+
},
39+
{
40+
name: "fragment",
41+
gitURL: "https://github.com/coder/envbuilder.git#feature-branch",
42+
expected: "/workspaces/envbuilder",
43+
},
44+
{
45+
name: "empty",
46+
gitURL: "",
47+
expected: constants.EmptyWorkspaceDir,
48+
},
49+
}
50+
for _, tt := range successTests {
51+
t.Run(tt.name, func(t *testing.T) {
52+
dir := options.DefaultWorkspaceFolder(tt.gitURL)
53+
require.Equal(t, tt.expected, dir)
54+
})
55+
}
56+
57+
invalidTests := []struct {
58+
name string
59+
invalidURL string
60+
}{
61+
{
62+
name: "simple text",
63+
invalidURL: "not a valid URL",
64+
},
65+
{
66+
name: "website URL",
67+
invalidURL: "www.google.com",
68+
},
69+
}
70+
for _, tt := range invalidTests {
71+
t.Run(tt.name, func(t *testing.T) {
72+
dir := options.DefaultWorkspaceFolder(tt.invalidURL)
73+
require.Equal(t, constants.EmptyWorkspaceDir, dir)
74+
})
75+
}
76+
}
77+
78+
func TestOptions_SetDefaults(t *testing.T) {
79+
t.Parallel()
80+
81+
expected := options.Options{
82+
InitScript: "sleep infinity",
83+
InitCommand: "/bin/sh",
84+
IgnorePaths: []string{"/var/run", "/product_uuid", "/product_name"},
85+
Filesystem: chmodfs.New(osfs.New("/")),
86+
GitURL: "",
87+
WorkspaceFolder: constants.EmptyWorkspaceDir,
88+
}
89+
90+
var actual options.Options
91+
actual.SetDefaults()
92+
assert.Equal(t, expected, actual)
93+
}

0 commit comments

Comments
 (0)