Compare commits

...
5 Commits
Author SHA1 Message Date
Jesse Duffield 3df0a9f132 update in-app release notes 2020-10-12 09:08:47 +11:00
Jesse Duffield 1e79ab78dd return default config when dealing with read only filesystem rather than create new config file 2020-10-12 08:48:28 +11:00
Jesse Duffield 1e48afeb8f quote config file when editing 2020-10-12 08:47:12 +11:00
Jesse Duffield b8ad1883f5 fix delta 2020-10-12 08:26:31 +11:00
band-a-prend 582fd24d78 Add SSH key passphrase prompt to pull/push from/to remote git repo
This commit resolves issue with absence of ssh key prompting
to pull from or push to remote git repository.

I checked lazygit with this patch for successfully pull from
and push to https://gitweb.gentoo.org/repo/proj/guru.git repository.
While for lazygit-0.23.1 I'm not able to do that.

The check for Passphrase follows the Password because of
more long time before SSH key is prompt in terminal.
Otherwise after timeout "Password" prompt is appears.

Excuse me for google translated i18n dutch lines.

Bug: https://github.com/jesseduffield/lazygit/issues/534

Signed-off-by: band-a-prend <torokhov-s-a@yandex.ru>
2020-10-10 17:58:23 +11:00
12 changed files with 127 additions and 23 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ require (
github.com/imdario/mergo v0.3.11
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4
github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e
github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe
github.com/jesseduffield/yaml v2.1.0+incompatible
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
+2 -2
View File
@@ -63,8 +63,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4 h1:GOQrmaE8i+KEdB8NzAegKYd4tPn/inM0I1uo0NXFerg=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e h1:FYXSJfL6JKWB+1NjGqT5/kYJbMI9oMx+JAI3CcrtLsM=
github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7 h1:K3MGrjmpPtIhfXmKh/zsIF0CdmNKOkjpIwcUfAa/J2A=
github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe h1:qsVhCf2RFyyKIUe/+gJblbCpXMUki9rZrHuEctg6M/E=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jesseduffield/yaml v2.1.0+incompatible h1:HWQJ1gIv2zHKbDYNp0Jwjlj24K8aqpFHnMCynY1EpmE=
+8 -7
View File
@@ -143,18 +143,19 @@ func (c *OSCommand) RunCommandWithOutputLive(command string, output func(string)
return RunCommandWithOutputLiveWrapper(c, command, output)
}
// DetectUnamePass detect a username / password question in a command
// promptUserForCredential is a function that gets executed when this function detect you need to fillin a password
// The promptUserForCredential argument will be "username" or "password" and expects the user's password or username back
// DetectUnamePass detect a username / password / passphrase question in a command
// promptUserForCredential is a function that gets executed when this function detect you need to fillin a password or passphrase
// The promptUserForCredential argument will be "username", "password" or "passphrase" and expects the user's password/passphrase or username back
func (c *OSCommand) DetectUnamePass(command string, promptUserForCredential func(string) string) error {
ttyText := ""
errMessage := c.RunCommandWithOutputLive(command, func(word string) string {
ttyText = ttyText + " " + word
prompts := map[string]string{
`.+'s password:`: "password",
`Password\s*for\s*'.+':`: "password",
`Username\s*for\s*'.+':`: "username",
`.+'s password:`: "password",
`Password\s*for\s*'.+':`: "password",
`Username\s*for\s*'.+':`: "username",
`Enter\s*passphrase\s*for\s*key\s*'.+':`: "passphrase",
}
for pattern, askFor := range prompts {
@@ -254,7 +255,7 @@ func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
return nil, errors.New("No editor defined in $VISUAL, $EDITOR, or git config")
}
splitCmd := str.ToArgv(fmt.Sprintf("%s %s", editor, filename))
splitCmd := str.ToArgv(fmt.Sprintf("%s %s", editor, c.Quote(filename)))
return c.PrepareSubProcess(splitCmd[0], splitCmd[1:]...), nil
}
+22
View File
@@ -227,6 +227,28 @@ func TestOSCommandEditFile(t *testing.T) {
assert.NoError(t, err)
},
},
{
"file/with space",
func(name string, args ...string) *exec.Cmd {
if name == "which" {
return exec.Command("echo")
}
assert.EqualValues(t, "vi", name)
assert.EqualValues(t, "file/with space", args[0])
return nil
},
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
func(cmd *exec.Cmd, err error) {
assert.NoError(t, err)
},
},
}
for _, s := range scenarios {
+4
View File
@@ -4,6 +4,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/OpenPeeDeeP/xdg"
yaml "github.com/jesseduffield/yaml"
@@ -114,6 +115,9 @@ func loadUserConfig(configDir string, base *UserConfig) (*UserConfig, error) {
if os.IsNotExist(err) {
file, err := os.Create(fileName)
if err != nil {
if strings.Contains(err.Error(), "read-only file system") {
return base, nil
}
return nil, err
}
file.Close()
+8 -5
View File
@@ -9,7 +9,7 @@ import (
type credentials chan string
// promptUserForCredential wait for a username or password input from the credentials popup
// promptUserForCredential wait for a username, password or passphrase input from the credentials popup
func (gui *Gui) promptUserForCredential(passOrUname string) string {
gui.credentials = make(chan string)
gui.g.Update(func(g *gocui.Gui) error {
@@ -17,9 +17,12 @@ func (gui *Gui) promptUserForCredential(passOrUname string) string {
if passOrUname == "username" {
credentialsView.Title = gui.Tr.CredentialsUsername
credentialsView.Mask = 0
} else {
} else if passOrUname == "password" {
credentialsView.Title = gui.Tr.CredentialsPassword
credentialsView.Mask = '*'
} else {
credentialsView.Title = gui.Tr.CredentialsPassphrase
credentialsView.Mask = '*'
}
if err := gui.switchContext(gui.Contexts.Credentials.Context); err != nil {
@@ -30,7 +33,7 @@ func (gui *Gui) promptUserForCredential(passOrUname string) string {
return nil
})
// wait for username/passwords input
// wait for username/passwords/passphrase input
userInput := <-gui.credentials
return userInput + "\n"
}
@@ -70,10 +73,10 @@ func (gui *Gui) handleCredentialsViewFocused() error {
func (gui *Gui) handleCredentialsPopup(cmdErr error) {
if cmdErr != nil {
errMessage := cmdErr.Error()
if strings.Contains(errMessage, "Invalid username or password") {
if strings.Contains(errMessage, "Invalid username, password or passphrase") {
errMessage = gui.Tr.PassUnameWrong
}
// we are not logging this error because it may contain a password
// we are not logging this error because it may contain a password or a passphrase
gui.createErrorPanel(errMessage)
} else {
_ = gui.closeConfirmationPrompt(false)
+1
View File
@@ -19,6 +19,7 @@ func dutchTranslationSet() TranslationSet {
CommitMessage: "Commit bericht",
CredentialsUsername: "Gebruikersnaam",
CredentialsPassword: "Wachtwoord",
CredentialsPassphrase: "Voer een wachtwoordzin in voor de SSH-sleutel",
PassUnameWrong: "Wachtwoord en/of gebruikersnaam verkeert",
CommitChanges: "Commit veranderingen",
AmendLastCommit: "wijzig laatste commit",
+11 -2
View File
@@ -30,6 +30,7 @@ type TranslationSet struct {
CommitMessage string
CredentialsUsername string
CredentialsPassword string
CredentialsPassphrase string
PassUnameWrong string
CommitChanges string
AmendLastCommit string
@@ -428,7 +429,14 @@ type TranslationSet struct {
NavigationTitle string
}
const englishReleaseNotes = `## lazygit 0.23 Release Notes
const englishReleaseNotes = `## lazygit 0.23.2 Release Notes
- Fixed bug where editing a file with spaces did not work
- Fixed formatting issue with delta that rendered '[0;K' to the screen
- Fixed bug where lazygit failed upon attempting to create a config file in a
read-only filesystem
## lazygit 0.23 Release Notes
Custom Commands:
- You can now create your own custom commands complete with menus and prompts
@@ -519,7 +527,8 @@ func englishTranslationSet() TranslationSet {
CommitMessage: "Commit message",
CredentialsUsername: "Username",
CredentialsPassword: "Password",
PassUnameWrong: "Password and/or username wrong",
CredentialsPassphrase: "Enter passphrase for SSH key",
PassUnameWrong: "Password, passphrase and/or username wrong",
CommitChanges: "commit changes",
AmendLastCommit: "amend last commit",
SureToAmend: "Are you sure you want to amend last commit? Afterwards, you can change commit message from the commits panel.",
+2 -1
View File
@@ -15,7 +15,8 @@ func polishTranslationSet() TranslationSet {
CommitMessage: "Wiadomość commita",
CredentialsUsername: "Username",
CredentialsPassword: "Password",
PassUnameWrong: "Password and/or username wrong",
CredentialsPassphrase: "Passphrase",
PassUnameWrong: "Password, passphrase and/or username wrong",
CommitChanges: "commituj zmiany",
AmendLastCommit: "zmień ostatnie zatwierdzenie",
SureToAmend: "Czy na pewno chcesz zmienić ostatnie zatwierdzenie? Możesz zmienić komunikat zatwierdzenia z panelu zatwierdzeń.",
+33 -4
View File
@@ -16,6 +16,19 @@ type escapeInterpreter struct {
csiParam []string
curFgColor, curBgColor Attribute
mode OutputMode
instruction instruction
}
const (
NONE = 1 << iota
ERASE_IN_LINE
)
type instruction struct {
kind int
param1 int
param2 int
toWrite []rune
}
type escapeState int
@@ -57,10 +70,11 @@ func (ei *escapeInterpreter) runes() []rune {
// terminal escape sequences.
func newEscapeInterpreter(mode OutputMode) *escapeInterpreter {
ei := &escapeInterpreter{
state: stateNone,
curFgColor: ColorDefault,
curBgColor: ColorDefault,
mode: mode,
state: stateNone,
curFgColor: ColorDefault,
curBgColor: ColorDefault,
mode: mode,
instruction: instruction{kind: NONE},
}
return ei
}
@@ -73,6 +87,10 @@ func (ei *escapeInterpreter) reset() {
ei.csiParam = nil
}
func (ei *escapeInterpreter) instructionRead() {
ei.instruction.kind = NONE
}
// parseOne parses a rune. If isEscape is true, it means that the rune is part
// of an escape sequence, and as such should not be printed verbatim. Otherwise,
// it's not an escape sequence.
@@ -131,6 +149,17 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
return false, errCSIParseError
}
ei.state = stateNone
ei.csiParam = nil
return true, nil
case ch == 'K':
p, err := strconv.Atoi(ei.csiParam[0])
if err != nil {
return false, errCSIParseError
}
ei.instruction.kind = ERASE_IN_LINE
ei.instruction.param1 = p
ei.state = stateNone
ei.csiParam = nil
return true, nil
+34
View File
@@ -400,6 +400,15 @@ func (v *View) Write(p []byte) (n int, err error) {
}
default:
cells := v.parseInput(ch)
if v.ei.instruction.kind != NONE {
switch v.ei.instruction.kind {
case ERASE_IN_LINE:
v.eraseInLine()
}
v.ei.instructionRead()
continue
}
if cells == nil {
continue
}
@@ -416,6 +425,31 @@ func (v *View) Write(p []byte) (n int, err error) {
return len(p), nil
}
func (v *View) eraseInLine() {
code := v.ei.instruction.param1
switch code {
case 0:
// need to write till end of the line with cells containing the same bg colour as we currently have.
if len(v.lines) == 0 {
v.lines = append(v.lines, []cell{})
}
nl := len(v.lines)
width, _ := v.Size()
cellCount := width - len(v.lines[nl-1])
c := cell{
fgColor: v.ei.curFgColor,
bgColor: v.ei.curBgColor,
chr: ' ',
}
for i := 0; i < cellCount; i++ {
v.lines[nl-1] = append(v.lines[nl-1], c)
}
default:
// don't recognise sequence. Until we merge the gocui master branch we can't handle going backwards.
}
}
// parseInput parses char by char the input written to the View. It returns nil
// while processing ESC sequences. Otherwise, it returns a cell slice that
// contains the processed data.
+1 -1
View File
@@ -104,7 +104,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
# github.com/jesseduffield/gocui v0.3.1-0.20201007110350-cc51e317126e
# github.com/jesseduffield/gocui v0.3.1-0.20201010224802-8a6768078fd7
## explicit
github.com/jesseduffield/gocui
# github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe