1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-02-03 13:21:56 +02:00

refactor to ensure code doesn't depend on integration code

This commit is contained in:
Jesse Duffield 2022-08-13 12:56:04 +10:00
parent 2bdefe2049
commit 304d74370e
16 changed files with 203 additions and 169 deletions

135
main.go
View File

@ -1,151 +1,24 @@
package main
import (
"os"
"runtime/debug"
"github.com/integrii/flaggy"
"github.com/jesseduffield/lazygit/pkg/app"
"github.com/jesseduffield/lazygit/pkg/integration"
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
const DEFAULT_VERSION = "unversioned"
// These values may be set by the build script.
// we'll overwrite them if they haven't been set by the build script and if Go itself has set corresponding values in the binary
// These values may be set by the build script via the LDFLAGS argument
var (
commit string
version = DEFAULT_VERSION
date string
version string
buildSource = "unknown"
)
func main() {
cliArgs := parseCliArgsAndEnvVars()
buildInfo := getBuildInfo()
integrationTest := getIntegrationTest()
app.Start(cliArgs, buildInfo, integrationTest)
}
func parseCliArgsAndEnvVars() *app.CliArgs {
flaggy.DefaultParser.ShowVersionWithVersionFlag = false
repoPath := ""
flaggy.String(&repoPath, "p", "path", "Path of git repo. (equivalent to --work-tree=<path> --git-dir=<path>/.git/)")
filterPath := ""
flaggy.String(&filterPath, "f", "filter", "Path to filter on in `git log -- <path>`. When in filter mode, the commits, reflog, and stash are filtered based on the given path, and some operations are restricted")
gitArg := ""
flaggy.AddPositionalValue(&gitArg, "git-arg", 1, false, "Panel to focus upon opening lazygit. Accepted values (based on git terminology): status, branch, log, stash. Ignored if --filter arg is passed.")
printVersionInfo := false
flaggy.Bool(&printVersionInfo, "v", "version", "Print the current version")
debug := false
flaggy.Bool(&debug, "d", "debug", "Run in debug mode with logging (see --logs flag below). Use the LOG_LEVEL env var to set the log level (debug/info/warn/error)")
tailLogs := false
flaggy.Bool(&tailLogs, "l", "logs", "Tail lazygit logs (intended to be used when `lazygit --debug` is called in a separate terminal tab)")
printDefaultConfig := false
flaggy.Bool(&printDefaultConfig, "c", "config", "Print the default config")
printConfigDir := false
flaggy.Bool(&printConfigDir, "cd", "print-config-dir", "Print the config directory")
useConfigDir := ""
flaggy.String(&useConfigDir, "ucd", "use-config-dir", "override default config directory with provided directory")
workTree := ""
flaggy.String(&workTree, "w", "work-tree", "equivalent of the --work-tree git argument")
gitDir := ""
flaggy.String(&gitDir, "g", "git-dir", "equivalent of the --git-dir git argument")
customConfigFile := ""
flaggy.String(&customConfigFile, "ucf", "use-config-file", "Comma separated list to custom config file(s)")
flaggy.Parse()
if os.Getenv("DEBUG") == "TRUE" {
debug = true
}
return &app.CliArgs{
RepoPath: repoPath,
FilterPath: filterPath,
GitArg: gitArg,
PrintVersionInfo: printVersionInfo,
Debug: debug,
TailLogs: tailLogs,
PrintDefaultConfig: printDefaultConfig,
PrintConfigDir: printConfigDir,
UseConfigDir: useConfigDir,
WorkTree: workTree,
GitDir: gitDir,
CustomConfigFile: customConfigFile,
}
}
func getBuildInfo() *app.BuildInfo {
buildInfo := &app.BuildInfo{
ldFlagsBuildInfo := &app.BuildInfo{
Commit: commit,
Date: date,
Version: version,
BuildSource: buildSource,
}
// if the version has already been set by build flags then we'll honour that.
// chances are it's something like v0.31.0 which is more informative than a
// commit hash.
if buildInfo.Version != DEFAULT_VERSION {
return buildInfo
}
goBuildInfo, ok := debug.ReadBuildInfo()
if !ok {
return buildInfo
}
revision, ok := lo.Find(goBuildInfo.Settings, func(setting debug.BuildSetting) bool {
return setting.Key == "vcs.revision"
})
if ok {
buildInfo.Commit = revision.Value
// if lazygit was built from source we'll show the version as the
// abbreviated commit hash
buildInfo.Version = utils.ShortSha(revision.Value)
}
// if version hasn't been set we assume that neither has the date
time, ok := lo.Find(goBuildInfo.Settings, func(setting debug.BuildSetting) bool {
return setting.Key == "vcs.time"
})
if ok {
buildInfo.Date = time.Value
}
return buildInfo
}
func getIntegrationTest() integrationTypes.IntegrationTest {
integrationTestName := os.Getenv("LAZYGIT_TEST_NAME")
if integrationTestName == "" {
return nil
}
// unsetting so that if we run lazygit in as a 'daemon' we don't think we're trying to run a test again
os.Unsetenv("LAZYGIT_TEST_NAME")
for _, candidateTest := range integration.Tests {
if candidateTest.Name() == integrationTestName {
return candidateTest
}
}
panic("Could not find integration test with name: " + integrationTestName)
app.Start(ldFlagsBuildInfo, nil)
}

View File

@ -7,18 +7,22 @@ import (
"os"
"path/filepath"
"runtime"
"runtime/debug"
"strings"
"github.com/integrii/flaggy"
"github.com/jesseduffield/lazygit/pkg/app/daemon"
appTypes "github.com/jesseduffield/lazygit/pkg/app/types"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/env"
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
"github.com/jesseduffield/lazygit/pkg/logs"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
"gopkg.in/yaml.v3"
)
type CliArgs struct {
type cliArgs struct {
RepoPath string
FilterPath string
GitArg string
@ -40,7 +44,10 @@ type BuildInfo struct {
BuildSource string
}
func Start(cliArgs *CliArgs, buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTest) {
func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTest) {
cliArgs := parseCliArgsAndEnvVars()
mergeBuildInfo(buildInfo)
if cliArgs.RepoPath != "" {
if cliArgs.WorkTree != "" || cliArgs.GitDir != "" {
log.Fatal("--path option is incompatible with the --work-tree and --git-dir options")
@ -132,6 +139,67 @@ func Start(cliArgs *CliArgs, buildInfo *BuildInfo, integrationTest integrationTy
Run(appConfig, common, appTypes.NewStartArgs(cliArgs.FilterPath, parsedGitArg, integrationTest))
}
func parseCliArgsAndEnvVars() *cliArgs {
flaggy.DefaultParser.ShowVersionWithVersionFlag = false
repoPath := ""
flaggy.String(&repoPath, "p", "path", "Path of git repo. (equivalent to --work-tree=<path> --git-dir=<path>/.git/)")
filterPath := ""
flaggy.String(&filterPath, "f", "filter", "Path to filter on in `git log -- <path>`. When in filter mode, the commits, reflog, and stash are filtered based on the given path, and some operations are restricted")
gitArg := ""
flaggy.AddPositionalValue(&gitArg, "git-arg", 1, false, "Panel to focus upon opening lazygit. Accepted values (based on git terminology): status, branch, log, stash. Ignored if --filter arg is passed.")
printVersionInfo := false
flaggy.Bool(&printVersionInfo, "v", "version", "Print the current version")
debug := false
flaggy.Bool(&debug, "d", "debug", "Run in debug mode with logging (see --logs flag below). Use the LOG_LEVEL env var to set the log level (debug/info/warn/error)")
tailLogs := false
flaggy.Bool(&tailLogs, "l", "logs", "Tail lazygit logs (intended to be used when `lazygit --debug` is called in a separate terminal tab)")
printDefaultConfig := false
flaggy.Bool(&printDefaultConfig, "c", "config", "Print the default config")
printConfigDir := false
flaggy.Bool(&printConfigDir, "cd", "print-config-dir", "Print the config directory")
useConfigDir := ""
flaggy.String(&useConfigDir, "ucd", "use-config-dir", "override default config directory with provided directory")
workTree := ""
flaggy.String(&workTree, "w", "work-tree", "equivalent of the --work-tree git argument")
gitDir := ""
flaggy.String(&gitDir, "g", "git-dir", "equivalent of the --git-dir git argument")
customConfigFile := ""
flaggy.String(&customConfigFile, "ucf", "use-config-file", "Comma separated list to custom config file(s)")
flaggy.Parse()
if os.Getenv("DEBUG") == "TRUE" {
debug = true
}
return &cliArgs{
RepoPath: repoPath,
FilterPath: filterPath,
GitArg: gitArg,
PrintVersionInfo: printVersionInfo,
Debug: debug,
TailLogs: tailLogs,
PrintDefaultConfig: printDefaultConfig,
PrintConfigDir: printConfigDir,
UseConfigDir: useConfigDir,
WorkTree: workTree,
GitDir: gitDir,
CustomConfigFile: customConfigFile,
}
}
func parseGitArg(gitArg string) appTypes.GitArg {
typedArg := appTypes.GitArg(gitArg)
@ -155,3 +223,43 @@ func parseGitArg(gitArg string) appTypes.GitArg {
panic("unreachable")
}
// the buildInfo struct we get passed in is based on what's baked into the lazygit
// binary via the LDFLAGS argument. Some lazygit distributions will make use of these
// arguments and some will not. Go recently started baking in build info
// into the binary by default e.g. the git commit hash. So in this function
// we merge the two together, giving priority to the stuff set by LDFLAGS.
// Note: this mutates the argument passed in
func mergeBuildInfo(buildInfo *BuildInfo) {
// if the version has already been set by build flags then we'll honour that.
// chances are it's something like v0.31.0 which is more informative than a
// commit hash.
if buildInfo.Version != "" {
return
}
buildInfo.Version = "unversioned"
goBuildInfo, ok := debug.ReadBuildInfo()
if !ok {
return
}
revision, ok := lo.Find(goBuildInfo.Settings, func(setting debug.BuildSetting) bool {
return setting.Key == "vcs.revision"
})
if ok {
buildInfo.Commit = revision.Value
// if lazygit was built from source we'll show the version as the
// abbreviated commit hash
buildInfo.Version = utils.ShortSha(revision.Value)
}
// if version hasn't been set we assume that neither has the date
time, ok := lo.Find(goBuildInfo.Settings, func(setting debug.BuildSetting) bool {
return setting.Key == "vcs.time"
})
if ok {
buildInfo.Date = time.Value
}
}

View File

@ -14,13 +14,13 @@ import (
// this gives our integration test a way of interacting with the gui for sending keypresses
// and reading state.
type GuiAdapter struct {
type GuiDriver struct {
gui *Gui
}
var _ integrationTypes.GuiAdapter = &GuiAdapter{}
var _ integrationTypes.GuiDriver = &GuiDriver{}
func (self *GuiAdapter) PressKey(keyStr string) {
func (self *GuiDriver) PressKey(keyStr string) {
key := keybindings.GetKey(keyStr)
var r rune
@ -39,19 +39,19 @@ func (self *GuiAdapter) PressKey(keyStr string) {
)
}
func (self *GuiAdapter) Keys() config.KeybindingConfig {
func (self *GuiDriver) Keys() config.KeybindingConfig {
return self.gui.Config.GetUserConfig().Keybinding
}
func (self *GuiAdapter) CurrentContext() types.Context {
func (self *GuiDriver) CurrentContext() types.Context {
return self.gui.c.CurrentContext()
}
func (self *GuiAdapter) Model() *types.Model {
func (self *GuiDriver) Model() *types.Model {
return self.gui.State.Model
}
func (self *GuiAdapter) Fail(message string) {
func (self *GuiDriver) Fail(message string) {
self.gui.g.Close()
// need to give the gui time to close
time.Sleep(time.Millisecond * 100)
@ -59,15 +59,15 @@ func (self *GuiAdapter) Fail(message string) {
}
// logs to the normal place that you log to i.e. viewable with `lazygit --logs`
func (self *GuiAdapter) Log(message string) {
func (self *GuiDriver) Log(message string) {
self.gui.c.Log.Warn(message)
}
// logs in the actual UI (in the commands panel)
func (self *GuiAdapter) LogUI(message string) {
func (self *GuiDriver) LogUI(message string) {
self.gui.c.LogAction(message)
}
func (self *GuiAdapter) CheckedOutRef() *models.Branch {
func (self *GuiDriver) CheckedOutRef() *models.Branch {
return self.gui.helpers.Refs.GetCheckedOutRef()
}

View File

@ -14,7 +14,7 @@ import (
)
type IntegrationTest interface {
Run(guiAdapter *GuiAdapter)
Run(guiAdapter *GuiDriver)
}
func (gui *Gui) handleTestMode(test integrationTypes.IntegrationTest) {
@ -22,7 +22,7 @@ func (gui *Gui) handleTestMode(test integrationTypes.IntegrationTest) {
go func() {
time.Sleep(time.Millisecond * 100)
test.Run(&GuiAdapter{gui: gui})
test.Run(&GuiDriver{gui: gui})
gui.g.Update(func(*gocui.Gui) error {
return gocui.ErrQuit

View File

@ -37,15 +37,15 @@ 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 pkg/integration/runner/main.go [<testname>...]
2. go run pkg/integration/tui/main.go
1. go run pkg/integration/cmd/runner/main.go [<testname>...]
2. go run pkg/integration/cmd/tui/main.go
3. go test pkg/integration/integration_test.go
The first, the test runner, is for directly running a test from the command line. If you pass no arguments, it runs all tests.
The second, the TUI, is for running tests from a terminal UI where it's easier to find a test and run it without having to copy it's name and paste it into the terminal. This is the easiest approach by far.
The third, the go-test command, intended only for use in CI, to be run along with the other `go test` tests. This runs the tests in headless mode so there's no visual output.
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 pkg/integration/runner/main.go commit/new_branch`.
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 pkg/integration/cmd/runner/main.go 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.
@ -68,7 +68,7 @@ At the moment, all the deprecated test code lives in pkg/integration/deprecated.
We should never write any new tests under the old method, and if a given test breaks because of new functionality, it's best to simply rewrite it under the new approach. If you want to run a test for the sake of watching what it does so that you can transcribe it into the new approach, you can run:
```
go run pkg/integration/deprecated/tui/main.go
go run pkg/integration/deprecated/cmd/tui/main.go
```
The tests in the old format live in test/integration. In the old format, test definitions are co-located with the snapshots. The setup step is done in a `setup.sh` shell script and the `recording.json` file contains the recorded keypresses to be replayed during the test.

View File

@ -0,0 +1,47 @@
package main
import (
"os"
"github.com/jesseduffield/lazygit/pkg/app"
"github.com/jesseduffield/lazygit/pkg/integration"
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
)
// The purpose of this program is to run lazygit with an integration test passed in.
// We could have done the check on LAZYGIT_TEST_NAME in the root main.go but
// that would mean lazygit would be depending on integration test code which
// would bloat the binary.
// You should not invoke this program directly. Instead you should go through
// pkg/integration/cmd/runner/main.go or pkg/integration/cmd/tui/main.go
func main() {
dummyBuildInfo := &app.BuildInfo{
Commit: "",
Date: "",
Version: "",
BuildSource: "integration test",
}
integrationTest := getIntegrationTest()
app.Start(dummyBuildInfo, integrationTest)
}
func getIntegrationTest() integrationTypes.IntegrationTest {
integrationTestName := os.Getenv("LAZYGIT_TEST_NAME")
if integrationTestName == "" {
panic("expected LAZYGIT_TEST_NAME environment variable to be set, given that we're running an integration test")
}
// unsetting so that if we run lazygit in as a 'daemon' we don't think we're trying to run a test again
os.Unsetenv("LAZYGIT_TEST_NAME")
for _, candidateTest := range integration.Tests {
if candidateTest.Name() == integrationTestName {
return candidateTest
}
}
panic("Could not find integration test with name: " + integrationTestName)
}

View File

@ -12,7 +12,13 @@ import (
// see pkg/integration/README.md
// If invoked directly, you can specify tests to run by passing them as positional arguments.
// The purpose of this program is to run integration tests. It does this by
// building our injector program (in the sibling injector directory) and then for
// each test we're running, invoke the injector program with the test's name as
// an environment variable. Then the injector finds the test and passes it to
// the lazygit startup code.
// If invoked directly, you can specify tests to run by passing their names as positional arguments
func main() {
mode := integration.GetModeFromEnv()

View File

@ -15,7 +15,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/secureexec"
)
// this program lets you manage integration tests in a TUI. See pkg/integration/README.md for more info.
// This program lets you run integration tests from a TUI. See pkg/integration/README.md for more info.
type App struct {
tests []*components.IntegrationTest
@ -85,7 +85,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=sandbox go run pkg/integration/runner/main.go %s", currentTest.Name()))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=sandbox go run pkg/integration/cmd/runner/main.go %s", currentTest.Name()))
app.runSubprocess(cmd)
return nil
@ -99,7 +99,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true go run pkg/integration/runner/main.go %s", currentTest.Name()))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true go run pkg/integration/cmd/runner/main.go %s", currentTest.Name()))
app.runSubprocess(cmd)
return nil
@ -113,7 +113,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true KEY_PRESS_DELAY=200 go run pkg/integration/runner/main.go %s", currentTest.Name()))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true KEY_PRESS_DELAY=200 go run pkg/integration/cmd/runner/main.go %s", currentTest.Name()))
app.runSubprocess(cmd)
return nil

View File

@ -12,10 +12,10 @@ import (
// through this struct we assert on the state of the lazygit gui
type Assert struct {
gui integrationTypes.GuiAdapter
gui integrationTypes.GuiDriver
}
func NewAssert(gui integrationTypes.GuiAdapter) *Assert {
func NewAssert(gui integrationTypes.GuiDriver) *Assert {
return &Assert{gui: gui}
}

View File

@ -11,13 +11,13 @@ import (
)
type Input struct {
gui integrationTypes.GuiAdapter
gui integrationTypes.GuiDriver
keys config.KeybindingConfig
assert *Assert
pushKeyDelay int
}
func NewInput(gui integrationTypes.GuiAdapter, keys config.KeybindingConfig, assert *Assert, pushKeyDelay int) *Input {
func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, assert *Assert, pushKeyDelay int) *Input {
return &Input{
gui: gui,
keys: keys,

View File

@ -81,7 +81,7 @@ func (self *IntegrationTest) SetupRepo(shell *Shell) {
}
// I want access to all contexts, the model, the ability to press a key, the ability to log,
func (self *IntegrationTest) Run(gui integrationTypes.GuiAdapter) {
func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) {
shell := NewShell()
assert := NewAssert(gui)
keys := gui.Keys()

View File

@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/assert"
)
// Deprecated: This file is part of the old way of doing things. See pkg/integration/runner/main.go for the new way
// Deprecated: This file is part of the old way of doing things. See pkg/integration/cmd/runner/main.go for the new way
// see https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md
// This file can be invoked directly, but you might find it easier to go through

View File

@ -108,7 +108,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=record go run pkg/integration/deprecated/runner/main.go %s", currentTest.Name))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=record go run pkg/integration/deprecated/cmd/runner/main.go %s", currentTest.Name))
app.runSubprocess(cmd)
return nil
@ -122,7 +122,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=sandbox go run pkg/integration/deprecated/runner/main.go %s", currentTest.Name))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=sandbox go run pkg/integration/deprecated/cmd/runner/main.go %s", currentTest.Name))
app.runSubprocess(cmd)
return nil
@ -136,7 +136,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true go run pkg/integration/deprecated/runner/main.go %s", currentTest.Name))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true go run pkg/integration/deprecated/cmd/runner/main.go %s", currentTest.Name))
app.runSubprocess(cmd)
return nil
@ -150,7 +150,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=updateSnapshot go run pkg/integration/deprecated/runner/main.go %s", currentTest.Name))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true MODE=updateSnapshot go run pkg/integration/deprecated/cmd/runner/main.go %s", currentTest.Name))
app.runSubprocess(cmd)
return nil
@ -164,7 +164,7 @@ func main() {
return nil
}
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true SPEED=1 go run pkg/integration/deprecated/runner/main.go %s", currentTest.Name))
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("INCLUDE_SKIPPED=true SPEED=1 go run pkg/integration/deprecated/cmd/runner/main.go %s", currentTest.Name))
app.runSubprocess(cmd)
return nil

View File

@ -20,7 +20,7 @@ import (
// Deprecated: This file is part of the old way of doing things. See pkg/integration/integration.go for the new way
// This package is for running our integration test suite. See https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.mdfor more info.
// This package is for running our integration test suite. See https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md for more info.
type IntegrationTest struct {
Name string `json:"name"`

View File

@ -58,7 +58,7 @@ func RunTests(
testDir := filepath.Join(rootDir, "test", "integration_new")
osCommand := oscommands.NewDummyOSCommand()
err = osCommand.Cmd.New("go build -o " + tempLazygitPath()).Run()
err = osCommand.Cmd.New("go build pkg/integration/cmd/intector.go -o " + tempLazygitPath()).Run()
if err != nil {
return err
}

View File

@ -10,12 +10,12 @@ import (
// to provide to a test in order for the test to run.
type IntegrationTest interface {
Run(GuiAdapter)
Run(GuiDriver)
SetupConfig(config *config.AppConfig)
}
// this is the interface through which our integration tests interact with the lazygit gui
type GuiAdapter interface {
type GuiDriver interface {
PressKey(string)
Keys() config.KeybindingConfig
CurrentContext() types.Context