mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 15:46:26 -04:00
Compare commits
No commits in common. "master" and "v0.65.0" have entirely different histories.
|
|
@ -120,10 +120,6 @@ separate, reviewable commit that the user decides when to fold in. A bare
|
||||||
`--amend` rewrites the commit on the spot and skips that checkpoint. Don't
|
`--amend` rewrites the commit on the spot and skips that checkpoint. Don't
|
||||||
treat "I'm only touching the tip commit" as an exception.
|
treat "I'm only touching the tip commit" as an exception.
|
||||||
|
|
||||||
Always use `fixup!` or `amend!` commits, never amend changes directly, even if
|
|
||||||
you naturally would because "the branch isn't pushed yet". The user always wants
|
|
||||||
to review what you changed, so make this transparent; no exceptions.
|
|
||||||
|
|
||||||
**When the tip is the wrong place for a fixup, insert it mid-branch.**
|
**When the tip is the wrong place for a fixup, insert it mid-branch.**
|
||||||
Committing a fixup at the tip of the branch only works while the code it
|
Committing a fixup at the tip of the branch only works while the code it
|
||||||
touches still looks the same there; once later commits have rewritten that
|
touches still looks the same there; once later commits have rewritten that
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/generics/maps"
|
"github.com/jesseduffield/generics/maps"
|
||||||
|
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/app"
|
"github.com/jesseduffield/lazygit/pkg/app"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ func CommandToRun() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetKeybindingsDir() string {
|
func GetKeybindingsDir() string {
|
||||||
return utils.MustFindLazygitRootDirectory() + "/docs-master/keybindings"
|
return utils.GetLazyRootDirectory() + "/docs-master/keybindings"
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAtDir(cheatsheetDir string) {
|
func generateAtDir(cheatsheetDir string) {
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ func runAndPrintFatalError(test *components.IntegrationTest, f func() error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestsToRun(testNames []string) []*components.IntegrationTest {
|
func getTestsToRun(testNames []string) []*components.IntegrationTest {
|
||||||
allIntegrationTests := tests.GetTests(utils.MustFindLazygitRootDirectory())
|
allIntegrationTests := tests.GetTests(utils.GetLazyRootDirectory())
|
||||||
var testsToRun []*components.IntegrationTest
|
var testsToRun []*components.IntegrationTest
|
||||||
|
|
||||||
if len(testNames) == 0 {
|
if len(testNames) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/creack/pty"
|
"github.com/creack/pty"
|
||||||
|
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -37,13 +37,8 @@ func TestIntegration(t *testing.T) {
|
||||||
codeCoverageDir := os.Getenv("LAZYGIT_GOCOVERDIR")
|
codeCoverageDir := os.Getenv("LAZYGIT_GOCOVERDIR")
|
||||||
testNumber := 0
|
testNumber := 0
|
||||||
|
|
||||||
rootDir, err := utils.FindLazygitRootDirectory()
|
err := components.RunTests(components.RunTestArgs{
|
||||||
if err != nil {
|
Tests: tests.GetTests(utils.GetLazyRootDirectory()),
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = components.RunTests(components.RunTestArgs{
|
|
||||||
Tests: tests.GetTests(rootDir),
|
|
||||||
Logf: t.Logf,
|
Logf: t.Logf,
|
||||||
RunCmd: runCmdHeadless,
|
RunCmd: runCmdHeadless,
|
||||||
TestWrapper: func(test *components.IntegrationTest, f func() error) {
|
TestWrapper: func(test *components.IntegrationTest, f func() error) {
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,12 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
lazycoreUtils "github.com/jesseduffield/lazycore/pkg/utils"
|
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -24,7 +23,7 @@ import (
|
||||||
var SLOW_INPUT_DELAY = 600
|
var SLOW_INPUT_DELAY = 600
|
||||||
|
|
||||||
func RunTUI(raceDetector bool) {
|
func RunTUI(raceDetector bool) {
|
||||||
rootDir := utils.MustFindLazygitRootDirectory()
|
rootDir := utils.GetLazyRootDirectory()
|
||||||
testDir := filepath.Join(rootDir, "test", "integration")
|
testDir := filepath.Join(rootDir, "test", "integration")
|
||||||
|
|
||||||
app := newApp(testDir)
|
app := newApp(testDir)
|
||||||
|
|
@ -207,7 +206,7 @@ type app struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newApp(testDir string) *app {
|
func newApp(testDir string) *app {
|
||||||
return &app{testDir: testDir, allTests: tests.GetTests(utils.MustFindLazygitRootDirectory())}
|
return &app{testDir: testDir, allTests: tests.GetTests(utils.GetLazyRootDirectory())}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *app) getCurrentTest() *components.IntegrationTest {
|
func (self *app) getCurrentTest() *components.IntegrationTest {
|
||||||
|
|
@ -225,7 +224,7 @@ func (self *app) loadTests() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *app) adjustCursor() {
|
func (self *app) adjustCursor() {
|
||||||
self.itemIdx = lazycoreUtils.Clamp(self.itemIdx, 0, len(self.filteredTests)-1)
|
self.itemIdx = utils.Clamp(self.itemIdx, 0, len(self.filteredTests)-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *app) filterWithString(needle string) {
|
func (self *app) filterWithString(needle string) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
lazycoreUtils "github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
|
|
@ -39,15 +40,12 @@ type RunTestArgs struct {
|
||||||
// showing what's actually happening during the test, but it's still good at running
|
// showing what's actually happening during the test, but it's still good at running
|
||||||
// tests in telling you about their results.
|
// tests in telling you about their results.
|
||||||
func RunTests(args RunTestArgs) error {
|
func RunTests(args RunTestArgs) error {
|
||||||
projectRootDir, err := utils.FindLazygitRootDirectory()
|
projectRootDir := lazycoreUtils.GetLazyRootDirectory()
|
||||||
|
err := os.Chdir(projectRootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Chdir(projectRootDir); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
testDir := filepath.Join(projectRootDir, "test", "_results")
|
testDir := filepath.Join(projectRootDir, "test", "_results")
|
||||||
if err := buildLazygit(args); err != nil {
|
if err := buildLazygit(args); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
lazycoreUtils "github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -227,12 +227,7 @@ func TestFailingFixture(t *testing.T) {
|
||||||
paths := NewPaths(t.TempDir())
|
paths := NewPaths(t.TempDir())
|
||||||
assert.NoError(t, os.MkdirAll(paths.ActualRepo(), 0o777))
|
assert.NoError(t, os.MkdirAll(paths.ActualRepo(), 0o777))
|
||||||
|
|
||||||
rootDir, err := utils.FindLazygitRootDirectory()
|
workingDir, err := createFixture(test, paths, lazycoreUtils.GetLazyRootDirectory())
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
workingDir, err := createFixture(test, paths, rootDir)
|
|
||||||
|
|
||||||
assert.ErrorContains(t, err, "git checkout no-such-branch")
|
assert.ErrorContains(t, err, "git checkout no-such-branch")
|
||||||
assert.Empty(t, workingDir)
|
assert.Empty(t, workingDir)
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,14 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
"github.com/karimkhaleel/jsonschema"
|
"github.com/karimkhaleel/jsonschema"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetSchemaDir() string {
|
func GetSchemaDir() string {
|
||||||
return utils.MustFindLazygitRootDirectory() + "/schema-master"
|
return utils.GetLazyRootDirectory() + "/schema-master"
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateSchema() *jsonschema.Schema {
|
func GenerateSchema() *jsonschema.Schema {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||||
"github.com/karimkhaleel/jsonschema"
|
"github.com/karimkhaleel/jsonschema"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@ func (n *Node) MarshalYAML() (any, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeToConfigDocs(config []byte) error {
|
func writeToConfigDocs(config []byte) error {
|
||||||
configPath := utils.MustFindLazygitRootDirectory() + "/docs-master/Config.md"
|
configPath := utils.GetLazyRootDirectory() + "/docs-master/Config.md"
|
||||||
markdown, err := os.ReadFile(configPath)
|
markdown, err := os.ReadFile(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error reading Config.md file %w", err)
|
return fmt.Errorf("Error reading Config.md file %w", err)
|
||||||
|
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/samber/lo"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FindLazygitRootDirectory returns the root directory of the lazygit source
|
|
||||||
// tree, by searching the working directory and its parents for the go.mod file
|
|
||||||
// that declares lazygit's module. Only development tools use it: the
|
|
||||||
// integration test runner, the cheatsheet generator, and the JSON schema
|
|
||||||
// generator. Not to be confused with finding the root directory of the
|
|
||||||
// repository that lazygit is being run in.
|
|
||||||
//
|
|
||||||
// We search upwards rather than expect to be called from the root directory,
|
|
||||||
// because `go test` runs each test binary in the source directory of its
|
|
||||||
// package, not in the directory that `go test` was invoked from.
|
|
||||||
func FindLazygitRootDirectory() (string, error) {
|
|
||||||
startDir, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := startDir
|
|
||||||
for {
|
|
||||||
if declaresLazygitModule(filepath.Join(dir, "go.mod")) {
|
|
||||||
return dir, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
parent := filepath.Dir(dir)
|
|
||||||
if parent == dir {
|
|
||||||
return "", fmt.Errorf(
|
|
||||||
"failed to find the lazygit root directory: there is no go.mod for a lazygit module in %s or any of its parent directories",
|
|
||||||
startDir)
|
|
||||||
}
|
|
||||||
dir = parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustFindLazygitRootDirectory is FindLazygitRootDirectory for tools that can't
|
|
||||||
// do anything useful if the directory isn't found.
|
|
||||||
func MustFindLazygitRootDirectory() string {
|
|
||||||
dir, err := FindLazygitRootDirectory()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return dir
|
|
||||||
}
|
|
||||||
|
|
||||||
// A fork is free to rename the module, so we accept any module path with a
|
|
||||||
// "lazygit" element in it, e.g. github.com/jesseduffield/lazygit.
|
|
||||||
func declaresLazygitModule(goModPath string) bool {
|
|
||||||
contents, err := os.ReadFile(goModPath)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return lo.SomeBy(strings.Split(string(contents), "\n"), func(line string) bool {
|
|
||||||
fields := strings.Fields(line)
|
|
||||||
return len(fields) >= 2 && fields[0] == "module" &&
|
|
||||||
slices.Contains(strings.Split(fields[1], "/"), "lazygit")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFindLazygitRootDirectory(t *testing.T) {
|
|
||||||
// This test runs in the pkg/utils directory, so we expect the function to
|
|
||||||
// search two levels up for the project root.
|
|
||||||
expectedRootDir, err := filepath.Abs(filepath.Join("..", ".."))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
rootDir, err := FindLazygitRootDirectory()
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, expectedRootDir, rootDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFindLazygitRootDirectoryOutsideProject(t *testing.T) {
|
|
||||||
t.Chdir(t.TempDir())
|
|
||||||
|
|
||||||
_, err := FindLazygitRootDirectory()
|
|
||||||
|
|
||||||
assert.ErrorContains(t, err, "there is no go.mod for a lazygit module")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeclaresLazygitModule(t *testing.T) {
|
|
||||||
scenarios := []struct {
|
|
||||||
testName string
|
|
||||||
contents string
|
|
||||||
expected bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
testName: "lazygit's go.mod",
|
|
||||||
contents: "module github.com/jesseduffield/lazygit\n\ngo 1.25.0\n",
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
testName: "a fork's go.mod",
|
|
||||||
contents: "module gitlab.com/somebody-else/lazygit\n\ngo 1.25.0\n",
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
testName: "a fork's go.mod with a major version suffix",
|
|
||||||
contents: "module github.com/somebody-else/lazygit/v2\n\ngo 1.25.0\n",
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
testName: "module declaration preceded by a comment",
|
|
||||||
contents: "// a comment\n\nmodule github.com/jesseduffield/lazygit\n",
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
testName: "module declaration followed by a comment",
|
|
||||||
contents: "module github.com/jesseduffield/lazygit // comment\n\ngo 1.25.0\n",
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
testName: "another project's go.mod",
|
|
||||||
contents: "module github.com/jesseduffield/lazydocker\n\ngo 1.25.0\n",
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
testName: "no module declaration",
|
|
||||||
contents: "go 1.25.0\n",
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, scenario := range scenarios {
|
|
||||||
t.Run(scenario.testName, func(t *testing.T) {
|
|
||||||
path := filepath.Join(t.TempDir(), "go.mod")
|
|
||||||
assert.NoError(t, os.WriteFile(path, []byte(scenario.contents), 0o644))
|
|
||||||
|
|
||||||
assert.Equal(t, scenario.expected, declaresLazygitModule(path))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeclaresLazygitModuleWithoutAGoModFile(t *testing.T) {
|
|
||||||
assert.False(t, declaresLazygitModule(filepath.Join(t.TempDir(), "go.mod")))
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue