1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-02-05 13:24:54 +02:00

202 lines
5.4 KiB
Go
Raw Normal View History

2022-08-12 09:19:39 +10:00
package components
2022-08-07 22:09:39 +10:00
import (
"fmt"
"os"
"path/filepath"
2022-08-07 22:09:39 +10:00
"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
2022-12-27 21:47:37 +11:00
// when running the shell outside the gui we can directly panic on failure,
// but inside the gui we need to close the gui before panicking
fail func(string)
}
2022-08-07 22:09:39 +10:00
2022-12-27 21:47:37 +11:00
func NewShell(dir string, fail func(string)) *Shell {
return &Shell{dir: dir, fail: fail}
}
2022-08-07 22:09:39 +10:00
2022-12-27 21:47:37 +11:00
func (self *Shell) RunCommand(cmdStr string) *Shell {
2022-08-07 22:09:39 +10:00
args := str.ToArgv(cmdStr)
cmd := secureexec.Command(args[0], args[1:]...)
cmd.Env = os.Environ()
2022-12-27 21:47:37 +11:00
cmd.Dir = self.dir
2022-08-07 22:09:39 +10:00
output, err := cmd.CombinedOutput()
if err != nil {
2022-12-27 21:47:37 +11:00
self.fail(fmt.Sprintf("error running command: %s\n%s", cmdStr, string(output)))
2022-08-07 22:09:39 +10:00
}
2022-12-27 21:47:37 +11:00
return self
2022-08-07 22:09:39 +10:00
}
2022-12-27 22:52:20 +11:00
func (self *Shell) runCommandWithOutput(cmdStr string) (string, error) {
args := str.ToArgv(cmdStr)
cmd := secureexec.Command(args[0], args[1:]...)
cmd.Env = os.Environ()
cmd.Dir = self.dir
output, err := cmd.CombinedOutput()
return string(output), err
}
2022-12-27 21:47:37 +11:00
func (self *Shell) RunShellCommand(cmdStr string) *Shell {
2022-12-24 16:46:01 +11:00
cmd := secureexec.Command("sh", "-c", cmdStr)
cmd.Env = os.Environ()
2022-12-27 21:47:37 +11:00
cmd.Dir = self.dir
2022-12-24 16:46:01 +11:00
output, err := cmd.CombinedOutput()
if err != nil {
2022-12-27 21:47:37 +11:00
self.fail(fmt.Sprintf("error running shell command: %s\n%s", cmdStr, string(output)))
2022-12-24 16:46:01 +11:00
}
2022-12-27 21:47:37 +11:00
return self
2022-12-24 16:46:01 +11:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) RunShellCommandExpectError(cmdStr string) *Shell {
2022-12-24 16:46:01 +11:00
cmd := secureexec.Command("sh", "-c", cmdStr)
cmd.Env = os.Environ()
2022-12-27 21:47:37 +11:00
cmd.Dir = self.dir
2022-12-24 16:46:01 +11:00
output, err := cmd.CombinedOutput()
if err == nil {
2022-12-27 21:47:37 +11:00
self.fail(fmt.Sprintf("Expected error running shell command: %s\n%s", cmdStr, string(output)))
2022-12-24 16:46:01 +11:00
}
2022-12-27 21:47:37 +11:00
return self
2022-12-24 16:46:01 +11:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) CreateFile(path string, content string) *Shell {
fullPath := filepath.Join(self.dir, path)
2022-09-13 18:11:03 +08:00
err := os.WriteFile(fullPath, []byte(content), 0o644)
2022-08-07 22:09:39 +10:00
if err != nil {
2022-12-27 21:47:37 +11:00
self.fail(fmt.Sprintf("error creating file: %s\n%s", fullPath, err))
2022-08-07 22:09:39 +10:00
}
2022-12-27 21:47:37 +11:00
return self
2022-08-07 22:09:39 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) CreateDir(path string) *Shell {
fullPath := filepath.Join(self.dir, path)
2022-11-11 12:16:38 +11:00
if err := os.MkdirAll(fullPath, 0o755); err != nil {
2022-12-27 21:47:37 +11:00
self.fail(fmt.Sprintf("error creating directory: %s\n%s", fullPath, err))
2022-11-11 12:16:38 +11:00
}
2022-12-27 21:47:37 +11:00
return self
2022-11-11 12:16:38 +11:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) UpdateFile(path string, content string) *Shell {
fullPath := filepath.Join(self.dir, path)
2022-09-13 18:11:03 +08:00
err := os.WriteFile(fullPath, []byte(content), 0o644)
2022-08-22 20:43:19 +10:00
if err != nil {
2022-12-27 21:47:37 +11:00
self.fail(fmt.Sprintf("error updating file: %s\n%s", fullPath, err))
2022-08-22 20:43:19 +10:00
}
2022-12-27 21:47:37 +11:00
return self
2022-08-22 20:43:19 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) NewBranch(name string) *Shell {
return self.RunCommand("git checkout -b " + name)
2022-08-07 22:09:39 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) Checkout(name string) *Shell {
return self.RunCommand("git checkout " + name)
2022-08-22 19:52:05 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) Merge(name string) *Shell {
return self.RunCommand("git merge --commit --no-ff " + name)
}
2022-12-27 21:47:37 +11:00
func (self *Shell) GitAdd(path string) *Shell {
return self.RunCommand(fmt.Sprintf("git add \"%s\"", path))
2022-08-08 21:32:58 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) GitAddAll() *Shell {
return self.RunCommand("git add -A")
2022-08-07 22:09:39 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) Commit(message string) *Shell {
return self.RunCommand(fmt.Sprintf("git commit -m \"%s\"", message))
2022-08-07 22:09:39 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) EmptyCommit(message string) *Shell {
return self.RunCommand(fmt.Sprintf("git commit --allow-empty -m \"%s\"", message))
2022-08-07 22:09:39 +10:00
}
2022-08-08 21:32:58 +10:00
// convenience method for creating a file and adding it
2022-12-27 21:47:37 +11:00
func (self *Shell) CreateFileAndAdd(fileName string, fileContents string) *Shell {
return self.
2022-08-08 21:32:58 +10:00
CreateFile(fileName, fileContents).
GitAdd(fileName)
}
2022-08-22 20:43:19 +10:00
// convenience method for updating a file and adding it
2022-12-27 21:47:37 +11:00
func (self *Shell) UpdateFileAndAdd(fileName string, fileContents string) *Shell {
return self.
2022-08-22 20:43:19 +10:00
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
2022-12-27 21:47:37 +11:00
func (self *Shell) CreateNCommits(n int) *Shell {
2022-08-08 21:32:58 +10:00
for i := 1; i <= n; i++ {
2022-12-27 21:47:37 +11:00
self.CreateFileAndAdd(
2022-08-08 21:32:58 +10:00
fmt.Sprintf("file%02d.txt", i),
fmt.Sprintf("file%02d content", i),
).
Commit(fmt.Sprintf("commit %02d", i))
}
2022-12-27 21:47:37 +11:00
return self
2022-08-08 21:32:58 +10:00
}
2022-12-27 21:47:37 +11:00
func (self *Shell) StashWithMessage(message string) *Shell {
self.RunCommand(fmt.Sprintf(`git stash -m "%s"`, message))
return self
}
2022-12-27 21:47:37 +11:00
func (self *Shell) SetConfig(key string, value string) *Shell {
self.RunCommand(fmt.Sprintf(`git config --local "%s" %s`, key, value))
return self
}
2022-12-28 17:39:45 +11:00
// creates a clone of the repo in a sibling directory and adds the clone
// as a remote, then fetches it.
func (self *Shell) CloneIntoRemote(name string) *Shell {
self.RunCommand(fmt.Sprintf("git clone --bare . ../%s", name))
self.RunCommand(fmt.Sprintf("git remote add %s ../%s", name, name))
self.RunCommand(fmt.Sprintf("git fetch %s", name))
return self
}
// e.g. branch: 'master', upstream: 'origin/master'
func (self *Shell) SetBranchUpstream(branch string, upstream string) *Shell {
self.RunCommand(fmt.Sprintf("git branch --set-upstream-to=%s %s", upstream, branch))
return self
}
func (self *Shell) RemoveRemoteBranch(remoteName string, branch string) *Shell {
self.RunCommand(fmt.Sprintf("git -C ../%s branch -d %s", remoteName, branch))
return self
}
func (self *Shell) HardReset(ref string) *Shell {
self.RunCommand(fmt.Sprintf("git reset --hard %s", ref))
return self
}