summaryrefslogtreecommitdiffstats
path: root/pkg/integration/components/shell.go
blob: d0f0345dc02fc0536b98ef97ded2ea5407c85e8d (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package components

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/jesseduffield/lazygit/pkg/secureexec"
	"github.com/mgutz/str"
)

// this is for running shell commands, mostly for the sake of setting up the repo
// but you can also run the commands from within lazygit to emulate things happening
// in the background.
type Shell struct {
	// working directory the shell is invoked in
	dir string
}

func NewShell(dir string) *Shell {
	return &Shell{dir: dir}
}

func (s *Shell) RunCommand(cmdStr string) *Shell {
	args := str.ToArgv(cmdStr)
	cmd := secureexec.Command(args[0], args[1:]...)
	cmd.Env = os.Environ()
	cmd.Dir = s.dir

	output, err := cmd.CombinedOutput()
	if err != nil {
		panic(fmt.Sprintf("error running command: %s\n%s", cmdStr, string(output)))
	}

	return s
}

func (s *Shell) RunShellCommand(cmdStr string) *Shell {
	cmd := secureexec.Command("sh", "-c", cmdStr)
	cmd.Env = os.Environ()
	cmd.Dir = s.dir

	output, err := cmd.CombinedOutput()
	if err != nil {
		panic(fmt.Sprintf("error running shell command: %s\n%s", cmdStr, string(output)))
	}

	return s
}

func (s *Shell) RunShellCommandExpectError(cmdStr string) *Shell {
	cmd := secureexec.Command("sh", "-c", cmdStr)
	cmd.Env = os.Environ()
	cmd.Dir = s.dir

	output, err := cmd.CombinedOutput()
	if err == nil {
		panic(fmt.Sprintf("Expected error running shell command: %s\n%s", cmdStr, string(output)))
	}

	return s
}

func (s *Shell) CreateFile(path string, content string) *Shell {
	fullPath := filepath.Join(s.dir, path)
	err := os.WriteFile(fullPath, []byte(content), 0o644)
	if err != nil {
		panic(fmt.Sprintf("error creating file: %s\n%s", fullPath, err))
	}

	return s
}

func (s *Shell) CreateDir(path string) *Shell {
	fullPath := filepath.Join(s.dir, path)
	if err := os.MkdirAll(fullPath, 0o755); err != nil {
		panic(fmt.Sprintf("error creating directory: %s\n%s", fullPath, err))
	}

	return s
}

func (s *Shell) UpdateFile(path string, content string) *Shell {
	fullPath := filepath.Join(s.dir, path)
	err := os.WriteFile(fullPath, []byte(content), 0o644)
	if err != nil {
		panic(fmt.Sprintf("error updating file: %s\n%s", fullPath, err))
	}

	return s
}

func (s *Shell) NewBranch(name string) *Shell {
	return s.RunCommand("git checkout -b " + name)
}

func (s *Shell) Checkout(name string) *Shell {
	return s.RunCommand("git checkout " + name)
}

func (s *Shell) Merge(name string) *Shell {
	return s.RunCommand("git merge --commit --no-ff " + name)
}

func (s *Shell) GitAdd(path string) *Shell {
	return s.RunCommand(fmt.Sprintf("git add \"%s\"", path))
}

func (s *Shell) GitAddAll() *Shell {
	return s.RunCommand("git add -A")
}

func (s *Shell) Commit(message string) *Shell {
	return s.RunCommand(fmt.Sprintf("git commit -m \"%s\"", message))
}

func (s *Shell) EmptyCommit(message string) *Shell {
	return s.RunCommand(fmt.Sprintf("git commit --allow-empty -m \"%s\"", message))
}

// convenience method for creating a file and adding it
func (s *Shell) CreateFileAndAdd(fileName string, fileContents string) *Shell {
	return s.
		CreateFile(fileName, fileContents).
		GitAdd(fileName)
}

// convenience method for updating a file and adding it
func (s *Shell) UpdateFileAndAdd(fileName string, fileContents string) *Shell {
	return s.
		UpdateFile(fileName, fileContents).
		GitAdd(fileName)
}

// creates commits 01, 02, 03, ..., n with a new file in each
// The reason for padding with zeroes is so that it's easier to do string
// matches on the commit messages when there are many of them
func (s *Shell) CreateNCommits(n int) *Shell {
	for i := 1; i <= n; i++ {
		s.CreateFileAndAdd(
			fmt.Sprintf("file%02d.txt", i),
			fmt.Sprintf("file%02d content", i),
		).
			Commit(fmt.Sprintf("commit %02d", i))
	}

	return s
}

func (s *Shell) StashWithMessage(message string) *Shell {
	s.RunCommand(fmt.Sprintf(`git stash -m "%s"`, message))
	return s
}

func (s *Shell) SetConfig(key string, value string) *Shell {
	s.RunCommand(fmt.Sprintf(`git config --local "%s" %s`, key, value))
	return s
}