mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-15 11:56:37 +02:00
In practice, using path seems to work too, since Windows seems to be capable of dealing with a path like C:/x/y instead of C:\x\y; but it's cleaner to do this properly.
228 lines
7.0 KiB
Go
228 lines
7.0 KiB
Go
package git_commands
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/go-errors/errors"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
|
"github.com/samber/lo"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type (
|
|
argFn func() []string
|
|
errFn func(getRevParseArgs argFn) error
|
|
)
|
|
|
|
type Scenario struct {
|
|
Name string
|
|
BeforeFunc func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn)
|
|
Path string
|
|
Expected *RepoPaths
|
|
Err errFn
|
|
}
|
|
|
|
func TestGetRepoPaths(t *testing.T) {
|
|
scenarios := []Scenario{
|
|
{
|
|
Name: "typical case",
|
|
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
|
// setup for main worktree
|
|
mockOutput := lo.Ternary(runtime.GOOS == "windows", []string{
|
|
// --show-toplevel
|
|
`C:\path\to\repo`,
|
|
// --git-dir
|
|
`C:\path\to\repo\.git`,
|
|
// --git-common-dir
|
|
`C:\path\to\repo\.git`,
|
|
// --is-bare-repository
|
|
"false",
|
|
// --show-superproject-working-tree
|
|
}, []string{
|
|
// --show-toplevel
|
|
"/path/to/repo",
|
|
// --git-dir
|
|
"/path/to/repo/.git",
|
|
// --git-common-dir
|
|
"/path/to/repo/.git",
|
|
// --is-bare-repository
|
|
"false",
|
|
// --show-superproject-working-tree
|
|
})
|
|
runner.ExpectGitArgs(
|
|
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
|
strings.Join(mockOutput, "\n"),
|
|
nil)
|
|
},
|
|
Path: "/path/to/repo",
|
|
Expected: lo.Ternary(runtime.GOOS == "windows", &RepoPaths{
|
|
worktreePath: `C:\path\to\repo`,
|
|
worktreeGitDirPath: `C:\path\to\repo\.git`,
|
|
repoPath: `C:\path\to\repo`,
|
|
repoGitDirPath: `C:\path\to\repo\.git`,
|
|
repoName: `repo`,
|
|
isBareRepo: false,
|
|
}, &RepoPaths{
|
|
worktreePath: "/path/to/repo",
|
|
worktreeGitDirPath: "/path/to/repo/.git",
|
|
repoPath: "/path/to/repo",
|
|
repoGitDirPath: "/path/to/repo/.git",
|
|
repoName: "repo",
|
|
isBareRepo: false,
|
|
}),
|
|
Err: nil,
|
|
},
|
|
{
|
|
Name: "bare repo",
|
|
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
|
// setup for main worktree
|
|
mockOutput := lo.Ternary(runtime.GOOS == "windows", []string{
|
|
// --show-toplevel
|
|
`C:\path\to\repo`,
|
|
// --git-dir
|
|
`C:\path\to\bare_repo\bare.git`,
|
|
// --git-common-dir
|
|
`C:\path\to\bare_repo\bare.git`,
|
|
// --is-bare-repository
|
|
`true`,
|
|
// --show-superproject-working-tree
|
|
}, []string{
|
|
// --show-toplevel
|
|
"/path/to/repo",
|
|
// --git-dir
|
|
"/path/to/bare_repo/bare.git",
|
|
// --git-common-dir
|
|
"/path/to/bare_repo/bare.git",
|
|
// --is-bare-repository
|
|
"true",
|
|
// --show-superproject-working-tree
|
|
})
|
|
runner.ExpectGitArgs(
|
|
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
|
strings.Join(mockOutput, "\n"),
|
|
nil)
|
|
},
|
|
Path: "/path/to/repo",
|
|
Expected: lo.Ternary(runtime.GOOS == "windows", &RepoPaths{
|
|
worktreePath: `C:\path\to\repo`,
|
|
worktreeGitDirPath: `C:\path\to\bare_repo\bare.git`,
|
|
repoPath: `C:\path\to\bare_repo`,
|
|
repoGitDirPath: `C:\path\to\bare_repo\bare.git`,
|
|
repoName: `bare_repo`,
|
|
isBareRepo: true,
|
|
}, &RepoPaths{
|
|
worktreePath: "/path/to/repo",
|
|
worktreeGitDirPath: "/path/to/bare_repo/bare.git",
|
|
repoPath: "/path/to/bare_repo",
|
|
repoGitDirPath: "/path/to/bare_repo/bare.git",
|
|
repoName: "bare_repo",
|
|
isBareRepo: true,
|
|
}),
|
|
Err: nil,
|
|
},
|
|
{
|
|
Name: "submodule",
|
|
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
|
mockOutput := lo.Ternary(runtime.GOOS == "windows", []string{
|
|
// --show-toplevel
|
|
`C:\path\to\repo\submodule1`,
|
|
// --git-dir
|
|
`C:\path\to\repo\.git\modules\submodule1`,
|
|
// --git-common-dir
|
|
`C:\path\to\repo\.git\modules\submodule1`,
|
|
// --is-bare-repository
|
|
`false`,
|
|
// --show-superproject-working-tree
|
|
`C:\path\to\repo`,
|
|
}, []string{
|
|
// --show-toplevel
|
|
"/path/to/repo/submodule1",
|
|
// --git-dir
|
|
"/path/to/repo/.git/modules/submodule1",
|
|
// --git-common-dir
|
|
"/path/to/repo/.git/modules/submodule1",
|
|
// --is-bare-repository
|
|
"false",
|
|
// --show-superproject-working-tree
|
|
"/path/to/repo",
|
|
})
|
|
runner.ExpectGitArgs(
|
|
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
|
strings.Join(mockOutput, "\n"),
|
|
nil)
|
|
},
|
|
Path: "/path/to/repo/submodule1",
|
|
Expected: lo.Ternary(runtime.GOOS == "windows", &RepoPaths{
|
|
worktreePath: `C:\path\to\repo\submodule1`,
|
|
worktreeGitDirPath: `C:\path\to\repo\.git\modules\submodule1`,
|
|
repoPath: `C:\path\to\repo\submodule1`,
|
|
repoGitDirPath: `C:\path\to\repo\.git\modules\submodule1`,
|
|
repoName: `submodule1`,
|
|
isBareRepo: false,
|
|
}, &RepoPaths{
|
|
worktreePath: "/path/to/repo/submodule1",
|
|
worktreeGitDirPath: "/path/to/repo/.git/modules/submodule1",
|
|
repoPath: "/path/to/repo/submodule1",
|
|
repoGitDirPath: "/path/to/repo/.git/modules/submodule1",
|
|
repoName: "submodule1",
|
|
isBareRepo: false,
|
|
}),
|
|
Err: nil,
|
|
},
|
|
{
|
|
Name: "git rev-parse returns an error",
|
|
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
|
runner.ExpectGitArgs(
|
|
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
|
"",
|
|
errors.New("fatal: invalid gitfile format: /path/to/repo/worktree2/.git"))
|
|
},
|
|
Path: "/path/to/repo/worktree2",
|
|
Expected: nil,
|
|
Err: func(getRevParseArgs argFn) error {
|
|
args := strings.Join(getRevParseArgs(), " ")
|
|
return errors.New(
|
|
fmt.Sprintf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --is-bare-repository --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args),
|
|
)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, s := range scenarios {
|
|
t.Run(s.Name, func(t *testing.T) {
|
|
runner := oscommands.NewFakeRunner(t)
|
|
cmd := oscommands.NewDummyCmdObjBuilder(runner)
|
|
|
|
version, err := GetGitVersion(oscommands.NewDummyOSCommand())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
getRevParseArgs := func() []string {
|
|
args := []string{"rev-parse"}
|
|
if version.IsAtLeast(2, 31, 0) {
|
|
args = append(args, "--path-format=absolute")
|
|
}
|
|
return args
|
|
}
|
|
// prepare the filesystem for the scenario
|
|
s.BeforeFunc(runner, getRevParseArgs)
|
|
|
|
repoPaths, err := GetRepoPathsForDir("", cmd, version)
|
|
|
|
// check the error and the paths
|
|
if s.Err != nil {
|
|
scenarioErr := s.Err(getRevParseArgs)
|
|
assert.Error(t, err)
|
|
assert.EqualError(t, err, scenarioErr.Error())
|
|
} else {
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, s.Expected, repoPaths)
|
|
}
|
|
})
|
|
}
|
|
}
|