-
-
Notifications
You must be signed in to change notification settings - Fork 181
/
create.go
102 lines (88 loc) · 2.36 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package create
import (
"bytes"
"context"
_ "embed"
"fmt"
"io"
"os"
"path/filepath"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stdcopy"
"github.com/go-errors/errors"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
)
var (
//go:embed templates/clone.sh
cloneScript string
)
func Run(branch string, fsys afero.Fs) error {
if err := utils.LoadConfigFS(fsys); err != nil {
return err
}
if err := utils.AssertSupabaseDbIsRunning(); err != nil {
return err
}
branchPath := filepath.Join(filepath.Dir(utils.CurrBranchPath), branch)
if err := assertNewBranchIsValid(branchPath, fsys); err != nil {
return nil
}
var ctx = context.Background()
if err := createBranch(ctx, branch); err != nil {
return err
}
if err := fsys.MkdirAll(branchPath, 0755); err != nil {
return err
}
fmt.Println("Created branch " + utils.Aqua(branch) + ".")
return nil
}
func assertNewBranchIsValid(branchPath string, fsys afero.Fs) error {
branch := filepath.Base(branchPath)
if utils.IsBranchNameReserved(branch) {
return errors.New("Cannot create branch " + utils.Aqua(branch) + ": branch name is reserved.")
}
if !utils.BranchNamePattern.MatchString(branch) {
return errors.New("Branch name " + utils.Aqua(branch) + " is invalid. Must match [0-9A-Za-z_-]+.")
}
if _, err := afero.ReadDir(fsys, branchPath); errors.Is(err, os.ErrNotExist) {
// skip
} else if err != nil {
return err
} else {
return errors.New("Branch " + utils.Aqua(branch) + " already exists.")
}
return nil
}
func createBranch(ctx context.Context, branch string) error {
exec, err := utils.Docker.ContainerExecCreate(ctx, utils.DbId, types.ExecConfig{
Cmd: []string{"/bin/bash", "-c", cloneScript},
Env: []string{"DB_NAME=" + branch},
AttachStderr: true,
AttachStdout: true,
})
if err != nil {
return err
}
// Read exec output
resp, err := utils.Docker.ContainerExecAttach(ctx, exec.ID, types.ExecStartCheck{})
if err != nil {
return err
}
defer resp.Close()
// Capture error details
var errBuf bytes.Buffer
if _, err := stdcopy.StdCopy(io.Discard, &errBuf, resp.Reader); err != nil {
return err
}
// Get the exit code
iresp, err := utils.Docker.ContainerExecInspect(ctx, exec.ID)
if err != nil {
return err
}
if iresp.ExitCode > 0 {
return errors.New("Error creating branch: " + errBuf.String())
}
return nil
}