mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02:00 
			
		
		
		
	Run integration tests with all supported git versions (#2754)
Run integration tests with various different git versions, more or less randomly picked from our range of supported versions. Based on @Ryooooooga's work in #2459, but also restructured a bit. All tests pass for all git versions, but only after cherry-picking #2747. I decided to go with @Ryooooooga's approach and do it without using docker. I also didn't use docker locally; to reproduce the various failures that I had to fix, I simply installed the respective git versions locally and used something like `PATH=~/git-versions/2.25.1/bin:$PATH ./scripts/run_integration_tests.sh`.
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/cd.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/cd.yml
									
									
									
									
										vendored
									
									
								
							| @@ -10,7 +10,7 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Unshallow repo | ||||
|         run: git fetch --prune --unshallow | ||||
|       - name: Setup Go | ||||
|   | ||||
							
								
								
									
										50
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -28,7 +28,7 @@ jobs: | ||||
|       GOFLAGS: -mod=vendor | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Setup Go | ||||
|         uses: actions/setup-go@v1 | ||||
|         with: | ||||
| @@ -47,13 +47,47 @@ jobs: | ||||
|         run: | | ||||
|           go test ./... -short | ||||
|   integration-tests: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         git-version: | ||||
|           - 2.20.0 # oldest supported version | ||||
|           - 2.22.5 | ||||
|           - 2.23.0 | ||||
|           - 2.25.1 | ||||
|           - 2.30.8 | ||||
|           - latest # We rely on github to have the latest version installed on their VMs | ||||
|     runs-on: ubuntu-latest | ||||
|     name: "Integration Tests" | ||||
|     name: "Integration Tests - git ${{matrix.git-version}}" | ||||
|     env: | ||||
|       GOFLAGS: -mod=vendor | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Restore Git cache | ||||
|         if: matrix.git-version != 'latest' | ||||
|         id: cache-git-restore | ||||
|         uses: actions/cache/restore@v3 | ||||
|         with: | ||||
|           path: ~/git-${{matrix.git-version}} | ||||
|           key: ${{runner.os}}-git-${{matrix.git-version}} | ||||
|       - name: Build Git ${{matrix.git-version}} | ||||
|         if: steps.cache-git-restore.outputs.cache-hit != 'true' && matrix.git-version != 'latest' | ||||
|         run: > | ||||
|           sudo apt-get update && sudo apt-get install --no-install-recommends -y build-essential ca-certificates curl gettext libexpat1-dev libssl-dev libz-dev openssl | ||||
|           && curl -sL "https://mirrors.edge.kernel.org/pub/software/scm/git/git-${{matrix.git-version}}.tar.xz" -o - | tar xJ -C "$HOME" | ||||
|           && cd "$HOME/git-${{matrix.git-version}}" | ||||
|           && ./configure | ||||
|           && make -j | ||||
|       - name: Install Git ${{matrix.git-version}} | ||||
|         if: matrix.git-version != 'latest' | ||||
|         run: sudo make -C "$HOME/git-${{matrix.git-version}}" -j install | ||||
|       - name: Save Git cache | ||||
|         if: steps.cache-git-restore.outputs.cache-hit != 'true' && matrix.git-version != 'latest' | ||||
|         uses: actions/cache/save@v3 | ||||
|         with: | ||||
|           path: ~/git-${{matrix.git-version}} | ||||
|           key: ${{runner.os}}-git-${{matrix.git-version}} | ||||
|       - name: Setup Go | ||||
|         uses: actions/setup-go@v1 | ||||
|         with: | ||||
| @@ -67,9 +101,11 @@ jobs: | ||||
|           key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-test | ||||
|           restore-keys: | | ||||
|             ${{runner.os}}-go- | ||||
|       - name: Print git version | ||||
|         run: git --version | ||||
|       - name: Test code | ||||
|         run: | | ||||
|           go test pkg/integration/clients/*.go | ||||
|           ./scripts/run_integration_tests.sh | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     env: | ||||
| @@ -77,7 +113,7 @@ jobs: | ||||
|       GOARCH: amd64 | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Setup Go | ||||
|         uses: actions/setup-go@v1 | ||||
|         with: | ||||
| @@ -113,7 +149,7 @@ jobs: | ||||
|       GOARCH: amd64 | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Setup Go | ||||
|         uses: actions/setup-go@v1 | ||||
|         with: | ||||
| @@ -147,7 +183,7 @@ jobs: | ||||
|       GOFLAGS: -mod=vendor | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - name: Setup Go | ||||
|         uses: actions/setup-go@v1 | ||||
|         with: | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/sponsors.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/sponsors.yml
									
									
									
									
										vendored
									
									
								
							| @@ -9,7 +9,7 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout 🛎️ | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|  | ||||
|       - name: Generate Sponsors 💖 | ||||
|         uses: JamesIves/github-sponsors-readme-action@v1.0.8 | ||||
|   | ||||
| @@ -221,7 +221,7 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s | ||||
|  | ||||
| func (self *PatchCommands) MovePatchIntoIndex(commits []*models.Commit, commitIdx int, stash bool) error { | ||||
| 	if stash { | ||||
| 		if err := self.stash.Save(self.Tr.StashPrefix + commits[commitIdx].Sha); err != nil { | ||||
| 		if err := self.stash.Push(self.Tr.StashPrefix + commits[commitIdx].Sha); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -52,9 +52,9 @@ func (self *StashCommands) Apply(index int) error { | ||||
| 	return self.cmd.New(cmdArgs).Run() | ||||
| } | ||||
|  | ||||
| // Save save stash | ||||
| func (self *StashCommands) Save(message string) error { | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("save", message). | ||||
| // Push push stash | ||||
| func (self *StashCommands) Push(message string) error { | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("push", "-m", message). | ||||
| 		ToArgv() | ||||
|  | ||||
| 	return self.cmd.New(cmdArgs).Run() | ||||
| @@ -63,8 +63,9 @@ func (self *StashCommands) Save(message string) error { | ||||
| func (self *StashCommands) Store(sha string, message string) error { | ||||
| 	trimmedMessage := strings.Trim(message, " \t") | ||||
|  | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("store", sha). | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("store"). | ||||
| 		ArgIf(trimmedMessage != "", "-m", trimmedMessage). | ||||
| 		Arg(sha). | ||||
| 		ToArgv() | ||||
|  | ||||
| 	return self.cmd.New(cmdArgs).Run() | ||||
| @@ -93,7 +94,7 @@ func (self *StashCommands) ShowStashEntryCmdObj(index int, ignoreWhitespace bool | ||||
| } | ||||
|  | ||||
| func (self *StashCommands) StashAndKeepIndex(message string) error { | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("save", message, "--keep-index"). | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("push", "--keep-index", "-m", message). | ||||
| 		ToArgv() | ||||
|  | ||||
| 	return self.cmd.New(cmdArgs).Run() | ||||
| @@ -107,7 +108,7 @@ func (self *StashCommands) StashUnstagedChanges(message string) error { | ||||
| 	).Run(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err := self.Save(message); err != nil { | ||||
| 	if err := self.Push(message); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -129,7 +130,7 @@ func (self *StashCommands) SaveStagedChanges(message string) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := self.Save(message); err != nil { | ||||
| 	if err := self.Push(message); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -171,7 +172,7 @@ func (self *StashCommands) SaveStagedChanges(message string) error { | ||||
|  | ||||
| func (self *StashCommands) StashIncludeUntrackedChanges(message string) error { | ||||
| 	return self.cmd.New( | ||||
| 		NewGitCmd("stash").Arg("save", message, "--include-untracked"). | ||||
| 		NewGitCmd("stash").Arg("push", "--include-untracked", "-m", message). | ||||
| 			ToArgv(), | ||||
| 	).Run() | ||||
| } | ||||
|   | ||||
| @@ -37,10 +37,10 @@ func TestStashPop(t *testing.T) { | ||||
|  | ||||
| func TestStashSave(t *testing.T) { | ||||
| 	runner := oscommands.NewFakeRunner(t). | ||||
| 		ExpectGitArgs([]string{"stash", "save", "A stash message"}, "", nil) | ||||
| 		ExpectGitArgs([]string{"stash", "push", "-m", "A stash message"}, "", nil) | ||||
| 	instance := buildStashCommands(commonDeps{runner: runner}) | ||||
|  | ||||
| 	assert.NoError(t, instance.Save("A stash message")) | ||||
| 	assert.NoError(t, instance.Push("A stash message")) | ||||
| 	runner.CheckForMissingCalls() | ||||
| } | ||||
|  | ||||
| @@ -57,7 +57,7 @@ func TestStashStore(t *testing.T) { | ||||
| 			testName: "Non-empty message", | ||||
| 			sha:      "0123456789abcdef", | ||||
| 			message:  "New stash name", | ||||
| 			expected: []string{"stash", "store", "0123456789abcdef", "-m", "New stash name"}, | ||||
| 			expected: []string{"stash", "store", "-m", "New stash name", "0123456789abcdef"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			testName: "Empty message", | ||||
| @@ -162,7 +162,7 @@ func TestStashRename(t *testing.T) { | ||||
| 			expectedShaCmd:   []string{"rev-parse", "refs/stash@{3}"}, | ||||
| 			shaResult:        "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd\n", | ||||
| 			expectedDropCmd:  []string{"stash", "drop", "stash@{3}"}, | ||||
| 			expectedStoreCmd: []string{"stash", "store", "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd", "-m", "New message"}, | ||||
| 			expectedStoreCmd: []string{"stash", "store", "-m", "New message", "f0d0f20f2f61ffd6d6bfe0752deffa38845a3edd"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			testName:         "Empty message", | ||||
|   | ||||
| @@ -697,7 +697,7 @@ func (self *FilesController) createStashMenu() error { | ||||
| 					if !self.c.Helpers().WorkingTree.IsWorkingTreeDirty() { | ||||
| 						return self.c.ErrorMsg(self.c.Tr.NoFilesToStash) | ||||
| 					} | ||||
| 					return self.handleStashSave(self.c.Git().Stash.Save, self.c.Tr.Actions.StashAllChanges) | ||||
| 					return self.handleStashSave(self.c.Git().Stash.Push, self.c.Tr.Actions.StashAllChanges) | ||||
| 				}, | ||||
| 				Key: 'a', | ||||
| 			}, | ||||
| @@ -740,7 +740,7 @@ func (self *FilesController) createStashMenu() error { | ||||
| 						return self.handleStashSave(self.c.Git().Stash.StashUnstagedChanges, self.c.Tr.Actions.StashUnstagedChanges) | ||||
| 					} | ||||
| 					// ordinary stash | ||||
| 					return self.handleStashSave(self.c.Git().Stash.Save, self.c.Tr.Actions.StashUnstagedChanges) | ||||
| 					return self.handleStashSave(self.c.Git().Stash.Push, self.c.Tr.Actions.StashUnstagedChanges) | ||||
| 				}, | ||||
| 				Key: 'u', | ||||
| 			}, | ||||
| @@ -749,7 +749,7 @@ func (self *FilesController) createStashMenu() error { | ||||
| } | ||||
|  | ||||
| func (self *FilesController) stash() error { | ||||
| 	return self.handleStashSave(self.c.Git().Stash.Save, self.c.Tr.Actions.StashAllChanges) | ||||
| 	return self.handleStashSave(self.c.Git().Stash.Push, self.c.Tr.Actions.StashAllChanges) | ||||
| } | ||||
|  | ||||
| func (self *FilesController) createResetToUpstreamMenu() error { | ||||
|   | ||||
| @@ -65,7 +65,7 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions | ||||
| 					Title:  self.c.Tr.AutoStashTitle, | ||||
| 					Prompt: self.c.Tr.AutoStashPrompt, | ||||
| 					HandleConfirm: func() error { | ||||
| 						if err := self.c.Git().Stash.Save(self.c.Tr.StashPrefix + ref); err != nil { | ||||
| 						if err := self.c.Git().Stash.Push(self.c.Tr.StashPrefix + ref); err != nil { | ||||
| 							return self.c.Error(err) | ||||
| 						} | ||||
| 						if err := self.c.Git().Branch.Checkout(ref, cmdOptions); err != nil { | ||||
|   | ||||
| @@ -249,7 +249,7 @@ func (self *UndoController) hardResetWithAutoStash(commitSha string, options har | ||||
| 			Prompt: self.c.Tr.AutoStashPrompt, | ||||
| 			HandleConfirm: func() error { | ||||
| 				return self.c.WithWaitingStatus(options.WaitingStatus, func(gocui.Task) error { | ||||
| 					if err := self.c.Git().Stash.Save(self.c.Tr.StashPrefix + commitSha); err != nil { | ||||
| 					if err := self.c.Git().Stash.Push(self.c.Tr.StashPrefix + commitSha); err != nil { | ||||
| 						return self.c.Error(err) | ||||
| 					} | ||||
| 					if err := reset(); err != nil { | ||||
|   | ||||
| @@ -141,7 +141,7 @@ func buildLazygit() error { | ||||
|  | ||||
| func createFixture(test *IntegrationTest, paths Paths, rootDir string) error { | ||||
| 	shell := NewShell(paths.ActualRepo(), func(errorMsg string) { panic(errorMsg) }) | ||||
| 	shell.Init("master") | ||||
| 	shell.Init() | ||||
|  | ||||
| 	os.Setenv(GIT_CONFIG_GLOBAL_ENV_VAR, globalGitConfigPath(rootDir)) | ||||
|  | ||||
|   | ||||
| @@ -196,11 +196,6 @@ func (self *Shell) CreateNCommitsStartingAt(n, startIndex int) *Shell { | ||||
| 	return self | ||||
| } | ||||
|  | ||||
| func (self *Shell) StashWithMessage(message string) *Shell { | ||||
| 	self.RunCommand([]string{"git", "stash", "-m", message}) | ||||
| 	return self | ||||
| } | ||||
|  | ||||
| func (self *Shell) SetConfig(key string, value string) *Shell { | ||||
| 	self.RunCommand([]string{"git", "config", "--local", key, value}) | ||||
| 	return self | ||||
| @@ -245,7 +240,7 @@ func (self *Shell) HardReset(ref string) *Shell { | ||||
| } | ||||
|  | ||||
| func (self *Shell) Stash(message string) *Shell { | ||||
| 	self.RunCommand([]string{"git", "stash", "-m", message}) | ||||
| 	self.RunCommand([]string{"git", "stash", "push", "-m", message}) | ||||
| 	return self | ||||
| } | ||||
|  | ||||
| @@ -254,8 +249,8 @@ func (self *Shell) StartBisect(good string, bad string) *Shell { | ||||
| 	return self | ||||
| } | ||||
|  | ||||
| func (self *Shell) Init(mainBranch string) *Shell { | ||||
| 	self.RunCommand([]string{"git", "init", "-b", mainBranch}) | ||||
| func (self *Shell) Init() *Shell { | ||||
| 	self.RunCommand([]string{"git", "-c", "init.defaultBranch=master", "init"}) | ||||
| 	return self | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -55,8 +55,7 @@ var ApplyInReverseWithConflict = NewIntegrationTest(NewIntegrationTestArgs{ | ||||
|  | ||||
| 		t.ExpectPopup().Alert(). | ||||
| 			Title(Equals("Error")). | ||||
| 			Content(Contains("Applied patch to 'file1' with conflicts."). | ||||
| 				Contains("Applied patch to 'file2' cleanly.")). | ||||
| 			Content(Contains("Applied patch to 'file1' with conflicts.")). | ||||
| 			Confirm() | ||||
|  | ||||
| 		t.Views().Files(). | ||||
|   | ||||
| @@ -14,9 +14,9 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ | ||||
| 		shell. | ||||
| 			EmptyCommit("blah"). | ||||
| 			CreateFileAndAdd("file-1", "change to stash1"). | ||||
| 			StashWithMessage("foo"). | ||||
| 			Stash("foo"). | ||||
| 			CreateFileAndAdd("file-2", "change to stash2"). | ||||
| 			StashWithMessage("bar") | ||||
| 			Stash("bar") | ||||
| 	}, | ||||
| 	Run: func(t *TestDriver, keys config.KeybindingConfig) { | ||||
| 		t.Views().Stash(). | ||||
|   | ||||
| @@ -15,14 +15,16 @@ var PullRebase = NewIntegrationTest(NewIntegrationTestArgs{ | ||||
| 		shell.Commit("one") | ||||
| 		shell.UpdateFileAndAdd("file", "content2") | ||||
| 		shell.Commit("two") | ||||
| 		shell.EmptyCommit("three") | ||||
| 		shell.CreateFileAndAdd("file3", "content3") | ||||
| 		shell.Commit("three") | ||||
|  | ||||
| 		shell.CloneIntoRemote("origin") | ||||
|  | ||||
| 		shell.SetBranchUpstream("master", "origin/master") | ||||
|  | ||||
| 		shell.HardReset("HEAD^^") | ||||
| 		shell.EmptyCommit("four") | ||||
| 		shell.CreateFileAndAdd("file4", "content4") | ||||
| 		shell.Commit("four") | ||||
|  | ||||
| 		shell.SetConfig("pull.rebase", "true") | ||||
| 	}, | ||||
|   | ||||
| @@ -15,7 +15,8 @@ var PullRebaseInteractiveConflict = NewIntegrationTest(NewIntegrationTestArgs{ | ||||
| 		shell.Commit("one") | ||||
| 		shell.UpdateFileAndAdd("file", "content2") | ||||
| 		shell.Commit("two") | ||||
| 		shell.EmptyCommit("three") | ||||
| 		shell.CreateFileAndAdd("file3", "content3") | ||||
| 		shell.Commit("three") | ||||
|  | ||||
| 		shell.CloneIntoRemote("origin") | ||||
|  | ||||
| @@ -24,7 +25,8 @@ var PullRebaseInteractiveConflict = NewIntegrationTest(NewIntegrationTestArgs{ | ||||
| 		shell.HardReset("HEAD^^") | ||||
| 		shell.UpdateFileAndAdd("file", "content4") | ||||
| 		shell.Commit("four") | ||||
| 		shell.EmptyCommit("five") | ||||
| 		shell.CreateFileAndAdd("file5", "content5") | ||||
| 		shell.Commit("five") | ||||
|  | ||||
| 		shell.SetConfig("pull.rebase", "interactive") | ||||
| 	}, | ||||
|   | ||||
| @@ -15,7 +15,8 @@ var PullRebaseInteractiveConflictDrop = NewIntegrationTest(NewIntegrationTestArg | ||||
| 		shell.Commit("one") | ||||
| 		shell.UpdateFileAndAdd("file", "content2") | ||||
| 		shell.Commit("two") | ||||
| 		shell.EmptyCommit("three") | ||||
| 		shell.CreateFileAndAdd("file3", "content3") | ||||
| 		shell.Commit("three") | ||||
|  | ||||
| 		shell.CloneIntoRemote("origin") | ||||
|  | ||||
| @@ -24,7 +25,8 @@ var PullRebaseInteractiveConflictDrop = NewIntegrationTest(NewIntegrationTestArg | ||||
| 		shell.HardReset("HEAD^^") | ||||
| 		shell.UpdateFileAndAdd("file", "content4") | ||||
| 		shell.Commit("four") | ||||
| 		shell.EmptyCommit("five") | ||||
| 		shell.CreateFileAndAdd("fil5", "content5") | ||||
| 		shell.Commit("five") | ||||
|  | ||||
| 		shell.SetConfig("pull.rebase", "interactive") | ||||
| 	}, | ||||
|   | ||||
							
								
								
									
										20
									
								
								scripts/run_integration_tests.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								scripts/run_integration_tests.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| # This is ugly, but older versions of git don't support the GIT_CONFIG_GLOBAL | ||||
| # env var; the only way to run tests for these old versions is to copy our test | ||||
| # config file to the actual global location. Move an existing file out of the | ||||
| # way so that we can restore it at the end. | ||||
| if test -f ~/.gitconfig; then | ||||
|   mv ~/.gitconfig ~/.gitconfig.lazygit.bak | ||||
| fi | ||||
|  | ||||
| cp test/global_git_config ~/.gitconfig | ||||
|  | ||||
| go test pkg/integration/clients/*.go | ||||
| EXITCODE=$? | ||||
|  | ||||
| if test -f ~/.gitconfig.lazygit.bak; then | ||||
|   mv ~/.gitconfig.lazygit.bak ~/.gitconfig | ||||
| fi | ||||
|  | ||||
| exit $EXITCODE | ||||
		Reference in New Issue
	
	Block a user