mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-11-30 09:16:47 +02:00
feat: add GitVersion
struct
This commit is contained in:
parent
41222f07ed
commit
cd9111837e
@ -7,8 +7,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
@ -100,52 +98,36 @@ func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) {
|
||||
return app, err
|
||||
}
|
||||
|
||||
gitVersion, err := app.validateGitVersion()
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
showRecentRepos, err := app.setupRepo()
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
app.Gui, err = gui.NewGui(common, config, app.Updater, showRecentRepos, dirName)
|
||||
app.Gui, err = gui.NewGui(common, config, gitVersion, app.Updater, showRecentRepos, dirName)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (app *App) validateGitVersion() error {
|
||||
output, err := app.OSCommand.Cmd.New("git --version").RunWithOutput()
|
||||
func (app *App) validateGitVersion() (*git_commands.GitVersion, error) {
|
||||
version, err := git_commands.GetGitVersion(app.OSCommand)
|
||||
// if we get an error anywhere here we'll show the same status
|
||||
minVersionError := errors.New(app.Tr.MinGitVersionError)
|
||||
if err != nil {
|
||||
return minVersionError
|
||||
return nil, minVersionError
|
||||
}
|
||||
|
||||
if isGitVersionValid(output) {
|
||||
return nil
|
||||
if version.IsOlderThan(2, 0, 0) {
|
||||
return nil, minVersionError
|
||||
}
|
||||
|
||||
return minVersionError
|
||||
}
|
||||
|
||||
func isGitVersionValid(versionStr string) bool {
|
||||
// output should be something like: 'git version 2.23.0 (blah)'
|
||||
re := regexp.MustCompile(`[^\d]+([\d\.]+)`)
|
||||
matches := re.FindStringSubmatch(versionStr)
|
||||
|
||||
if len(matches) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
gitVersion := matches[1]
|
||||
majorVersion, err := strconv.Atoi(gitVersion[0:1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if majorVersion < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return version, nil
|
||||
}
|
||||
|
||||
func isDirectoryAGitRepository(dir string) (bool, error) {
|
||||
@ -166,10 +148,6 @@ func openRecentRepo(app *App) bool {
|
||||
}
|
||||
|
||||
func (app *App) setupRepo() (bool, error) {
|
||||
if err := app.validateGitVersion(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if env.GetGitDirEnv() != "" {
|
||||
// we've been given the git dir directly. We'll verify this dir when initializing our Git object
|
||||
return false, nil
|
||||
|
@ -1,45 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsGitVersionValid(t *testing.T) {
|
||||
type scenario struct {
|
||||
versionStr string
|
||||
expectedResult bool
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
"",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"git version 1.9.0",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"git version 1.9.0 (Apple Git-128)",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"git version 2.4.0",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"git version 2.24.3 (Apple Git-128)",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s := s
|
||||
t.Run(s.versionStr, func(t *testing.T) {
|
||||
result := isGitVersionValid(s.versionStr)
|
||||
assert.Equal(t, result, s.expectedResult)
|
||||
})
|
||||
}
|
||||
}
|
@ -53,6 +53,7 @@ type Loaders struct {
|
||||
|
||||
func NewGitCommand(
|
||||
cmn *common.Common,
|
||||
version *git_commands.GitVersion,
|
||||
osCommand *oscommands.OSCommand,
|
||||
gitConfig git_config.IGitConfig,
|
||||
syncMutex *deadlock.Mutex,
|
||||
@ -73,6 +74,7 @@ func NewGitCommand(
|
||||
|
||||
return NewGitCommandAux(
|
||||
cmn,
|
||||
version,
|
||||
osCommand,
|
||||
gitConfig,
|
||||
dotGitDir,
|
||||
@ -83,6 +85,7 @@ func NewGitCommand(
|
||||
|
||||
func NewGitCommandAux(
|
||||
cmn *common.Common,
|
||||
version *git_commands.GitVersion,
|
||||
osCommand *oscommands.OSCommand,
|
||||
gitConfig git_config.IGitConfig,
|
||||
dotGitDir string,
|
||||
@ -100,7 +103,7 @@ func NewGitCommandAux(
|
||||
|
||||
fileLoader := git_commands.NewFileLoader(cmn, cmd, configCommands)
|
||||
|
||||
gitCommon := git_commands.NewGitCommon(cmn, cmd, osCommand, dotGitDir, repo, configCommands, syncMutex)
|
||||
gitCommon := git_commands.NewGitCommon(cmn, version, cmd, osCommand, dotGitDir, repo, configCommands, syncMutex)
|
||||
statusCommands := git_commands.NewStatusCommands(gitCommon)
|
||||
flowCommands := git_commands.NewFlowCommands(gitCommon)
|
||||
remoteCommands := git_commands.NewRemoteCommands(gitCommon)
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
type GitCommon struct {
|
||||
*common.Common
|
||||
version *GitVersion
|
||||
cmd oscommands.ICmdObjBuilder
|
||||
os *oscommands.OSCommand
|
||||
dotGitDir string
|
||||
@ -20,6 +21,7 @@ type GitCommon struct {
|
||||
|
||||
func NewGitCommon(
|
||||
cmn *common.Common,
|
||||
version *GitVersion,
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
osCommand *oscommands.OSCommand,
|
||||
dotGitDir string,
|
||||
@ -29,6 +31,7 @@ func NewGitCommon(
|
||||
) *GitCommon {
|
||||
return &GitCommon{
|
||||
Common: cmn,
|
||||
version: version,
|
||||
cmd: cmd,
|
||||
os: osCommand,
|
||||
dotGitDir: dotGitDir,
|
||||
|
67
pkg/commands/git_commands/version.go
Normal file
67
pkg/commands/git_commands/version.go
Normal file
@ -0,0 +1,67 @@
|
||||
package git_commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
)
|
||||
|
||||
type GitVersion struct {
|
||||
Major, Minor, Patch int
|
||||
Additional string
|
||||
}
|
||||
|
||||
func GetGitVersion(osCommand *oscommands.OSCommand) (*GitVersion, error) {
|
||||
versionStr, _, err := osCommand.Cmd.New("git --version").RunWithOutputs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
version, err := ParseGitVersion(versionStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return version, nil
|
||||
}
|
||||
|
||||
func ParseGitVersion(versionStr string) (*GitVersion, error) {
|
||||
// versionStr should be something like:
|
||||
// git version 2.39.0
|
||||
// git version 2.37.1 (Apple Git-137.1)
|
||||
re := regexp.MustCompile(`[^\d]+(\d+)(\.\d+)?(\.\d+)?(.*)`)
|
||||
matches := re.FindStringSubmatch(versionStr)
|
||||
|
||||
if len(matches) < 5 {
|
||||
return nil, errors.New("unexpected git version format: " + versionStr)
|
||||
}
|
||||
|
||||
v := &GitVersion{}
|
||||
var err error
|
||||
|
||||
if v.Major, err = strconv.Atoi(matches[1]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(matches[2]) > 1 {
|
||||
if v.Minor, err = strconv.Atoi(matches[2][1:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(matches[3]) > 1 {
|
||||
if v.Patch, err = strconv.Atoi(matches[3][1:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
v.Additional = strings.Trim(matches[4], " \r\n")
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (v *GitVersion) IsOlderThan(major, minor, patch int) bool {
|
||||
actual := v.Major*1000*1000 + v.Minor*1000 + v.Patch
|
||||
required := major*1000*1000 + minor*1000 + patch
|
||||
return actual < required
|
||||
}
|
47
pkg/commands/git_commands/version_test.go
Normal file
47
pkg/commands/git_commands/version_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package git_commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseGitVersion(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
input string
|
||||
expected GitVersion
|
||||
}{
|
||||
{
|
||||
input: "git version 2.39.0",
|
||||
expected: GitVersion{Major: 2, Minor: 39, Patch: 0, Additional: ""},
|
||||
},
|
||||
{
|
||||
input: "git version 2.37.1 (Apple Git-137.1)",
|
||||
expected: GitVersion{Major: 2, Minor: 37, Patch: 1, Additional: "(Apple Git-137.1)"},
|
||||
},
|
||||
{
|
||||
input: "git version 2.37 (Apple Git-137.1)",
|
||||
expected: GitVersion{Major: 2, Minor: 37, Patch: 0, Additional: "(Apple Git-137.1)"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
actual, err := ParseGitVersion(s.input)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, actual)
|
||||
assert.Equal(t, s.expected.Major, actual.Major)
|
||||
assert.Equal(t, s.expected.Minor, actual.Minor)
|
||||
assert.Equal(t, s.expected.Patch, actual.Patch)
|
||||
assert.Equal(t, s.expected.Additional, actual.Additional)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitVersionIsOlderThan(t *testing.T) {
|
||||
assert.False(t, (&GitVersion{2, 0, 0, ""}).IsOlderThan(1, 99, 99))
|
||||
assert.False(t, (&GitVersion{2, 0, 0, ""}).IsOlderThan(2, 0, 0))
|
||||
assert.False(t, (&GitVersion{2, 1, 0, ""}).IsOlderThan(2, 0, 9))
|
||||
|
||||
assert.True(t, (&GitVersion{2, 0, 1, ""}).IsOlderThan(2, 1, 0))
|
||||
assert.True(t, (&GitVersion{2, 0, 1, ""}).IsOlderThan(3, 0, 0))
|
||||
}
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
gogit "github.com/jesseduffield/go-git/v5"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
@ -218,6 +219,7 @@ func TestNewGitCommand(t *testing.T) {
|
||||
s.setup()
|
||||
s.test(
|
||||
NewGitCommand(utils.NewDummyCommon(),
|
||||
&git_commands.GitVersion{},
|
||||
oscommands.NewDummyOSCommand(),
|
||||
git_config.NewFakeGitConfig(nil),
|
||||
&deadlock.Mutex{},
|
||||
|
@ -1,6 +1,7 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/updates"
|
||||
@ -16,6 +17,6 @@ func NewDummyUpdater() *updates.Updater {
|
||||
|
||||
func NewDummyGui() *Gui {
|
||||
newAppConfig := config.NewDummyAppConfig()
|
||||
dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, NewDummyUpdater(), false, "")
|
||||
dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{}, NewDummyUpdater(), false, "")
|
||||
return dummyGui
|
||||
}
|
||||
|
@ -76,9 +76,10 @@ type Repo string
|
||||
// Gui wraps the gocui Gui object which handles rendering and events
|
||||
type Gui struct {
|
||||
*common.Common
|
||||
g *gocui.Gui
|
||||
git *commands.GitCommand
|
||||
os *oscommands.OSCommand
|
||||
g *gocui.Gui
|
||||
gitVersion *git_commands.GitVersion
|
||||
git *commands.GitCommand
|
||||
os *oscommands.OSCommand
|
||||
|
||||
// this is the state of the GUI for the current repo
|
||||
State *GuiRepoState
|
||||
@ -222,6 +223,7 @@ func (gui *Gui) onNewRepo(startArgs appTypes.StartArgs, reuseState bool) error {
|
||||
var err error
|
||||
gui.git, err = commands.NewGitCommand(
|
||||
gui.Common,
|
||||
gui.gitVersion,
|
||||
gui.os,
|
||||
git_config.NewStdCachedGitConfig(gui.Log),
|
||||
gui.Mutexes.SyncMutex,
|
||||
@ -341,12 +343,14 @@ func initialContext(contextTree *context.ContextTree, startArgs appTypes.StartAr
|
||||
func NewGui(
|
||||
cmn *common.Common,
|
||||
config config.AppConfigurer,
|
||||
gitVersion *git_commands.GitVersion,
|
||||
updater *updates.Updater,
|
||||
showRecentRepos bool,
|
||||
initialDir string,
|
||||
) (*Gui, error) {
|
||||
gui := &Gui{
|
||||
Common: cmn,
|
||||
gitVersion: gitVersion,
|
||||
Config: config,
|
||||
Updater: updater,
|
||||
statusManager: &statusManager{},
|
||||
|
Loading…
Reference in New Issue
Block a user