diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..6c6a32467
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,10 @@
+- **PR Description**
+
+- **Please check if the PR fulfills these requirements**
+
+* [ ] Cheatsheets are up-to-date (run `go run scripts/cheatsheet/main.go generate`)
+* [ ] Code has been formatted (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting))
+* [ ] Tests have been added/updated (see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md) for the integration test guide)
+* [ ] Text is internationalised (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation))
+* [ ] Docs (specifically `docs/Config.md`) have been updated if necessary
+* [ ] You've read through your own file changes for silly mistakes etc
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b175b02f2..a781b290f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -135,7 +135,7 @@ jobs:
- name: Build integration test injector
run: |
GOOS=linux go build pkg/integration/clients/injector/main.go
- check-cheatsheet:
+ check-codebase:
runs-on: ubuntu-latest
env:
GOFLAGS: -mod=vendor
@@ -159,6 +159,10 @@ jobs:
- name: Check Cheatsheet
run: |
go run scripts/cheatsheet/main.go check
+ - name: Check Vendor Directory
+ # ensure our vendor directory matches up with our go modules
+ run: |
+ go mod vendor && git diff --exit-code || (echo "Unexpected change to vendor directory. Run 'go mod vendor' locally and commit the changes" && exit 1)
lint:
runs-on: ubuntu-latest
env:
@@ -183,12 +187,6 @@ jobs:
uses: golangci/golangci-lint-action@v3.1.0
with:
version: latest
- - name: Format code
- run: |
- if [ $(find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;|wc -l) -gt 0 ]; then
- find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;
- exit 1
- fi
- name: errors
run: golangci-lint run
if: ${{ failure() }}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c6a68feae..4de86725f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -69,9 +69,15 @@ by setting [`formatting.gofumpt`](https://github.com/golang/tools/blob/master/go
}
```
+To run gofumpt from your terminal go:
+
+```
+go install mvdan.cc/gofumpt@latest && gofumpt -l -w .
+```
+
## Internationalisation
-Boy that's a hard word to spell. Anyway, lazygit is translated into several languages within the pkg/i18n package. If you need to render text to the user, you should add a new field to the TranslationSet struct in `pkg/i18n/english.go` and add the actual content within the `EnglishTranslationSet()` method in the same file. Although it is appreciated if you translate the text into other languages, it's not expected of you (google translate will likely do a bad job anyway!).
+Boy that's a hard word to spell. Anyway, lazygit is translated into several languages within the pkg/i18n package. If you need to render text to the user, you should add a new field to the TranslationSet struct in `pkg/i18n/english.go` and add the actual content within the `EnglishTranslationSet()` method in the same file. Then you can access via `gui.Tr.YourNewText` (or `app.Tr.YourNewText`, etc). Although it is appreciated if you translate the text into other languages, it's not expected of you (google translate will likely do a bad job anyway!).
## Debugging
diff --git a/README.md b/README.md
index 6c437bb7c..d8e0785fb 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ A simple terminal UI for git commands, written in Go with the [gocui](https://gi
-




















































+





















































## Elevator Pitch
@@ -42,6 +42,7 @@ If you're a mere mortal like me and you're tired of hearing how powerful git is
- [Arch Linux](#arch-linux)
- [Fedora and RHEL](#fedora-and-rhel)
- [Solus Linux](#solus-linux)
+ - [Ubuntu](#ubuntu)
- [Funtoo Linux](#funtoo-linux)
- [FreeBSD](#freebsd)
- [Conda](#conda)
@@ -146,6 +147,26 @@ sudo dnf install lazygit
sudo eopkg install lazygit
```
+### Ubuntu
+
+```sh
+LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep -Po '"tag_name": "v\K[0-35.]+')
+```
+
+```sh
+curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz"
+```
+
+```sh
+sudo tar xf lazygit.tar.gz -C /usr/local/bin lazygit
+```
+
+Verify the correct installation of lazygit:
+
+```sh
+lazygit --version
+```
+
### Funtoo Linux
Funtoo Linux has an autogenerated lazygit package in [dev-kit](https://github.com/funtoo/dev-kit/tree/1.4-release/dev-vcs/lazygit):
diff --git a/cmd/integration_test/main.go b/cmd/integration_test/main.go
index 492e5e19f..83321fc34 100644
--- a/cmd/integration_test/main.go
+++ b/cmd/integration_test/main.go
@@ -13,7 +13,7 @@ Usage:
See https://github.com/jesseduffield/lazygit/tree/master/pkg/integration/README.md
CLI mode:
- > go run cmd/integration_test/main.go cli ...
+ > go run cmd/integration_test/main.go cli [--slow] ...
If you pass no test names, it runs all tests
Accepted environment variables:
KEY_PRESS_DELAY (e.g. 200): the number of milliseconds to wait between keypresses
@@ -40,7 +40,14 @@ func main() {
case "help":
fmt.Println(usage)
case "cli":
- clients.RunCLI(os.Args[2:])
+ testNames := os.Args[2:]
+ slow := false
+ // get the next arg if it's --slow
+ if len(os.Args) > 2 && (os.Args[2] == "--slow" || os.Args[2] == "-slow") {
+ testNames = os.Args[3:]
+ slow = true
+ }
+ clients.RunCLI(testNames, slow)
case "tui":
clients.RunTUI()
default:
diff --git a/go.mod b/go.mod
index eb31e4713..56210e80b 100644
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4
- github.com/jesseduffield/gocui v0.3.1-0.20220813101052-3a3ab26faa15
+ github.com/jesseduffield/gocui v0.3.1-0.20220815095708-156fda5e0419
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
github.com/jesseduffield/yaml v2.1.0+incompatible
diff --git a/go.sum b/go.sum
index 31b69c743..e2084d6a9 100644
--- a/go.sum
+++ b/go.sum
@@ -72,8 +72,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4 h1:GOQrmaE8i+KEdB8NzAegKYd4tPn/inM0I1uo0NXFerg=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
-github.com/jesseduffield/gocui v0.3.1-0.20220813101052-3a3ab26faa15 h1:DTVj8aCmINqLj5AXBEGmpWwfN1HJ3EWtUiYfcyIaSxs=
-github.com/jesseduffield/gocui v0.3.1-0.20220813101052-3a3ab26faa15/go.mod h1:znJuCDnF2Ph40YZSlBwdX/4GEofnIoWLGdT4mK5zRAU=
+github.com/jesseduffield/gocui v0.3.1-0.20220815095708-156fda5e0419 h1:p3Ix7RUcy4X16Lk5jTSfTxecJT7ryqYHclfRbo/Svzs=
+github.com/jesseduffield/gocui v0.3.1-0.20220815095708-156fda5e0419/go.mod h1:znJuCDnF2Ph40YZSlBwdX/4GEofnIoWLGdT4mK5zRAU=
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0=
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo=
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e h1:uw/oo+kg7t/oeMs6sqlAwr85ND/9cpO3up3VxphxY0U=
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 88af18486..3a4943762 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -16,6 +16,7 @@ import (
"github.com/jesseduffield/generics/slices"
appTypes "github.com/jesseduffield/lazygit/pkg/app/types"
"github.com/jesseduffield/lazygit/pkg/commands"
+ "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/common"
@@ -200,6 +201,18 @@ func isDirectoryAGitRepository(dir string) (bool, error) {
return info != nil, err
}
+func openRecentRepo(app *App) bool {
+ for _, repoDir := range app.Config.GetAppState().RecentRepos {
+ if isRepo, _ := isDirectoryAGitRepository(repoDir); isRepo {
+ if err := os.Chdir(repoDir); err == nil {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
func (app *App) setupRepo() (bool, error) {
if err := app.validateGitVersion(); err != nil {
return false, err
@@ -216,6 +229,7 @@ func (app *App) setupRepo() (bool, error) {
if err != nil {
return false, err
}
+
if isRepo, err := isDirectoryAGitRepository(cwd); isRepo {
return false, err
}
@@ -268,6 +282,28 @@ func (app *App) setupRepo() (bool, error) {
os.Exit(1)
}
+ // Run this afterward so that the previous repo creation steps can run without this interfering
+ if isBare, err := git_commands.IsBareRepo(app.OSCommand); isBare {
+ if err != nil {
+ return false, err
+ }
+
+ fmt.Print(app.Tr.BareRepo)
+
+ response, _ := bufio.NewReader(os.Stdin).ReadString('\n')
+
+ if shouldOpenRecent := strings.Trim(response, " \r\n") == "y"; !shouldOpenRecent {
+ os.Exit(0)
+ }
+
+ if didOpenRepo := openRecentRepo(app); didOpenRepo {
+ return true, nil
+ }
+
+ fmt.Println(app.Tr.NoRecentRepositories)
+ os.Exit(1)
+ }
+
return false, nil
}
diff --git a/pkg/commands/git_commands/status.go b/pkg/commands/git_commands/status.go
index 50b1fab57..d660dd8b0 100644
--- a/pkg/commands/git_commands/status.go
+++ b/pkg/commands/git_commands/status.go
@@ -2,8 +2,10 @@ package git_commands
import (
"path/filepath"
+ "strconv"
+ "strings"
- gogit "github.com/jesseduffield/go-git/v5"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
)
@@ -49,13 +51,21 @@ func (self *StatusCommands) WorkingTreeState() enums.RebaseMode {
return enums.REBASE_MODE_NONE
}
+func (self *StatusCommands) IsBareRepo() (bool, error) {
+ return IsBareRepo(self.os)
+}
+
+func IsBareRepo(osCommand *oscommands.OSCommand) (bool, error) {
+ res, err := osCommand.Cmd.New("git rev-parse --is-bare-repository").DontLog().RunWithOutput()
+ if err != nil {
+ return false, err
+ }
+
+ // The command returns output with a newline, so we need to strip
+ return strconv.ParseBool(strings.TrimSpace(res))
+}
+
// IsInMergeState states whether we are still mid-merge
func (self *StatusCommands) IsInMergeState() (bool, error) {
return self.os.FileExists(filepath.Join(self.dotGitDir, "MERGE_HEAD"))
}
-
-func (self *StatusCommands) IsBareRepo() bool {
- // note: could use `git rev-parse --is-bare-repository` if we wanna drop go-git
- _, err := self.repo.Worktree()
- return err == gogit.ErrIsBareRepository
-}
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go
index f6f9621d1..13a4bf3ad 100644
--- a/pkg/config/user_config.go
+++ b/pkg/config/user_config.go
@@ -315,7 +315,9 @@ type CustomCommand struct {
}
type CustomCommandPrompt struct {
- Type string `yaml:"type"` // one of 'input', 'menu', or 'confirm'
+ // one of 'input', 'menu', 'confirm', or 'menuFromCommand'
+ Type string `yaml:"type"`
+
Title string `yaml:"title"`
// this only apply to input prompts
diff --git a/pkg/gui/gui_driver.go b/pkg/gui/gui_driver.go
index 860c6c9b8..7df2b95ba 100644
--- a/pkg/gui/gui_driver.go
+++ b/pkg/gui/gui_driver.go
@@ -71,3 +71,11 @@ func (self *GuiDriver) LogUI(message string) {
func (self *GuiDriver) CheckedOutRef() *models.Branch {
return self.gui.helpers.Refs.GetCheckedOutRef()
}
+
+func (self *GuiDriver) MainView() *gocui.View {
+ return self.gui.mainView()
+}
+
+func (self *GuiDriver) SecondaryView() *gocui.View {
+ return self.gui.secondaryView()
+}
diff --git a/pkg/gui/recent_repos_panel.go b/pkg/gui/recent_repos_panel.go
index 705461726..df7656841 100644
--- a/pkg/gui/recent_repos_panel.go
+++ b/pkg/gui/recent_repos_panel.go
@@ -159,7 +159,12 @@ func (gui *Gui) dispatchSwitchToRepo(path string, reuse bool) error {
// updateRecentRepoList registers the fact that we opened lazygit in this repo,
// so that we can open the same repo via the 'recent repos' menu
func (gui *Gui) updateRecentRepoList() error {
- if gui.git.Status.IsBareRepo() {
+ isBareRepo, err := gui.git.Status.IsBareRepo()
+ if err != nil {
+ return err
+ }
+
+ if isBareRepo {
// we could totally do this but it would require storing both the git-dir and the
// worktree in our recent repos list, which is a change that would need to be
// backwards compatible
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index bd9804634..142330a41 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -259,6 +259,7 @@ type TranslationSet struct {
DiscardFileChangesPrompt string
DisabledForGPG string
CreateRepo string
+ BareRepo string
InitialBranch string
NoRecentRepositories string
IncorrectNotARepository string
@@ -901,6 +902,7 @@ func EnglishTranslationSet() TranslationSet {
DiscardFileChangesPrompt: "Are you sure you want to discard this commit's changes to this file? If this file was created in this commit, it will be deleted",
DisabledForGPG: "Feature not available for users using GPG",
CreateRepo: "Not in a git repository. Create a new git repository? (y/n): ",
+ BareRepo: "You've attempted to open Lazygit in a bare repo but Lazygit does not yet support bare repos. Open most recent repo? (y/n) ",
InitialBranch: "Branch name? (leave empty for git's default): ",
NoRecentRepositories: "Must open lazygit in a git repository. No valid recent repositories. Exiting.",
IncorrectNotARepository: "The value of 'notARepository' is incorrect. It should be one of 'prompt', 'create', 'skip', or 'quit'.",
diff --git a/pkg/integration/README.md b/pkg/integration/README.md
index ba2365403..916149cea 100644
--- a/pkg/integration/README.md
+++ b/pkg/integration/README.md
@@ -1,6 +1,18 @@
# Integration Tests
-The pkg/integration pacakge is for integration testing: that is, actually running a real lazygit session and having a robot pretend to be a human user and then making assertions that everything works as expected.
+The pkg/integration package is for integration testing: that is, actually running a real lazygit session and having a robot pretend to be a human user and then making assertions that everything works as expected.
+
+TL;DR: integration tests live in pkg/integration/tests. Run integration tests with:
+
+```sh
+go run cmd/integration_test/main.go tui
+```
+
+or
+
+```sh
+go run cmd/integration_test/main.go cli [--slow] [testname or testpath...]
+```
## Writing tests
@@ -37,7 +49,7 @@ If you find yourself doing something frequently in a test, consider making it a
There are three ways to invoke a test:
-1. go run cmd/integration_test/main.go cli [...]
+1. go run cmd/integration_test/main.go cli [--slow] [testname or testpath...]
2. go run cmd/integration_test/main.go tui
3. go test pkg/integration/clients/go_test.go
@@ -47,7 +59,7 @@ The third, the go-test command, intended only for use in CI, to be run along wit
The name of a test is based on its path, so the name of the test at `pkg/integration/tests/commit/new_branch.go` is commit/new_branch. So to run it with our test runner you would run `go run cmd/integration_test/main.go cli commit/new_branch`.
-You can pass the KEY_PRESS_DELAY env var to the test runner in order to set a delay in milliseconds between keypresses, which helps for watching a test at a realistic speed to understand what it's doing. Or in the tui you can press 't' to run the test with a pre-set delay.
+You can pass the KEY_PRESS_DELAY env var to the test runner in order to set a delay in milliseconds between keypresses, which helps for watching a test at a realistic speed to understand what it's doing. Or you can pass the '--slow' flag which sets a pre-set 'slow' key delay. In the tui you can press 't' to run the test in slow mode.
### Snapshots
diff --git a/pkg/integration/clients/cli.go b/pkg/integration/clients/cli.go
index 76f0c9549..eedb82984 100644
--- a/pkg/integration/clients/cli.go
+++ b/pkg/integration/clients/cli.go
@@ -4,8 +4,11 @@ import (
"log"
"os"
"os/exec"
+ "regexp"
"strconv"
+ "strings"
+ "github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/integration/components"
"github.com/jesseduffield/lazygit/pkg/integration/tests"
)
@@ -20,14 +23,19 @@ import (
// If invoked directly, you can specify tests to run by passing their names as positional arguments
-func RunCLI(testNames []string) {
+func RunCLI(testNames []string, slow bool) {
+ keyPressDelay := tryConvert(os.Getenv("KEY_PRESS_DELAY"), 0)
+ if slow {
+ keyPressDelay = SLOW_KEY_PRESS_DELAY
+ }
+
err := components.RunTests(
getTestsToRun(testNames),
log.Printf,
runCmdInTerminal,
runAndPrintError,
getModeFromEnv(),
- tryConvert(os.Getenv("KEY_PRESS_DELAY"), 0),
+ keyPressDelay,
)
if err != nil {
log.Print(err.Error())
@@ -36,21 +44,30 @@ func RunCLI(testNames []string) {
func runAndPrintError(test *components.IntegrationTest, f func() error) {
if err := f(); err != nil {
- log.Print(err.Error())
+ log.Fatalf(err.Error())
}
}
func getTestsToRun(testNames []string) []*components.IntegrationTest {
+ allIntegrationTests := tests.GetTests()
var testsToRun []*components.IntegrationTest
if len(testNames) == 0 {
- return tests.Tests
+ return allIntegrationTests
}
+ testNames = slices.Map(testNames, func(name string) string {
+ // allowing full test paths to be passed for convenience
+ return strings.TrimSuffix(
+ regexp.MustCompile(`.*pkg/integration/tests/`).ReplaceAllString(name, ""),
+ ".go",
+ )
+ })
+
outer:
for _, testName := range testNames {
// check if our given test name actually exists
- for _, test := range tests.Tests {
+ for _, test := range allIntegrationTests {
if test.Name() == testName {
testsToRun = append(testsToRun, test)
continue outer
diff --git a/pkg/integration/clients/go_test.go b/pkg/integration/clients/go_test.go
index d52cd409a..9fceecd40 100644
--- a/pkg/integration/clients/go_test.go
+++ b/pkg/integration/clients/go_test.go
@@ -29,7 +29,7 @@ func TestIntegration(t *testing.T) {
testNumber := 0
err := components.RunTests(
- tests.Tests,
+ tests.GetTests(),
t.Logf,
runCmdHeadless,
func(test *components.IntegrationTest, f func() error) {
diff --git a/pkg/integration/clients/injector/main.go b/pkg/integration/clients/injector/main.go
index 263dba5da..37c76fe3e 100644
--- a/pkg/integration/clients/injector/main.go
+++ b/pkg/integration/clients/injector/main.go
@@ -52,7 +52,8 @@ func getIntegrationTest() integrationTypes.IntegrationTest {
))
}
- for _, candidateTest := range tests.Tests {
+ allTests := tests.GetTests()
+ for _, candidateTest := range allTests {
if candidateTest.Name() == integrationTestName {
return candidateTest
}
diff --git a/pkg/integration/clients/tui.go b/pkg/integration/clients/tui.go
index 707e482ca..9348cd1f3 100644
--- a/pkg/integration/clients/tui.go
+++ b/pkg/integration/clients/tui.go
@@ -19,6 +19,8 @@ import (
// This program lets you run integration tests from a TUI. See pkg/integration/README.md for more info.
+var SLOW_KEY_PRESS_DELAY = 300
+
func RunTUI() {
rootDir := utils.GetLazygitRootDirectory()
testDir := filepath.Join(rootDir, "test", "integration")
@@ -106,7 +108,7 @@ func RunTUI() {
return nil
}
- suspendAndRunTest(currentTest, components.ASK_TO_UPDATE_SNAPSHOT, 200)
+ suspendAndRunTest(currentTest, components.ASK_TO_UPDATE_SNAPSHOT, SLOW_KEY_PRESS_DELAY)
return nil
}); err != nil {
@@ -168,7 +170,7 @@ func RunTUI() {
return err
}
- app.filteredTests = tests.Tests
+ app.filteredTests = app.allTests
app.renderTests()
app.editorView.TextArea.Clear()
app.editorView.Clear()
@@ -204,6 +206,7 @@ func RunTUI() {
}
type app struct {
+ allTests []*components.IntegrationTest
filteredTests []*components.IntegrationTest
itemIdx int
testDir string
@@ -214,7 +217,7 @@ type app struct {
}
func newApp(testDir string) *app {
- return &app{testDir: testDir}
+ return &app{testDir: testDir, allTests: tests.GetTests()}
}
func (self *app) getCurrentTest() *components.IntegrationTest {
@@ -226,7 +229,7 @@ func (self *app) getCurrentTest() *components.IntegrationTest {
}
func (self *app) loadTests() {
- self.filteredTests = tests.Tests
+ self.filteredTests = self.allTests
self.adjustCursor()
}
@@ -237,9 +240,9 @@ func (self *app) adjustCursor() {
func (self *app) filterWithString(needle string) {
if needle == "" {
- self.filteredTests = tests.Tests
+ self.filteredTests = self.allTests
} else {
- self.filteredTests = slices.Filter(tests.Tests, func(test *components.IntegrationTest) bool {
+ self.filteredTests = slices.Filter(self.allTests, func(test *components.IntegrationTest) bool {
return strings.Contains(test.Name(), needle)
})
}
diff --git a/pkg/integration/components/assert.go b/pkg/integration/components/assert.go
index 584ad438b..ae363eb8d 100644
--- a/pkg/integration/components/assert.go
+++ b/pkg/integration/components/assert.go
@@ -19,6 +19,43 @@ func NewAssert(gui integrationTypes.GuiDriver) *Assert {
return &Assert{gui: gui}
}
+// for making assertions on string values
+type matcher struct {
+ testFn func(string) (bool, string)
+ prefix string
+}
+
+func (self *matcher) test(value string) (bool, string) {
+ ok, message := self.testFn(value)
+ if ok {
+ return true, ""
+ }
+
+ if self.prefix != "" {
+ return false, self.prefix + " " + message
+ }
+
+ return false, message
+}
+
+func (self *matcher) context(prefix string) *matcher {
+ self.prefix = prefix
+
+ return self
+}
+
+func Contains(target string) *matcher {
+ return &matcher{testFn: func(value string) (bool, string) {
+ return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to contain '%s'", value, target)
+ }}
+}
+
+func Equals(target string) *matcher {
+ return &matcher{testFn: func(value string) (bool, string) {
+ return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target)
+ }}
+}
+
func (self *Assert) WorkingTreeFileCount(expectedCount int) {
self.assertWithRetries(func() (bool, string) {
actualCount := len(self.gui.Model().Files)
@@ -41,22 +78,16 @@ func (self *Assert) CommitCount(expectedCount int) {
})
}
-func (self *Assert) HeadCommitMessage(expectedMessage string) {
+func (self *Assert) MatchHeadCommitMessage(matcher *matcher) {
self.assertWithRetries(func() (bool, string) {
- if len(self.gui.Model().Commits) == 0 {
- return false, "Expected at least one commit to be present"
- }
-
- headCommit := self.gui.Model().Commits[0]
- if headCommit.Name != expectedMessage {
- return false, fmt.Sprintf(
- "Expected commit message to be '%s', but got '%s'",
- expectedMessage, headCommit.Name,
- )
- }
-
- return true, ""
+ return len(self.gui.Model().Commits) > 0, "Expected at least one commit to be present"
})
+
+ self.matchString(matcher, "Unexpected commit message.",
+ func() string {
+ return self.gui.Model().Commits[0].Name
+ },
+ )
}
func (self *Assert) CurrentViewName(expectedViewName string) {
@@ -81,10 +112,70 @@ func (self *Assert) InListContext() {
})
}
-func (self *Assert) SelectedLineContains(text string) {
+func (self *Assert) MatchSelectedLine(matcher *matcher) {
+ self.matchString(matcher, "Unexpected selected line.",
+ func() string {
+ return self.gui.CurrentContext().GetView().SelectedLine()
+ },
+ )
+}
+
+func (self *Assert) InPrompt() {
self.assertWithRetries(func() (bool, string) {
- line := self.gui.CurrentContext().GetView().SelectedLine()
- return strings.Contains(line, text), fmt.Sprintf("Expected selected line to contain '%s', but got '%s'", text, line)
+ currentView := self.gui.CurrentContext().GetView()
+ return currentView.Name() == "confirmation" && currentView.Editable, "Expected prompt popup to be focused"
+ })
+}
+
+func (self *Assert) InConfirm() {
+ self.assertWithRetries(func() (bool, string) {
+ currentView := self.gui.CurrentContext().GetView()
+ return currentView.Name() == "confirmation" && !currentView.Editable, "Expected confirmation popup to be focused"
+ })
+}
+
+func (self *Assert) InAlert() {
+ // basically the same thing as a confirmation popup with the current implementation
+ self.assertWithRetries(func() (bool, string) {
+ currentView := self.gui.CurrentContext().GetView()
+ return currentView.Name() == "confirmation" && !currentView.Editable, "Expected alert popup to be focused"
+ })
+}
+
+func (self *Assert) InMenu() {
+ self.assertWithRetries(func() (bool, string) {
+ return self.gui.CurrentContext().GetView().Name() == "menu", "Expected popup menu to be focused"
+ })
+}
+
+func (self *Assert) MatchCurrentViewTitle(matcher *matcher) {
+ self.matchString(matcher, "Unexpected current view title.",
+ func() string {
+ return self.gui.CurrentContext().GetView().Title
+ },
+ )
+}
+
+func (self *Assert) MatchMainViewContent(matcher *matcher) {
+ self.matchString(matcher, "Unexpected main view content.",
+ func() string {
+ return self.gui.MainView().Buffer()
+ },
+ )
+}
+
+func (self *Assert) MatchSecondaryViewContent(matcher *matcher) {
+ self.matchString(matcher, "Unexpected secondary view title.",
+ func() string {
+ return self.gui.SecondaryView().Buffer()
+ },
+ )
+}
+
+func (self *Assert) matchString(matcher *matcher, context string, getValue func() string) {
+ self.assertWithRetries(func() (bool, string) {
+ value := getValue()
+ return matcher.context(context).test(value)
})
}
diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go
index d44b11830..63e902613 100644
--- a/pkg/integration/components/input.go
+++ b/pkg/integration/components/input.go
@@ -77,7 +77,7 @@ func (self *Input) Cancel() {
}
// i.e. pressing space
-func (self *Input) Select() {
+func (self *Input) PrimaryAction() {
self.pressKey(self.keys.Universal.Select)
}
@@ -93,7 +93,7 @@ func (self *Input) PreviousItem() {
func (self *Input) ContinueMerge() {
self.PressKeys(self.keys.Universal.CreateRebaseOptionsMenu)
- self.assert.SelectedLineContains("continue")
+ self.assert.MatchSelectedLine(Contains("continue"))
self.Confirm()
}
diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go
index 5a5022c53..d2b31aed6 100644
--- a/pkg/integration/components/runner.go
+++ b/pkg/integration/components/runner.go
@@ -136,9 +136,10 @@ func createFixture(test *IntegrationTest, paths Paths) error {
}
shell := NewShell()
- shell.RunCommand("git init")
+ shell.RunCommand("git init -b master")
shell.RunCommand(`git config user.email "CI@example.com"`)
shell.RunCommand(`git config user.name "CI"`)
+ shell.RunCommand(`git config commit.gpgSign false`)
test.SetupRepo(shell)
diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go
index a5973c07a..3cc6a7641 100644
--- a/pkg/integration/components/test.go
+++ b/pkg/integration/components/test.go
@@ -53,7 +53,7 @@ func NewIntegrationTest(args NewIntegrationTestArgs) *IntegrationTest {
if args.Description != unitTestDescription {
// this panics if we're in a unit test for our integration tests,
// so we're using "test test" as a sentinel value
- name = testNameFromFilePath()
+ name = testNameFromCurrentFilePath()
}
return &IntegrationTest{
@@ -106,8 +106,12 @@ func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) {
}
}
-func testNameFromFilePath() string {
+func testNameFromCurrentFilePath() string {
path := utils.FilePath(3)
+ return TestNameFromFilePath(path)
+}
+
+func TestNameFromFilePath(path string) string {
name := strings.Split(path, "integration/tests/")[1]
return name[:len(name)-len(".go")]
diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go
index de8dac8e4..e180bfccb 100644
--- a/pkg/integration/components/test_test.go
+++ b/pkg/integration/components/test_test.go
@@ -3,6 +3,7 @@ package components
import (
"testing"
+ "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/types"
@@ -47,6 +48,14 @@ func (self *fakeGuiDriver) CheckedOutRef() *models.Branch {
return nil
}
+func (self *fakeGuiDriver) MainView() *gocui.View {
+ return nil
+}
+
+func (self *fakeGuiDriver) SecondaryView() *gocui.View {
+ return nil
+}
+
func TestAssertionFailure(t *testing.T) {
test := NewIntegrationTest(NewIntegrationTestArgs{
Description: unitTestDescription,
diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go
index 12a68925d..dbef083ae 100644
--- a/pkg/integration/tests/commit/commit.go
+++ b/pkg/integration/tests/commit/commit.go
@@ -2,24 +2,24 @@ package commit
import (
"github.com/jesseduffield/lazygit/pkg/config"
- "github.com/jesseduffield/lazygit/pkg/integration/components"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
)
-var Commit = components.NewIntegrationTest(components.NewIntegrationTestArgs{
+var Commit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Staging a couple files and committing",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
- SetupRepo: func(shell *components.Shell) {
+ SetupRepo: func(shell *Shell) {
shell.CreateFile("myfile", "myfile content")
shell.CreateFile("myfile2", "myfile2 content")
},
- Run: func(shell *components.Shell, input *components.Input, assert *components.Assert, keys config.KeybindingConfig) {
+ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
assert.CommitCount(0)
- input.Select()
+ input.PrimaryAction()
input.NextItem()
- input.Select()
+ input.PrimaryAction()
input.PressKeys(keys.Files.CommitChanges)
commitMessage := "my commit message"
@@ -27,6 +27,6 @@ var Commit = components.NewIntegrationTest(components.NewIntegrationTestArgs{
input.Confirm()
assert.CommitCount(1)
- assert.HeadCommitMessage(commitMessage)
+ assert.MatchHeadCommitMessage(Equals(commitMessage))
},
})
diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go
index ad96938f5..ea784791d 100644
--- a/pkg/integration/tests/commit/new_branch.go
+++ b/pkg/integration/tests/commit/new_branch.go
@@ -2,21 +2,21 @@ package commit
import (
"github.com/jesseduffield/lazygit/pkg/config"
- "github.com/jesseduffield/lazygit/pkg/integration/components"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
)
-var NewBranch = components.NewIntegrationTest(components.NewIntegrationTestArgs{
+var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Creating a new branch from a commit",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
- SetupRepo: func(shell *components.Shell) {
+ SetupRepo: func(shell *Shell) {
shell.
EmptyCommit("commit 1").
EmptyCommit("commit 2").
EmptyCommit("commit 3")
},
- Run: func(shell *components.Shell, input *components.Input, assert *components.Assert, keys config.KeybindingConfig) {
+ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
assert.CommitCount(3)
input.SwitchToCommitsWindow()
@@ -32,7 +32,7 @@ var NewBranch = components.NewIntegrationTest(components.NewIntegrationTestArgs{
input.Confirm()
assert.CommitCount(2)
- assert.HeadCommitMessage("commit 2")
+ assert.MatchHeadCommitMessage(Contains("commit 2"))
assert.CurrentBranchName(branchName)
},
})
diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go
new file mode 100644
index 000000000..e92e3eed3
--- /dev/null
+++ b/pkg/integration/tests/custom_commands/basic.go
@@ -0,0 +1,36 @@
+package custom_commands
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var Basic = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Using a custom command to create a new file",
+ ExtraCmdArgs: "",
+ Skip: false,
+ SetupRepo: func(shell *Shell) {
+ shell.EmptyCommit("blah")
+ },
+ SetupConfig: func(cfg *config.AppConfig) {
+ cfg.UserConfig.CustomCommands = []config.CustomCommand{
+ {
+ Key: "a",
+ Context: "files",
+ Command: "touch myfile",
+ },
+ }
+ },
+ Run: func(
+ shell *Shell,
+ input *Input,
+ assert *Assert,
+ keys config.KeybindingConfig,
+ ) {
+ assert.WorkingTreeFileCount(0)
+
+ input.PressKeys("a")
+ assert.WorkingTreeFileCount(1)
+ assert.MatchSelectedLine(Contains("myfile"))
+ },
+})
diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go
new file mode 100644
index 000000000..f45d820d6
--- /dev/null
+++ b/pkg/integration/tests/custom_commands/menu_from_command.go
@@ -0,0 +1,74 @@
+package custom_commands
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+// NOTE: we're getting a weird offset in the popup prompt for some reason. Not sure what's behind that.
+
+var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Using menuFromCommand prompt type",
+ ExtraCmdArgs: "",
+ Skip: false,
+ SetupRepo: func(shell *Shell) {
+ shell.
+ EmptyCommit("foo").
+ EmptyCommit("bar").
+ EmptyCommit("baz").
+ NewBranch("feature/foo")
+ },
+ SetupConfig: func(cfg *config.AppConfig) {
+ cfg.UserConfig.CustomCommands = []config.CustomCommand{
+ {
+ Key: "a",
+ Context: "localBranches",
+ Command: `echo "{{index .PromptResponses 0}} {{index .PromptResponses 1}} {{ .SelectedLocalBranch.Name }}" > output.txt`,
+ Prompts: []config.CustomCommandPrompt{
+ {
+ Type: "menuFromCommand",
+ Title: "Choose commit message",
+ Command: `git log --oneline --pretty=%B`,
+ Filter: `(?P.*)`,
+ ValueFormat: `{{ .commit_message }}`,
+ LabelFormat: `{{ .commit_message | yellow }}`,
+ },
+ {
+ Type: "input",
+ Title: "Description",
+ InitialValue: `{{ if .SelectedLocalBranch.Name }}Branch: #{{ .SelectedLocalBranch.Name }}{{end}}`,
+ },
+ },
+ },
+ }
+ },
+ Run: func(
+ shell *Shell,
+ input *Input,
+ assert *Assert,
+ keys config.KeybindingConfig,
+ ) {
+ assert.WorkingTreeFileCount(0)
+ input.SwitchToBranchesWindow()
+
+ input.PressKeys("a")
+
+ assert.InMenu()
+ assert.MatchCurrentViewTitle(Equals("Choose commit message"))
+ assert.MatchSelectedLine(Equals("baz"))
+ input.NextItem()
+ assert.MatchSelectedLine(Equals("bar"))
+ input.Confirm()
+
+ assert.InPrompt()
+ assert.MatchCurrentViewTitle(Equals("Description"))
+ input.Type(" my branch")
+ input.Confirm()
+
+ input.SwitchToFilesWindow()
+
+ assert.WorkingTreeFileCount(1)
+ assert.MatchSelectedLine(Contains("output.txt"))
+ assert.MatchMainViewContent(Contains("bar Branch: #feature/foo my branch feature/foo"))
+ },
+})
diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go
new file mode 100644
index 000000000..e66b6a091
--- /dev/null
+++ b/pkg/integration/tests/custom_commands/multiple_prompts.go
@@ -0,0 +1,86 @@
+package custom_commands
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Using a custom command with multiple prompts",
+ ExtraCmdArgs: "",
+ Skip: false,
+ SetupRepo: func(shell *Shell) {
+ shell.EmptyCommit("blah")
+ },
+ SetupConfig: func(cfg *config.AppConfig) {
+ cfg.UserConfig.CustomCommands = []config.CustomCommand{
+ {
+ Key: "a",
+ Context: "files",
+ Command: `echo "{{index .PromptResponses 1}}" > {{index .PromptResponses 0}}`,
+ Prompts: []config.CustomCommandPrompt{
+ {
+ Type: "input",
+ Title: "Enter a file name",
+ },
+ {
+ Type: "menu",
+ Title: "Choose file content",
+ Options: []config.CustomCommandMenuOption{
+ {
+ Name: "foo",
+ Description: "Foo",
+ Value: "FOO",
+ },
+ {
+ Name: "bar",
+ Description: "Bar",
+ Value: "BAR",
+ },
+ {
+ Name: "baz",
+ Description: "Baz",
+ Value: "BAZ",
+ },
+ },
+ },
+ {
+ Type: "confirm",
+ Title: "Are you sure?",
+ Body: "Are you REALLY sure you want to make this file? Up to you buddy.",
+ },
+ },
+ },
+ }
+ },
+ Run: func(
+ shell *Shell,
+ input *Input,
+ assert *Assert,
+ keys config.KeybindingConfig,
+ ) {
+ assert.WorkingTreeFileCount(0)
+
+ input.PressKeys("a")
+
+ assert.InPrompt()
+ assert.MatchCurrentViewTitle(Equals("Enter a file name"))
+ input.Type("myfile")
+ input.Confirm()
+
+ assert.InMenu()
+ assert.MatchCurrentViewTitle(Equals("Choose file content"))
+ assert.MatchSelectedLine(Contains("foo"))
+ input.NextItem()
+ assert.MatchSelectedLine(Contains("bar"))
+ input.Confirm()
+
+ assert.InConfirm()
+ assert.MatchCurrentViewTitle(Equals("Are you sure?"))
+ input.Confirm()
+
+ assert.WorkingTreeFileCount(1)
+ assert.MatchSelectedLine(Contains("myfile"))
+ assert.MatchMainViewContent(Contains("BAR"))
+ },
+})
diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go
index 3c785a727..014a4b8c9 100644
--- a/pkg/integration/tests/interactive_rebase/one.go
+++ b/pkg/integration/tests/interactive_rebase/one.go
@@ -2,37 +2,37 @@ package interactive_rebase
import (
"github.com/jesseduffield/lazygit/pkg/config"
- "github.com/jesseduffield/lazygit/pkg/integration/components"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
)
-var One = components.NewIntegrationTest(components.NewIntegrationTestArgs{
+var One = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Begins an interactive rebase, then fixups, drops, and squashes some commits",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
- SetupRepo: func(shell *components.Shell) {
+ SetupRepo: func(shell *Shell) {
shell.
CreateNCommits(5) // these will appears at commit 05, 04, 04, down to 01
},
- Run: func(shell *components.Shell, input *components.Input, assert *components.Assert, keys config.KeybindingConfig) {
+ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
input.SwitchToCommitsWindow()
assert.CurrentViewName("commits")
input.NavigateToListItemContainingText("commit 02")
input.PressKeys(keys.Universal.Edit)
- assert.SelectedLineContains("YOU ARE HERE")
+ assert.MatchSelectedLine(Contains("YOU ARE HERE"))
input.PreviousItem()
input.PressKeys(keys.Commits.MarkCommitAsFixup)
- assert.SelectedLineContains("fixup")
+ assert.MatchSelectedLine(Contains("fixup"))
input.PreviousItem()
input.PressKeys(keys.Universal.Remove)
- assert.SelectedLineContains("drop")
+ assert.MatchSelectedLine(Contains("drop"))
input.PreviousItem()
input.PressKeys(keys.Commits.SquashDown)
- assert.SelectedLineContains("squash")
+ assert.MatchSelectedLine(Contains("squash"))
input.ContinueRebase()
diff --git a/pkg/integration/tests/tests.go b/pkg/integration/tests/tests.go
index e9794169a..587ac8e30 100644
--- a/pkg/integration/tests/tests.go
+++ b/pkg/integration/tests/tests.go
@@ -1,18 +1,74 @@
package tests
import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/jesseduffield/generics/set"
+ "github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/integration/components"
"github.com/jesseduffield/lazygit/pkg/integration/tests/branch"
"github.com/jesseduffield/lazygit/pkg/integration/tests/commit"
+ "github.com/jesseduffield/lazygit/pkg/integration/tests/custom_commands"
"github.com/jesseduffield/lazygit/pkg/integration/tests/interactive_rebase"
+ "github.com/jesseduffield/lazygit/pkg/utils"
)
// Here is where we lists the actual tests that will run. When you create a new test,
// be sure to add it to this list.
-var Tests = []*components.IntegrationTest{
+var tests = []*components.IntegrationTest{
commit.Commit,
commit.NewBranch,
branch.Suggestions,
interactive_rebase.One,
+ custom_commands.Basic,
+ custom_commands.MultiplePrompts,
+ custom_commands.MenuFromCommand,
+}
+
+func GetTests() []*components.IntegrationTest {
+ // first we ensure that each test in this directory has actually been added to the above list.
+ testCount := 0
+
+ testNamesSet := set.NewFromSlice(slices.Map(
+ tests,
+ func(test *components.IntegrationTest) string {
+ return test.Name()
+ },
+ ))
+
+ missingTestNames := []string{}
+
+ if err := filepath.Walk(filepath.Join(utils.GetLazygitRootDirectory(), "pkg/integration/tests"), func(path string, info os.FileInfo, err error) error {
+ if !info.IsDir() && strings.HasSuffix(path, ".go") {
+ // ignoring this current file
+ if filepath.Base(path) == "tests.go" {
+ return nil
+ }
+
+ nameFromPath := components.TestNameFromFilePath(path)
+ if !testNamesSet.Includes(nameFromPath) {
+ missingTestNames = append(missingTestNames, nameFromPath)
+ }
+ testCount++
+ }
+ return nil
+ }); err != nil {
+ panic(fmt.Sprintf("failed to walk tests: %v", err))
+ }
+
+ if len(missingTestNames) > 0 {
+ panic(fmt.Sprintf("The following tests are missing from the list of tests: %s. You need to add them to `pkg/integration/tests/tests.go`.", strings.Join(missingTestNames, ", ")))
+ }
+
+ if testCount > len(tests) {
+ panic("you have not added all of the tests to the tests list in `pkg/integration/tests/tests.go`")
+ } else if testCount < len(tests) {
+ panic("There are more tests in `pkg/integration/tests/tests.go` than there are test files in the tests directory. Ensure that you only have one test per file and you haven't included the same test twice in the tests list.")
+ }
+
+ return tests
}
diff --git a/pkg/integration/types/types.go b/pkg/integration/types/types.go
index 543212d59..b5ee2ca68 100644
--- a/pkg/integration/types/types.go
+++ b/pkg/integration/types/types.go
@@ -1,6 +1,7 @@
package types
import (
+ "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/types"
@@ -28,4 +29,9 @@ type GuiDriver interface {
// logs in the actual UI (in the commands panel)
LogUI(message string)
CheckedOutRef() *models.Branch
+ // the view that appears to the right of the side panel
+ MainView() *gocui.View
+ // the other view that sometimes appears to the right of the side panel
+ // e.g. when we're showing both staged and unstaged changes
+ SecondaryView() *gocui.View
}
diff --git a/test/integration/customCommands/config/config.yml b/test/integration/customCommands/config/config.yml
deleted file mode 100644
index 33c1d684e..000000000
--- a/test/integration/customCommands/config/config.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-disableStartupPopups: true
-customCommands:
- - key : 'N'
- description: 'Add file'
- command: "echo {{index .PromptResponses 0}} > {{index .PromptResponses 1}}"
- context: 'files'
- prompts:
- - type: 'input'
- title: 'File name:'
- - type: 'input'
- title: 'File content:'
-gui:
- theme:
- activeBorderColor:
- - green
- - bold
- SelectedRangeBgcolor:
- - reverse
diff --git a/test/integration/customCommands/expected/repo/.git_keep/COMMIT_EDITMSG b/test/integration/customCommands/expected/repo/.git_keep/COMMIT_EDITMSG
deleted file mode 100644
index 9daeafb98..000000000
--- a/test/integration/customCommands/expected/repo/.git_keep/COMMIT_EDITMSG
+++ /dev/null
@@ -1 +0,0 @@
-test
diff --git a/test/integration/customCommands/expected/repo/.git_keep/index b/test/integration/customCommands/expected/repo/.git_keep/index
deleted file mode 100644
index 1cdf852e0..000000000
Binary files a/test/integration/customCommands/expected/repo/.git_keep/index and /dev/null differ
diff --git a/test/integration/customCommands/expected/repo/.git_keep/logs/HEAD b/test/integration/customCommands/expected/repo/.git_keep/logs/HEAD
deleted file mode 100644
index db58e88aa..000000000
--- a/test/integration/customCommands/expected/repo/.git_keep/logs/HEAD
+++ /dev/null
@@ -1 +0,0 @@
-0000000000000000000000000000000000000000 15bdb2c31c825116ad5af06ee25517d90b24f13b CI 1617684452 +1000 commit (initial): test
diff --git a/test/integration/customCommands/expected/repo/.git_keep/logs/refs/heads/master b/test/integration/customCommands/expected/repo/.git_keep/logs/refs/heads/master
deleted file mode 100644
index db58e88aa..000000000
--- a/test/integration/customCommands/expected/repo/.git_keep/logs/refs/heads/master
+++ /dev/null
@@ -1 +0,0 @@
-0000000000000000000000000000000000000000 15bdb2c31c825116ad5af06ee25517d90b24f13b CI 1617684452 +1000 commit (initial): test
diff --git a/test/integration/customCommands/expected/repo/.git_keep/objects/15/bdb2c31c825116ad5af06ee25517d90b24f13b b/test/integration/customCommands/expected/repo/.git_keep/objects/15/bdb2c31c825116ad5af06ee25517d90b24f13b
deleted file mode 100644
index c309d426a..000000000
Binary files a/test/integration/customCommands/expected/repo/.git_keep/objects/15/bdb2c31c825116ad5af06ee25517d90b24f13b and /dev/null differ
diff --git a/test/integration/customCommands/expected/repo/.git_keep/objects/20/f11a5545b04a86ca81f7a9967d5207349052d7 b/test/integration/customCommands/expected/repo/.git_keep/objects/20/f11a5545b04a86ca81f7a9967d5207349052d7
deleted file mode 100644
index 368e30f82..000000000
Binary files a/test/integration/customCommands/expected/repo/.git_keep/objects/20/f11a5545b04a86ca81f7a9967d5207349052d7 and /dev/null differ
diff --git a/test/integration/customCommands/expected/repo/.git_keep/objects/8a/2e45643093ea7cf7b06382e38470034c24e812 b/test/integration/customCommands/expected/repo/.git_keep/objects/8a/2e45643093ea7cf7b06382e38470034c24e812
deleted file mode 100644
index 78c73ed64..000000000
Binary files a/test/integration/customCommands/expected/repo/.git_keep/objects/8a/2e45643093ea7cf7b06382e38470034c24e812 and /dev/null differ
diff --git a/test/integration/customCommands/expected/repo/.git_keep/refs/heads/master b/test/integration/customCommands/expected/repo/.git_keep/refs/heads/master
deleted file mode 100644
index ce73a61b4..000000000
--- a/test/integration/customCommands/expected/repo/.git_keep/refs/heads/master
+++ /dev/null
@@ -1 +0,0 @@
-15bdb2c31c825116ad5af06ee25517d90b24f13b
diff --git a/test/integration/customCommands/expected/repo/blah b/test/integration/customCommands/expected/repo/blah
deleted file mode 100644
index 20f11a554..000000000
--- a/test/integration/customCommands/expected/repo/blah
+++ /dev/null
@@ -1 +0,0 @@
-myfile
diff --git a/test/integration/customCommands/recording.json b/test/integration/customCommands/recording.json
deleted file mode 100644
index f49c696e3..000000000
--- a/test/integration/customCommands/recording.json
+++ /dev/null
@@ -1 +0,0 @@
-{"KeyEvents":[{"Timestamp":837,"Mod":0,"Key":256,"Ch":78},{"Timestamp":1622,"Mod":0,"Key":256,"Ch":109},{"Timestamp":1798,"Mod":0,"Key":256,"Ch":121},{"Timestamp":1918,"Mod":0,"Key":256,"Ch":102},{"Timestamp":2006,"Mod":0,"Key":256,"Ch":105},{"Timestamp":2078,"Mod":0,"Key":256,"Ch":108},{"Timestamp":2174,"Mod":0,"Key":256,"Ch":101},{"Timestamp":2431,"Mod":0,"Key":13,"Ch":13},{"Timestamp":3246,"Mod":0,"Key":256,"Ch":98},{"Timestamp":3294,"Mod":0,"Key":256,"Ch":108},{"Timestamp":3398,"Mod":0,"Key":256,"Ch":97},{"Timestamp":3462,"Mod":0,"Key":256,"Ch":104},{"Timestamp":3735,"Mod":0,"Key":13,"Ch":13},{"Timestamp":4206,"Mod":0,"Key":256,"Ch":32},{"Timestamp":4421,"Mod":0,"Key":256,"Ch":99},{"Timestamp":4646,"Mod":0,"Key":256,"Ch":116},{"Timestamp":4726,"Mod":0,"Key":256,"Ch":101},{"Timestamp":4886,"Mod":0,"Key":256,"Ch":115},{"Timestamp":4918,"Mod":0,"Key":256,"Ch":116},{"Timestamp":5190,"Mod":0,"Key":13,"Ch":13},{"Timestamp":5550,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":74}]}
\ No newline at end of file
diff --git a/test/integration/customCommands/setup.sh b/test/integration/customCommands/setup.sh
deleted file mode 100644
index fbd02e952..000000000
--- a/test/integration/customCommands/setup.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-set -e
-
-cd $1
-
-git init
-
-git config user.email "CI@example.com"
-git config user.name "CI"
diff --git a/test/integration/customCommands/test.json b/test/integration/customCommands/test.json
deleted file mode 100644
index c5c5aaf5c..000000000
--- a/test/integration/customCommands/test.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "description": "Invoke a custom command that creates a file, and then stage and commit that file", "speed": 5 }
diff --git a/test/integration/customCommandsComplex/config/config.yml b/test/integration/customCommandsComplex/config/config.yml
deleted file mode 100644
index 69072c2c7..000000000
--- a/test/integration/customCommandsComplex/config/config.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-disableStartupPopups: true
-customCommands:
- - key: 'N'
- description: 'Add file'
- context: 'localBranches'
- command: 'echo "{{index .PromptResponses 0}} {{index .PromptResponses 1}} {{index .PromptResponses 2}} {{ .SelectedLocalBranch.Name }}" > output.txt'
- loadingText: 'Running custom command...'
- prompts:
- - type: 'menuFromCommand'
- title: 'Title'
- command: 'git log --oneline --pretty=%B'
- filter: '(?P.*)'
- valueFormat: '{{ .commit_message }}'
- labelFormat: '{{ .commit_message | yellow }}'
- - type: 'input'
- title: 'Description'
- initialValue: "{{ if .SelectedLocalBranch.Name }}Branch: #{{ .SelectedLocalBranch.Name }}{{end}}"
- - type: 'menu'
- title: 'yes or no'
- options:
- - name: 'no'
- value: 'false'
- - name: 'yes'
- value: 'true'
-gui:
- theme:
- activeBorderColor:
- - green
- - bold
- SelectedRangeBgcolor:
- - reverse
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/COMMIT_EDITMSG b/test/integration/customCommandsComplex/expected/repo/.git_keep/COMMIT_EDITMSG
deleted file mode 100644
index 9daeafb98..000000000
--- a/test/integration/customCommandsComplex/expected/repo/.git_keep/COMMIT_EDITMSG
+++ /dev/null
@@ -1 +0,0 @@
-test
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/index b/test/integration/customCommandsComplex/expected/repo/.git_keep/index
deleted file mode 100644
index 005c7dd34..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/index and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/logs/HEAD b/test/integration/customCommandsComplex/expected/repo/.git_keep/logs/HEAD
deleted file mode 100644
index 605138dc1..000000000
--- a/test/integration/customCommandsComplex/expected/repo/.git_keep/logs/HEAD
+++ /dev/null
@@ -1,5 +0,0 @@
-0000000000000000000000000000000000000000 ab38b1ca116f77648925d952e731f419db360cdb CI 1642201096 +1100 commit (initial): myfile1
-ab38b1ca116f77648925d952e731f419db360cdb 4fdfedfd9d406506be8b02f5b863dbc08d43cc9f CI 1642201096 +1100 commit: myfile2
-4fdfedfd9d406506be8b02f5b863dbc08d43cc9f 7dd93a4be3d27d40fbe791d6d77e0d2fedc4d785 CI 1642201096 +1100 commit: myfile3
-7dd93a4be3d27d40fbe791d6d77e0d2fedc4d785 f708d3e3819470a69f6c8562ff1e68eef02f8cac CI 1642201096 +1100 commit: myfile4
-f708d3e3819470a69f6c8562ff1e68eef02f8cac 5428838691c97ac192c8b8e1c3f573d8541a94b6 CI 1642201104 +1100 commit: test
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/logs/refs/heads/master b/test/integration/customCommandsComplex/expected/repo/.git_keep/logs/refs/heads/master
deleted file mode 100644
index 605138dc1..000000000
--- a/test/integration/customCommandsComplex/expected/repo/.git_keep/logs/refs/heads/master
+++ /dev/null
@@ -1,5 +0,0 @@
-0000000000000000000000000000000000000000 ab38b1ca116f77648925d952e731f419db360cdb CI 1642201096 +1100 commit (initial): myfile1
-ab38b1ca116f77648925d952e731f419db360cdb 4fdfedfd9d406506be8b02f5b863dbc08d43cc9f CI 1642201096 +1100 commit: myfile2
-4fdfedfd9d406506be8b02f5b863dbc08d43cc9f 7dd93a4be3d27d40fbe791d6d77e0d2fedc4d785 CI 1642201096 +1100 commit: myfile3
-7dd93a4be3d27d40fbe791d6d77e0d2fedc4d785 f708d3e3819470a69f6c8562ff1e68eef02f8cac CI 1642201096 +1100 commit: myfile4
-f708d3e3819470a69f6c8562ff1e68eef02f8cac 5428838691c97ac192c8b8e1c3f573d8541a94b6 CI 1642201104 +1100 commit: test
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/05/3cf208ac3728c36c6ed86f2a03a1fb72a8e6bc b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/05/3cf208ac3728c36c6ed86f2a03a1fb72a8e6bc
deleted file mode 100644
index 161576b97..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/05/3cf208ac3728c36c6ed86f2a03a1fb72a8e6bc and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/0e/6cf0a6b79e8d44e186d812a1f74b43d64fac52 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/0e/6cf0a6b79e8d44e186d812a1f74b43d64fac52
deleted file mode 100644
index 7f2ebf4ee..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/0e/6cf0a6b79e8d44e186d812a1f74b43d64fac52 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/18/0cf8328022becee9aaa2577a8f84ea2b9f3827 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/18/0cf8328022becee9aaa2577a8f84ea2b9f3827
deleted file mode 100644
index f74bf2335..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/18/0cf8328022becee9aaa2577a8f84ea2b9f3827 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/2b/173c861df433fa43ffad13f80c8b312c5c8bce b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/2b/173c861df433fa43ffad13f80c8b312c5c8bce
deleted file mode 100644
index 0a734f981..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/2b/173c861df433fa43ffad13f80c8b312c5c8bce and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/2f/6174050380438f14b16658a356e762435ca591 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/2f/6174050380438f14b16658a356e762435ca591
deleted file mode 100644
index 31ae3f5ba..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/2f/6174050380438f14b16658a356e762435ca591 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/4f/dfedfd9d406506be8b02f5b863dbc08d43cc9f b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/4f/dfedfd9d406506be8b02f5b863dbc08d43cc9f
deleted file mode 100644
index 5bcc5c659..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/4f/dfedfd9d406506be8b02f5b863dbc08d43cc9f and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/54/28838691c97ac192c8b8e1c3f573d8541a94b6 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/54/28838691c97ac192c8b8e1c3f573d8541a94b6
deleted file mode 100644
index bd598d7ab..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/54/28838691c97ac192c8b8e1c3f573d8541a94b6 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/7d/b446a082f8c10183f1f27178698f07f3750b6b b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/7d/b446a082f8c10183f1f27178698f07f3750b6b
deleted file mode 100644
index 6de444c0f..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/7d/b446a082f8c10183f1f27178698f07f3750b6b and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/7d/d93a4be3d27d40fbe791d6d77e0d2fedc4d785 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/7d/d93a4be3d27d40fbe791d6d77e0d2fedc4d785
deleted file mode 100644
index a96d76d40..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/7d/d93a4be3d27d40fbe791d6d77e0d2fedc4d785 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/a5/bce3fd2565d8f458555a0c6f42d0504a848bd5 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/a5/bce3fd2565d8f458555a0c6f42d0504a848bd5
deleted file mode 100644
index 285df3e5f..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/a5/bce3fd2565d8f458555a0c6f42d0504a848bd5 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/a7/341a59f0ddeef969e69fb6368266d22b0f2416 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/a7/341a59f0ddeef969e69fb6368266d22b0f2416
deleted file mode 100644
index 96d2e71a6..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/a7/341a59f0ddeef969e69fb6368266d22b0f2416 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/ab/38b1ca116f77648925d952e731f419db360cdb b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/ab/38b1ca116f77648925d952e731f419db360cdb
deleted file mode 100644
index 3de7c78a7..000000000
--- a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/ab/38b1ca116f77648925d952e731f419db360cdb
+++ /dev/null
@@ -1,2 +0,0 @@
-xA
-0@ѮsL:#)1P!")#tyS5[˥*`5df 9T:KL⧽qzm[
@#a/p%Btg='MξeY.,,
\ No newline at end of file
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/d2/34c5e057fe32c676ea67e8cb38f4625ddaeb54 b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/d2/34c5e057fe32c676ea67e8cb38f4625ddaeb54
deleted file mode 100644
index d39fa7d2f..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/d2/34c5e057fe32c676ea67e8cb38f4625ddaeb54 and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/df/6b0d2bcc76e6ec0fca20c227104a4f28bac41b b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/df/6b0d2bcc76e6ec0fca20c227104a4f28bac41b
deleted file mode 100644
index 9b771fc2f..000000000
Binary files a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/df/6b0d2bcc76e6ec0fca20c227104a4f28bac41b and /dev/null differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/f7/08d3e3819470a69f6c8562ff1e68eef02f8cac b/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/f7/08d3e3819470a69f6c8562ff1e68eef02f8cac
deleted file mode 100644
index 010f8e879..000000000
--- a/test/integration/customCommandsComplex/expected/repo/.git_keep/objects/f7/08d3e3819470a69f6c8562ff1e68eef02f8cac
+++ /dev/null
@@ -1,2 +0,0 @@
-xA
-0@Q9E$I"BW=F`R"~◵[Lt껪u1*Ҍa>FvC!nHfYcBaQA\U)$q&c88KY"s؞QrӾuy*39
\ No newline at end of file
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/refs/heads/master b/test/integration/customCommandsComplex/expected/repo/.git_keep/refs/heads/master
deleted file mode 100644
index 8d1ca4f04..000000000
--- a/test/integration/customCommandsComplex/expected/repo/.git_keep/refs/heads/master
+++ /dev/null
@@ -1 +0,0 @@
-5428838691c97ac192c8b8e1c3f573d8541a94b6
diff --git a/test/integration/customCommandsComplex/expected/repo/myfile1 b/test/integration/customCommandsComplex/expected/repo/myfile1
deleted file mode 100644
index a5bce3fd2..000000000
--- a/test/integration/customCommandsComplex/expected/repo/myfile1
+++ /dev/null
@@ -1 +0,0 @@
-test1
diff --git a/test/integration/customCommandsComplex/expected/repo/myfile2 b/test/integration/customCommandsComplex/expected/repo/myfile2
deleted file mode 100644
index 180cf8328..000000000
--- a/test/integration/customCommandsComplex/expected/repo/myfile2
+++ /dev/null
@@ -1 +0,0 @@
-test2
diff --git a/test/integration/customCommandsComplex/expected/repo/myfile3 b/test/integration/customCommandsComplex/expected/repo/myfile3
deleted file mode 100644
index df6b0d2bc..000000000
--- a/test/integration/customCommandsComplex/expected/repo/myfile3
+++ /dev/null
@@ -1 +0,0 @@
-test3
diff --git a/test/integration/customCommandsComplex/expected/repo/myfile4 b/test/integration/customCommandsComplex/expected/repo/myfile4
deleted file mode 100644
index d234c5e05..000000000
--- a/test/integration/customCommandsComplex/expected/repo/myfile4
+++ /dev/null
@@ -1 +0,0 @@
-test4
diff --git a/test/integration/customCommandsComplex/expected/repo/output.txt b/test/integration/customCommandsComplex/expected/repo/output.txt
deleted file mode 100644
index 7db446a08..000000000
--- a/test/integration/customCommandsComplex/expected/repo/output.txt
+++ /dev/null
@@ -1 +0,0 @@
-myfile2 Branch: #master haha true master
diff --git a/test/integration/customCommandsComplex/recording.json b/test/integration/customCommandsComplex/recording.json
deleted file mode 100644
index 8fdbd648c..000000000
--- a/test/integration/customCommandsComplex/recording.json
+++ /dev/null
@@ -1 +0,0 @@
-{"KeyEvents":[{"Timestamp":623,"Mod":0,"Key":259,"Ch":0},{"Timestamp":1369,"Mod":0,"Key":256,"Ch":78},{"Timestamp":1904,"Mod":0,"Key":258,"Ch":0},{"Timestamp":2033,"Mod":0,"Key":258,"Ch":0},{"Timestamp":2328,"Mod":0,"Key":13,"Ch":13},{"Timestamp":2848,"Mod":0,"Key":256,"Ch":32},{"Timestamp":3296,"Mod":0,"Key":256,"Ch":97},{"Timestamp":3616,"Mod":0,"Key":127,"Ch":127},{"Timestamp":3824,"Mod":0,"Key":256,"Ch":104},{"Timestamp":3879,"Mod":0,"Key":256,"Ch":97},{"Timestamp":3927,"Mod":0,"Key":256,"Ch":104},{"Timestamp":4000,"Mod":0,"Key":256,"Ch":97},{"Timestamp":4239,"Mod":0,"Key":13,"Ch":13},{"Timestamp":4809,"Mod":0,"Key":258,"Ch":0},{"Timestamp":5024,"Mod":0,"Key":13,"Ch":13},{"Timestamp":5824,"Mod":0,"Key":260,"Ch":0},{"Timestamp":6079,"Mod":0,"Key":256,"Ch":32},{"Timestamp":6376,"Mod":0,"Key":256,"Ch":99},{"Timestamp":6591,"Mod":0,"Key":256,"Ch":116},{"Timestamp":6640,"Mod":0,"Key":256,"Ch":101},{"Timestamp":6816,"Mod":0,"Key":256,"Ch":115},{"Timestamp":6856,"Mod":0,"Key":256,"Ch":116},{"Timestamp":7136,"Mod":0,"Key":13,"Ch":13},{"Timestamp":7487,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":36}]}
\ No newline at end of file
diff --git a/test/integration/customCommandsComplex/setup.sh b/test/integration/customCommandsComplex/setup.sh
deleted file mode 100644
index 0f364d18a..000000000
--- a/test/integration/customCommandsComplex/setup.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-set -e
-
-cd $1
-
-git init
-
-git config user.email "CI@example.com"
-git config user.name "CI"
-
-echo test1 > myfile1
-git add .
-git commit -am "myfile1"
-echo test2 > myfile2
-git add .
-git commit -am "myfile2"
-echo test3 > myfile3
-git add .
-git commit -am "myfile3"
-echo test4 > myfile4
-git add .
-git commit -am "myfile4"
diff --git a/test/integration/customCommandsComplex/test.json b/test/integration/customCommandsComplex/test.json
deleted file mode 100644
index beac0e9ca..000000000
--- a/test/integration/customCommandsComplex/test.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "description": "Invoke a custom command that creates a file, and then stage and commit that file. In this case we're using a more customised flow",
- "speed": 5
-}
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/COMMIT_EDITMSG b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/COMMIT_EDITMSG
new file mode 100644
index 000000000..907b30816
--- /dev/null
+++ b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/COMMIT_EDITMSG
@@ -0,0 +1 @@
+blah
diff --git a/test/integration/customCommands/expected/repo/.git_keep/FETCH_HEAD b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/FETCH_HEAD
similarity index 100%
rename from test/integration/customCommands/expected/repo/.git_keep/FETCH_HEAD
rename to test/integration_new/custom_commands/basic/expected/repo/.git_keep/FETCH_HEAD
diff --git a/test/integration/customCommands/expected/repo/.git_keep/HEAD b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/HEAD
similarity index 100%
rename from test/integration/customCommands/expected/repo/.git_keep/HEAD
rename to test/integration_new/custom_commands/basic/expected/repo/.git_keep/HEAD
diff --git a/test/integration/customCommands/expected/repo/.git_keep/config b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/config
similarity index 100%
rename from test/integration/customCommands/expected/repo/.git_keep/config
rename to test/integration_new/custom_commands/basic/expected/repo/.git_keep/config
diff --git a/test/integration/customCommands/expected/repo/.git_keep/description b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/description
similarity index 100%
rename from test/integration/customCommands/expected/repo/.git_keep/description
rename to test/integration_new/custom_commands/basic/expected/repo/.git_keep/description
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/index b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/index
new file mode 100644
index 000000000..65d675154
Binary files /dev/null and b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/index differ
diff --git a/test/integration/customCommands/expected/repo/.git_keep/info/exclude b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/info/exclude
similarity index 100%
rename from test/integration/customCommands/expected/repo/.git_keep/info/exclude
rename to test/integration_new/custom_commands/basic/expected/repo/.git_keep/info/exclude
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/logs/HEAD b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/logs/HEAD
new file mode 100644
index 000000000..b6f3a54de
--- /dev/null
+++ b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 fe47c0cf0521f8864cd0531ddf35d2f741c14abf CI 1660476851 +1000 commit (initial): blah
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/logs/refs/heads/master b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/logs/refs/heads/master
new file mode 100644
index 000000000..b6f3a54de
--- /dev/null
+++ b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 fe47c0cf0521f8864cd0531ddf35d2f741c14abf CI 1660476851 +1000 commit (initial): blah
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100644
index 000000000..adf64119a
Binary files /dev/null and b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/objects/fe/47c0cf0521f8864cd0531ddf35d2f741c14abf b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/objects/fe/47c0cf0521f8864cd0531ddf35d2f741c14abf
new file mode 100644
index 000000000..91494d1a9
Binary files /dev/null and b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/objects/fe/47c0cf0521f8864cd0531ddf35d2f741c14abf differ
diff --git a/test/integration_new/custom_commands/basic/expected/repo/.git_keep/refs/heads/master b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/refs/heads/master
new file mode 100644
index 000000000..0dfced756
--- /dev/null
+++ b/test/integration_new/custom_commands/basic/expected/repo/.git_keep/refs/heads/master
@@ -0,0 +1 @@
+fe47c0cf0521f8864cd0531ddf35d2f741c14abf
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/FETCH_HEAD b/test/integration_new/custom_commands/basic/expected/repo/myfile
similarity index 100%
rename from test/integration/customCommandsComplex/expected/repo/.git_keep/FETCH_HEAD
rename to test/integration_new/custom_commands/basic/expected/repo/myfile
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/COMMIT_EDITMSG b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/COMMIT_EDITMSG
new file mode 100644
index 000000000..76018072e
--- /dev/null
+++ b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/COMMIT_EDITMSG
@@ -0,0 +1 @@
+baz
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/FETCH_HEAD b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/FETCH_HEAD
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/HEAD b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/HEAD
new file mode 100644
index 000000000..0e5fcffdf
--- /dev/null
+++ b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/feature/foo
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/config b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/config
similarity index 100%
rename from test/integration/customCommandsComplex/expected/repo/.git_keep/config
rename to test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/config
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/description b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/description
similarity index 100%
rename from test/integration/customCommandsComplex/expected/repo/.git_keep/description
rename to test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/description
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/index b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/index
new file mode 100644
index 000000000..65d675154
Binary files /dev/null and b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/index differ
diff --git a/test/integration/customCommandsComplex/expected/repo/.git_keep/info/exclude b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/info/exclude
similarity index 100%
rename from test/integration/customCommandsComplex/expected/repo/.git_keep/info/exclude
rename to test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/info/exclude
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/HEAD b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/HEAD
new file mode 100644
index 000000000..22805e198
--- /dev/null
+++ b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/HEAD
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 d50975554a574b9c66e109927fdb4edfb6bbadb3 CI 1660476303 +1000 commit (initial): foo
+d50975554a574b9c66e109927fdb4edfb6bbadb3 af550d3777f20bf024ad55c9c796e7e85ef32ccb CI 1660476303 +1000 commit: bar
+af550d3777f20bf024ad55c9c796e7e85ef32ccb 16919871d6b442beac07e1573c557ca433cff356 CI 1660476303 +1000 commit: baz
+16919871d6b442beac07e1573c557ca433cff356 16919871d6b442beac07e1573c557ca433cff356 CI 1660476303 +1000 checkout: moving from master to feature/foo
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/refs/heads/feature/foo b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/refs/heads/feature/foo
new file mode 100644
index 000000000..5538ba67f
--- /dev/null
+++ b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/refs/heads/feature/foo
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 16919871d6b442beac07e1573c557ca433cff356 CI 1660476303 +1000 branch: Created from HEAD
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/refs/heads/master b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/refs/heads/master
new file mode 100644
index 000000000..f9d13618c
--- /dev/null
+++ b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/logs/refs/heads/master
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 d50975554a574b9c66e109927fdb4edfb6bbadb3 CI 1660476303 +1000 commit (initial): foo
+d50975554a574b9c66e109927fdb4edfb6bbadb3 af550d3777f20bf024ad55c9c796e7e85ef32ccb CI 1660476303 +1000 commit: bar
+af550d3777f20bf024ad55c9c796e7e85ef32ccb 16919871d6b442beac07e1573c557ca433cff356 CI 1660476303 +1000 commit: baz
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/16/919871d6b442beac07e1573c557ca433cff356 b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/16/919871d6b442beac07e1573c557ca433cff356
new file mode 100644
index 000000000..7b0995a4d
Binary files /dev/null and b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/16/919871d6b442beac07e1573c557ca433cff356 differ
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100644
index 000000000..adf64119a
Binary files /dev/null and b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/af/550d3777f20bf024ad55c9c796e7e85ef32ccb b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/af/550d3777f20bf024ad55c9c796e7e85ef32ccb
new file mode 100644
index 000000000..5de7e30df
Binary files /dev/null and b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/af/550d3777f20bf024ad55c9c796e7e85ef32ccb differ
diff --git a/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/d5/0975554a574b9c66e109927fdb4edfb6bbadb3 b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/d5/0975554a574b9c66e109927fdb4edfb6bbadb3
new file mode 100644
index 000000000..a8654985c
--- /dev/null
+++ b/test/integration_new/custom_commands/menu_from_command/expected/repo/.git_keep/objects/d5/0975554a574b9c66e109927fdb4edfb6bbadb3
@@ -0,0 +1,3 @@
+xA
+0@Q91)BW=F&`R"n?~ 1660476863 +1000 commit (initial): blah
diff --git a/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/logs/refs/heads/master b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/logs/refs/heads/master
new file mode 100644
index 000000000..4f92ac410
--- /dev/null
+++ b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 b97a1d7c0e8dceef724220008962f8512a974ff0 CI 1660476863 +1000 commit (initial): blah
diff --git a/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100644
index 000000000..adf64119a
Binary files /dev/null and b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/objects/b9/7a1d7c0e8dceef724220008962f8512a974ff0 b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/objects/b9/7a1d7c0e8dceef724220008962f8512a974ff0
new file mode 100644
index 000000000..7344889d7
Binary files /dev/null and b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/objects/b9/7a1d7c0e8dceef724220008962f8512a974ff0 differ
diff --git a/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/refs/heads/master b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/refs/heads/master
new file mode 100644
index 000000000..9cd8f786a
--- /dev/null
+++ b/test/integration_new/custom_commands/multiple_prompts/expected/repo/.git_keep/refs/heads/master
@@ -0,0 +1 @@
+b97a1d7c0e8dceef724220008962f8512a974ff0
diff --git a/test/integration_new/custom_commands/multiple_prompts/expected/repo/myfile b/test/integration_new/custom_commands/multiple_prompts/expected/repo/myfile
new file mode 100644
index 000000000..ba578e48b
--- /dev/null
+++ b/test/integration_new/custom_commands/multiple_prompts/expected/repo/myfile
@@ -0,0 +1 @@
+BAR
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 923b40da1..e7ae53317 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
-# github.com/jesseduffield/gocui v0.3.1-0.20220813101052-3a3ab26faa15
+# github.com/jesseduffield/gocui v0.3.1-0.20220815095708-156fda5e0419
## explicit; go 1.12
github.com/jesseduffield/gocui
# github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10