mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-30 03:23:08 +03:00
Merge branch 'master' into feature/auto-updates
This commit is contained in:
@ -5,7 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||
@ -53,10 +53,7 @@ func NewApp(config config.AppConfigurer) (*App, error) {
|
||||
return app, err
|
||||
}
|
||||
|
||||
app.Tr, err = i18n.NewLocalizer(app.Log)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
app.Tr = i18n.NewLocalizer(app.Log)
|
||||
|
||||
app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand)
|
||||
if err != nil {
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
gitconfig "github.com/tcnksm/go-gitconfig"
|
||||
@ -223,8 +223,14 @@ func (c *GitCommand) NewBranch(name string) error {
|
||||
}
|
||||
|
||||
// DeleteBranch delete branch
|
||||
func (c *GitCommand) DeleteBranch(branch string) error {
|
||||
return c.OSCommand.RunCommand("git branch -d " + branch)
|
||||
func (c *GitCommand) DeleteBranch(branch string, force bool) error {
|
||||
var command string
|
||||
if force {
|
||||
command = "git branch -D "
|
||||
} else {
|
||||
command = "git branch -d "
|
||||
}
|
||||
return c.OSCommand.RunCommand(command + branch)
|
||||
}
|
||||
|
||||
// ListStash list stash
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/jesseduffield/lazygit/pkg/test"
|
||||
)
|
||||
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/mgutz/str"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
gitconfig "github.com/tcnksm/go-gitconfig"
|
||||
)
|
||||
|
||||
@ -175,7 +175,8 @@ func (c *OSCommand) Unquote(message string) string {
|
||||
return message
|
||||
}
|
||||
|
||||
func (C *OSCommand) AppendLineToFile(filename, line string) error {
|
||||
// AppendLineToFile adds a new line in file
|
||||
func (c *OSCommand) AppendLineToFile(filename, line string) error {
|
||||
f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -121,10 +121,7 @@ func LoadUserConfigFromFile(v *viper.Viper) error {
|
||||
folder = configDirs.QueryFolderContainsFile("config.yml")
|
||||
}
|
||||
v.AddConfigPath(folder.Path)
|
||||
if err := v.MergeInConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return v.MergeInConfig()
|
||||
}
|
||||
|
||||
// InsertToUserConfig adds a key/value pair to the user's config and saves it
|
||||
@ -139,10 +136,7 @@ func (c *AppConfig) InsertToUserConfig(key, value string) error {
|
||||
return err
|
||||
}
|
||||
v.Set(key, value)
|
||||
if err := v.WriteConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return v.WriteConfig()
|
||||
}
|
||||
|
||||
func getDefaultConfig() []byte {
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
)
|
||||
|
@ -62,20 +62,34 @@ func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleDeleteBranch(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.deleteBranch(g, v, false)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleForceDeleteBranch(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.deleteBranch(g, v, true)
|
||||
}
|
||||
|
||||
func (gui *Gui) deleteBranch(g *gocui.Gui, v *gocui.View, force bool) error {
|
||||
checkedOutBranch := gui.State.Branches[0]
|
||||
selectedBranch := gui.getSelectedBranch(v)
|
||||
if checkedOutBranch.Name == selectedBranch.Name {
|
||||
return gui.createErrorPanel(g, gui.Tr.SLocalize("CantDeleteCheckOutBranch"))
|
||||
}
|
||||
title := gui.Tr.SLocalize("DeleteBranch")
|
||||
var messageId string
|
||||
if force {
|
||||
messageId = "ForceDeleteBranchMessage"
|
||||
} else {
|
||||
messageId = "DeleteBranchMessage"
|
||||
}
|
||||
message := gui.Tr.TemplateLocalize(
|
||||
"DeleteBranchMessage",
|
||||
messageId,
|
||||
Teml{
|
||||
"selectedBranchName": selectedBranch.Name,
|
||||
},
|
||||
)
|
||||
title := gui.Tr.SLocalize("DeleteBranch")
|
||||
return gui.createConfirmationPanel(g, v, title, message, func(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := gui.GitCommand.DeleteBranch(selectedBranch.Name); err != nil {
|
||||
if err := gui.GitCommand.DeleteBranch(selectedBranch.Name, force); err != nil {
|
||||
return gui.createErrorPanel(g, err.Error())
|
||||
}
|
||||
return gui.refreshSidePanels(g)
|
||||
@ -108,6 +122,7 @@ func (gui *Gui) renderBranchesOptions(g *gocui.Gui) error {
|
||||
"c": gui.Tr.SLocalize("checkoutByName"),
|
||||
"n": gui.Tr.SLocalize("newBranch"),
|
||||
"d": gui.Tr.SLocalize("deleteBranch"),
|
||||
"D": gui.Tr.SLocalize("forceDeleteBranch"),
|
||||
"← → ↑ ↓": gui.Tr.SLocalize("navigate"),
|
||||
})
|
||||
}
|
||||
|
@ -251,14 +251,6 @@ func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.EditFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) openFile(filename string) error {
|
||||
err := gui.OSCommand.OpenFile(filename)
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
file, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
|
@ -15,13 +15,13 @@ import (
|
||||
|
||||
// "strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/golang-collections/collections/stack"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||
"github.com/jesseduffield/lazygit/pkg/updates"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// OverlappingEdges determines if panel edges overlap
|
||||
@ -152,14 +152,15 @@ func (gui *Gui) setAppStatus(status string) error {
|
||||
func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
g.Highlight = true
|
||||
width, height := g.Size()
|
||||
version := gui.Config.GetVersion()
|
||||
leftSideWidth := width / 3
|
||||
statusFilesBoundary := 2
|
||||
filesBranchesBoundary := 2 * height / 5 // height - 20
|
||||
commitsBranchesBoundary := 3 * height / 5 // height - 10
|
||||
commitsStashBoundary := height - 5 // height - 5
|
||||
optionsVersionBoundary := width - max(len(version), 1)
|
||||
minimumHeight := 16
|
||||
minimumWidth := 10
|
||||
version := gui.Config.GetVersion()
|
||||
|
||||
appStatusView, _ := g.View("appStatus")
|
||||
appStatusOptionsBoundary := -2
|
||||
@ -244,7 +245,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
v.FgColor = gocui.ColorWhite
|
||||
}
|
||||
|
||||
if v, err := g.SetView("options", appStatusOptionsBoundary-1, optionsTop, width-len(version)-2, optionsTop+2, 0); err != nil {
|
||||
if v, err := g.SetView("options", appStatusOptionsBoundary-1, optionsTop, optionsVersionBoundary-1, optionsTop+2, 0); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
@ -281,7 +282,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
v.Frame = false
|
||||
}
|
||||
|
||||
if v, err := g.SetView("version", width-len(version)-1, optionsTop, width, optionsTop+2, 0); err != nil {
|
||||
if v, err := g.SetView("version", optionsVersionBoundary-1, optionsTop, width, optionsTop+2, 0); err != nil {
|
||||
if err != gocui.ErrUnknownView {
|
||||
return err
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
|
||||
bindings := []Binding{
|
||||
{ViewName: "", Key: 'q', Modifier: gocui.ModNone, Handler: gui.quit},
|
||||
{ViewName: "", Key: gocui.KeyCtrlC, Modifier: gocui.ModNone, Handler: gui.quit},
|
||||
{ViewName: "", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.quit},
|
||||
{ViewName: "", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpMain},
|
||||
{ViewName: "", Key: gocui.KeyPgdn, Modifier: gocui.ModNone, Handler: gui.scrollDownMain},
|
||||
{ViewName: "", Key: gocui.KeyCtrlU, Modifier: gocui.ModNone, Handler: gui.scrollUpMain},
|
||||
@ -57,6 +58,7 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
|
||||
{ViewName: "branches", Key: 'F', Modifier: gocui.ModNone, Handler: gui.handleForceCheckout},
|
||||
{ViewName: "branches", Key: 'n', Modifier: gocui.ModNone, Handler: gui.handleNewBranch},
|
||||
{ViewName: "branches", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleDeleteBranch},
|
||||
{ViewName: "branches", Key: 'D', Modifier: gocui.ModNone, Handler: gui.handleForceDeleteBranch},
|
||||
{ViewName: "branches", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleMerge},
|
||||
{ViewName: "commits", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleCommitSquashDown},
|
||||
{ViewName: "commits", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRenameCommit},
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/spkg/bom"
|
||||
)
|
||||
|
||||
var cyclableViews = []string{"status", "files", "branches", "commits", "stash"}
|
||||
@ -224,7 +226,9 @@ func (gui *Gui) renderString(g *gocui.Gui, viewName, s string) error {
|
||||
gui.Log.Info(s)
|
||||
}
|
||||
v.Clear()
|
||||
fmt.Fprint(v, s)
|
||||
output := string(bom.Clean([]byte(s)))
|
||||
output = utils.NormalizeLinefeeds(output)
|
||||
fmt.Fprint(v, output)
|
||||
v.Wrap = true
|
||||
return nil
|
||||
})
|
||||
|
@ -132,7 +132,10 @@ func addDutch(i18nObject *i18n.Bundle) error {
|
||||
Other: "Verwijder branch",
|
||||
}, &i18n.Message{
|
||||
ID: "DeleteBranchMessage",
|
||||
Other: "Weet je zeker dat je {{.selectedBranchName}} branch wil verwijderen?",
|
||||
Other: "Weet je zeker dat je branch {{.selectedBranchName}} wil verwijderen?",
|
||||
}, &i18n.Message{
|
||||
ID: "ForceDeleteBranchMessage",
|
||||
Other: "Weet je zeker dat je branch {{.selectedBranchName}} geforceerd wil verwijderen?",
|
||||
}, &i18n.Message{
|
||||
ID: "CantMergeBranchIntoItself",
|
||||
Other: "Je kan niet een branch in zichzelf mergen",
|
||||
@ -151,6 +154,9 @@ func addDutch(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "deleteBranch",
|
||||
Other: "verwijder branch",
|
||||
}, &i18n.Message{
|
||||
ID: "forceDeleteBranch",
|
||||
Other: "verwijder branch (forceer)",
|
||||
}, &i18n.Message{
|
||||
ID: "NoBranchesThisRepo",
|
||||
Other: "Geen branches voor deze repo",
|
||||
|
@ -140,7 +140,10 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
||||
Other: "Delete Branch",
|
||||
}, &i18n.Message{
|
||||
ID: "DeleteBranchMessage",
|
||||
Other: "Are you sure you want delete the branch {{.selectedBranchName}} ?",
|
||||
Other: "Are you sure you want to delete the branch {{.selectedBranchName}}?",
|
||||
}, &i18n.Message{
|
||||
ID: "ForceDeleteBranchMessage",
|
||||
Other: "Are you sure you want to force delete the branch {{.selectedBranchName}}?",
|
||||
}, &i18n.Message{
|
||||
ID: "CantMergeBranchIntoItself",
|
||||
Other: "You cannot merge a branch into itself",
|
||||
@ -159,6 +162,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "deleteBranch",
|
||||
Other: "delete branch",
|
||||
}, &i18n.Message{
|
||||
ID: "forceDeleteBranch",
|
||||
Other: "delete branch (force)",
|
||||
}, &i18n.Message{
|
||||
ID: "NoBranchesThisRepo",
|
||||
Other: "No branches for this repo",
|
||||
|
@ -1,7 +1,7 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/cloudfoundry/jibber_jabber"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
@ -18,33 +18,12 @@ type Localizer struct {
|
||||
}
|
||||
|
||||
// NewLocalizer creates a new Localizer
|
||||
func NewLocalizer(log *logrus.Logger) (*Localizer, error) {
|
||||
func NewLocalizer(log *logrus.Logger) *Localizer {
|
||||
userLang := detectLanguage(jibber_jabber.DetectLanguage)
|
||||
|
||||
// detect the user's language
|
||||
userLang, err := jibber_jabber.DetectLanguage()
|
||||
if err != nil {
|
||||
if err.Error() != "Could not detect Language" {
|
||||
return nil, err
|
||||
}
|
||||
userLang = "C"
|
||||
}
|
||||
log.Info("language: " + userLang)
|
||||
|
||||
// create a i18n bundle that can be used to add translations and other things
|
||||
i18nBundle := &i18n.Bundle{DefaultLanguage: language.English}
|
||||
|
||||
addBundles(log, i18nBundle)
|
||||
|
||||
// return the new localizer that can be used to translate text
|
||||
i18nLocalizer := i18n.NewLocalizer(i18nBundle, userLang)
|
||||
|
||||
localizer := &Localizer{
|
||||
i18nLocalizer: i18nLocalizer,
|
||||
language: userLang,
|
||||
Log: log,
|
||||
}
|
||||
|
||||
return localizer, nil
|
||||
return setupLocalizer(log, userLang)
|
||||
}
|
||||
|
||||
// Localize handels the translations
|
||||
@ -82,17 +61,42 @@ func (l *Localizer) GetLanguage() string {
|
||||
|
||||
// add translation file(s)
|
||||
func addBundles(log *logrus.Logger, i18nBundle *i18n.Bundle) {
|
||||
err := addPolish(i18nBundle)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = addDutch(i18nBundle)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = addEnglish(i18nBundle)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
fs := []func(*i18n.Bundle) error{
|
||||
addPolish,
|
||||
addDutch,
|
||||
addEnglish,
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
if err := f(i18nBundle); err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// detectLanguage extracts user language from environment
|
||||
func detectLanguage(langDetector func() (string, error)) string {
|
||||
if userLang, err := langDetector(); err == nil {
|
||||
return userLang
|
||||
}
|
||||
|
||||
return "C"
|
||||
}
|
||||
|
||||
// setupLocalizer creates a new localizer using given userLang
|
||||
func setupLocalizer(log *logrus.Logger, userLang string) *Localizer {
|
||||
// create a i18n bundle that can be used to add translations and other things
|
||||
i18nBundle := &i18n.Bundle{DefaultLanguage: language.English}
|
||||
|
||||
addBundles(log, i18nBundle)
|
||||
|
||||
// return the new localizer that can be used to translate text
|
||||
i18nLocalizer := i18n.NewLocalizer(i18nBundle, userLang)
|
||||
|
||||
return &Localizer{
|
||||
i18nLocalizer: i18nLocalizer,
|
||||
language: userLang,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
81
pkg/i18n/i18n_test.go
Normal file
81
pkg/i18n/i18n_test.go
Normal file
@ -0,0 +1,81 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewLocalizer(t *testing.T) {
|
||||
assert.NotNil(t, NewLocalizer(logrus.New()))
|
||||
}
|
||||
|
||||
func TestDetectLanguage(t *testing.T) {
|
||||
type scenario struct {
|
||||
langDetector func() (string, error)
|
||||
expected string
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
func() (string, error) {
|
||||
return "", fmt.Errorf("An error occurred")
|
||||
},
|
||||
"C",
|
||||
},
|
||||
{
|
||||
func() (string, error) {
|
||||
return "en", nil
|
||||
},
|
||||
"en",
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
assert.EqualValues(t, s.expected, detectLanguage(s.langDetector))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalizer(t *testing.T) {
|
||||
type scenario struct {
|
||||
userLang string
|
||||
test func(*Localizer)
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
"C",
|
||||
func(l *Localizer) {
|
||||
assert.EqualValues(t, "C", l.GetLanguage())
|
||||
assert.Equal(t, "Diff", l.Localize(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: "DiffTitle",
|
||||
},
|
||||
}))
|
||||
assert.Equal(t, "Diff", l.SLocalize("DiffTitle"))
|
||||
assert.Equal(t, "Are you sure you want to delete the branch test?", l.TemplateLocalize("DeleteBranchMessage", Teml{"selectedBranchName": "test"}))
|
||||
},
|
||||
},
|
||||
{
|
||||
"nl",
|
||||
func(l *Localizer) {
|
||||
assert.EqualValues(t, "nl", l.GetLanguage())
|
||||
assert.Equal(t, "Diff", l.Localize(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: "DiffTitle",
|
||||
},
|
||||
}))
|
||||
assert.Equal(t, "Diff", l.SLocalize("DiffTitle"))
|
||||
assert.Equal(t, "Weet je zeker dat je branch test wil verwijderen?", l.TemplateLocalize("DeleteBranchMessage", Teml{"selectedBranchName": "test"}))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s.test(setupLocalizer(logrus.New(), s.userLang))
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -11,15 +12,20 @@ import (
|
||||
// GenerateRepo generates a repo from test/repos and changes the directory to be
|
||||
// inside the newly made repo
|
||||
func GenerateRepo(filename string) error {
|
||||
testPath := utils.GetProjectRoot() + "/test/repos/"
|
||||
reposDir := "/test/repos/"
|
||||
testPath := utils.GetProjectRoot() + reposDir
|
||||
|
||||
// workaround for debian packaging
|
||||
if _, err := os.Stat(testPath); os.IsNotExist(err) {
|
||||
cwd, _ := os.Getwd()
|
||||
testPath = filepath.Dir(filepath.Dir(cwd)) + reposDir
|
||||
}
|
||||
if err := os.Chdir(testPath); err != nil {
|
||||
return err
|
||||
}
|
||||
if output, err := exec.Command("bash", filename).CombinedOutput(); err != nil {
|
||||
return errors.New(string(output))
|
||||
}
|
||||
if err := os.Chdir(testPath + "repo"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
return os.Chdir(testPath + "repo")
|
||||
}
|
||||
|
@ -13,10 +13,10 @@ import (
|
||||
|
||||
"github.com/kardianos/osext"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
getter "github.com/jesseduffield/go-getter"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Update checks for updates and does updates
|
||||
|
@ -64,6 +64,13 @@ func TrimTrailingNewline(str string) string {
|
||||
return str
|
||||
}
|
||||
|
||||
// NormalizeLinefeeds - Removes all Windows and Mac style line feeds
|
||||
func NormalizeLinefeeds(str string) string {
|
||||
str = strings.Replace(str, "\r\n", "\n", -1)
|
||||
str = strings.Replace(str, "\r", "", -1)
|
||||
return str
|
||||
}
|
||||
|
||||
// GetProjectRoot returns the path to the root of the project. Only to be used
|
||||
// in testing contexts, as with binaries it's unlikely this path will exist on
|
||||
// the machine
|
||||
|
@ -81,3 +81,36 @@ func TestTrimTrailingNewline(t *testing.T) {
|
||||
assert.EqualValues(t, s.expected, TrimTrailingNewline(s.str))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeLinefeeds(t *testing.T) {
|
||||
type scenario struct {
|
||||
byteArray []byte
|
||||
expected []byte
|
||||
}
|
||||
var scenarios = []scenario{
|
||||
{
|
||||
// \r\n
|
||||
[]byte{97, 115, 100, 102, 13, 10},
|
||||
[]byte{97, 115, 100, 102, 10},
|
||||
},
|
||||
{
|
||||
// bash\r\nblah
|
||||
[]byte{97, 115, 100, 102, 13, 10, 97, 115, 100, 102},
|
||||
[]byte{97, 115, 100, 102, 10, 97, 115, 100, 102},
|
||||
},
|
||||
{
|
||||
// \r
|
||||
[]byte{97, 115, 100, 102, 13},
|
||||
[]byte{97, 115, 100, 102},
|
||||
},
|
||||
{
|
||||
// \n
|
||||
[]byte{97, 115, 100, 102, 10},
|
||||
[]byte{97, 115, 100, 102, 10},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
assert.EqualValues(t, string(s.expected), NormalizeLinefeeds(string(s.byteArray)))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user