mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-14 11:23:09 +02:00
c465b0f2ff
This prevents commands like "go test ./..." from looking into it, and it prevents VS Code's Problems panel from showing errors about the go files in that folder.
255 lines
6.0 KiB
Go
255 lines
6.0 KiB
Go
package components
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
lazycoreUtils "github.com/jesseduffield/lazycore/pkg/utils"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
const (
|
|
TEST_NAME_ENV_VAR = "TEST_NAME"
|
|
SANDBOX_ENV_VAR = "SANDBOX"
|
|
GIT_CONFIG_GLOBAL_ENV_VAR = "GIT_CONFIG_GLOBAL"
|
|
)
|
|
|
|
// This function lets you run tests either from within `go test` or from a regular binary.
|
|
// The reason for having two separate ways of testing is that `go test` isn't great at
|
|
// showing what's actually happening during the test, but it's still good at running
|
|
// tests in telling you about their results.
|
|
func RunTests(
|
|
tests []*IntegrationTest,
|
|
logf func(format string, formatArgs ...interface{}),
|
|
runCmd func(cmd *exec.Cmd) error,
|
|
testWrapper func(test *IntegrationTest, f func() error),
|
|
sandbox bool,
|
|
waitForDebugger bool,
|
|
inputDelay int,
|
|
maxAttempts int,
|
|
) error {
|
|
projectRootDir := lazycoreUtils.GetLazyRootDirectory()
|
|
err := os.Chdir(projectRootDir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
testDir := filepath.Join(projectRootDir, "test", "_results")
|
|
|
|
if err := buildLazygit(); err != nil {
|
|
return err
|
|
}
|
|
|
|
gitVersion, err := getGitVersion()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, test := range tests {
|
|
test := test
|
|
|
|
testWrapper(test, func() error { //nolint: thelper
|
|
paths := NewPaths(
|
|
filepath.Join(testDir, test.Name()),
|
|
)
|
|
|
|
for i := 0; i < maxAttempts; i++ {
|
|
err := runTest(test, paths, projectRootDir, logf, runCmd, sandbox, waitForDebugger, inputDelay, gitVersion)
|
|
if err != nil {
|
|
if i == maxAttempts-1 {
|
|
return err
|
|
}
|
|
logf("retrying test %s", test.Name())
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func runTest(
|
|
test *IntegrationTest,
|
|
paths Paths,
|
|
projectRootDir string,
|
|
logf func(format string, formatArgs ...interface{}),
|
|
runCmd func(cmd *exec.Cmd) error,
|
|
sandbox bool,
|
|
waitForDebugger bool,
|
|
inputDelay int,
|
|
gitVersion *git_commands.GitVersion,
|
|
) error {
|
|
if test.Skip() {
|
|
logf("Skipping test %s", test.Name())
|
|
return nil
|
|
}
|
|
|
|
if !test.ShouldRunForGitVersion(gitVersion) {
|
|
logf("Skipping test %s for git version %d.%d.%d", test.Name(), gitVersion.Major, gitVersion.Minor, gitVersion.Patch)
|
|
return nil
|
|
}
|
|
|
|
if err := prepareTestDir(test, paths, projectRootDir); err != nil {
|
|
return err
|
|
}
|
|
|
|
cmd, err := getLazygitCommand(test, paths, projectRootDir, sandbox, waitForDebugger, inputDelay)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = runCmd(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func prepareTestDir(
|
|
test *IntegrationTest,
|
|
paths Paths,
|
|
rootDir string,
|
|
) error {
|
|
findOrCreateDir(paths.Root())
|
|
deleteAndRecreateEmptyDir(paths.Actual())
|
|
|
|
err := os.Mkdir(paths.ActualRepo(), 0o777)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return createFixture(test, paths, rootDir)
|
|
}
|
|
|
|
func buildLazygit() error {
|
|
// // TODO: remove this line!
|
|
// // skipping this because I'm not making changes to the app code atm.
|
|
// return nil
|
|
|
|
osCommand := oscommands.NewDummyOSCommand()
|
|
return osCommand.Cmd.New([]string{
|
|
"go", "build", "-o", tempLazygitPath(), filepath.FromSlash("pkg/integration/clients/injector/main.go"),
|
|
}).Run()
|
|
}
|
|
|
|
func createFixture(test *IntegrationTest, paths Paths, rootDir string) error {
|
|
shell := NewShell(paths.ActualRepo(), func(errorMsg string) { panic(errorMsg) })
|
|
shell.Init()
|
|
|
|
os.Setenv(GIT_CONFIG_GLOBAL_ENV_VAR, globalGitConfigPath(rootDir))
|
|
|
|
test.SetupRepo(shell)
|
|
|
|
return nil
|
|
}
|
|
|
|
func globalGitConfigPath(rootDir string) string {
|
|
return filepath.Join(rootDir, "test", "global_git_config")
|
|
}
|
|
|
|
func getGitVersion() (*git_commands.GitVersion, error) {
|
|
osCommand := oscommands.NewDummyOSCommand()
|
|
cmdObj := osCommand.Cmd.New([]string{"git", "--version"})
|
|
versionStr, err := cmdObj.RunWithOutput()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return git_commands.ParseGitVersion(versionStr)
|
|
}
|
|
|
|
func getLazygitCommand(test *IntegrationTest, paths Paths, rootDir string, sandbox bool, waitForDebugger bool, inputDelay int) (*exec.Cmd, error) {
|
|
osCommand := oscommands.NewDummyOSCommand()
|
|
|
|
err := os.RemoveAll(paths.Config())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
templateConfigDir := filepath.Join(rootDir, "test", "default_test_config")
|
|
err = oscommands.CopyDir(templateConfigDir, paths.Config())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cmdArgs := []string{tempLazygitPath(), "-debug", "--use-config-dir=" + paths.Config()}
|
|
if !test.useCustomPath {
|
|
cmdArgs = append(cmdArgs, "--path="+paths.ActualRepo())
|
|
}
|
|
resolvedExtraArgs := lo.Map(test.ExtraCmdArgs(), func(arg string, _ int) string {
|
|
return utils.ResolvePlaceholderString(arg, map[string]string{
|
|
"actualPath": paths.Actual(),
|
|
"actualRepoPath": paths.ActualRepo(),
|
|
})
|
|
})
|
|
cmdArgs = append(cmdArgs, resolvedExtraArgs...)
|
|
|
|
cmdObj := osCommand.Cmd.New(cmdArgs)
|
|
|
|
cmdObj.AddEnvVars(fmt.Sprintf("%s=%s", TEST_NAME_ENV_VAR, test.Name()))
|
|
if sandbox {
|
|
cmdObj.AddEnvVars(fmt.Sprintf("%s=%s", SANDBOX_ENV_VAR, "true"))
|
|
}
|
|
if waitForDebugger {
|
|
cmdObj.AddEnvVars("WAIT_FOR_DEBUGGER=true")
|
|
}
|
|
if test.ExtraEnvVars() != nil {
|
|
for key, value := range test.ExtraEnvVars() {
|
|
cmdObj.AddEnvVars(fmt.Sprintf("%s=%s", key, value))
|
|
}
|
|
}
|
|
|
|
if inputDelay > 0 {
|
|
cmdObj.AddEnvVars(fmt.Sprintf("INPUT_DELAY=%d", inputDelay))
|
|
}
|
|
|
|
cmdObj.AddEnvVars(fmt.Sprintf("%s=%s", GIT_CONFIG_GLOBAL_ENV_VAR, globalGitConfigPath(rootDir)))
|
|
|
|
return cmdObj.GetCmd(), nil
|
|
}
|
|
|
|
func tempLazygitPath() string {
|
|
return filepath.Join("/tmp", "lazygit", "test_lazygit")
|
|
}
|
|
|
|
func findOrCreateDir(path string) {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
err = os.MkdirAll(path, 0o777)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
} else {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func deleteAndRecreateEmptyDir(path string) {
|
|
// remove contents of integration test directory
|
|
dir, err := os.ReadDir(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
err = os.Mkdir(path, 0o777)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
} else {
|
|
panic(err)
|
|
}
|
|
}
|
|
for _, d := range dir {
|
|
os.RemoveAll(filepath.Join(path, d.Name()))
|
|
}
|
|
}
|