mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-04 22:34:39 +02:00
Merge branch 'master' into feature/anonymous-reporting
This commit is contained in:
commit
a1c6adab59
@ -7,14 +7,33 @@ jobs:
|
|||||||
working_directory: /go/src/github.com/jesseduffield/lazygit
|
working_directory: /go/src/github.com/jesseduffield/lazygit
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- v1-pkg-cache
|
||||||
|
- run:
|
||||||
|
name: Run gofmt -s
|
||||||
|
command: |
|
||||||
|
if [ $(find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;|wc -l) -gt 0 ]; then
|
||||||
|
find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
- run:
|
- run:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
command: |
|
command: |
|
||||||
./test.sh
|
./test.sh
|
||||||
|
- run:
|
||||||
|
name: Compile project on every platform
|
||||||
|
command: |
|
||||||
|
go get github.com/mitchellh/gox
|
||||||
|
gox -parallel 10 -os "linux freebsd netbsd windows" -osarch "darwin/i386 darwin/amd64"
|
||||||
- run:
|
- run:
|
||||||
name: Push on codecov result
|
name: Push on codecov result
|
||||||
command: |
|
command: |
|
||||||
bash <(curl -s https://codecov.io/bash)
|
bash <(curl -s https://codecov.io/bash)
|
||||||
|
- save_cache:
|
||||||
|
key: v1-pkg-cache
|
||||||
|
paths:
|
||||||
|
- "/go/pkg"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
docker:
|
docker:
|
||||||
|
5
main.go
5
main.go
@ -16,6 +16,7 @@ var (
|
|||||||
version = "unversioned"
|
version = "unversioned"
|
||||||
date string
|
date string
|
||||||
|
|
||||||
|
configFlag = flag.Bool("config", false, "Print the current default config")
|
||||||
debuggingFlag = flag.Bool("debug", false, "a boolean")
|
debuggingFlag = flag.Bool("debug", false, "a boolean")
|
||||||
versionFlag = flag.Bool("v", false, "Print the current version")
|
versionFlag = flag.Bool("v", false, "Print the current version")
|
||||||
)
|
)
|
||||||
@ -31,6 +32,10 @@ func main() {
|
|||||||
fmt.Printf("commit=%s, build date=%s, version=%s, os=%s, arch=%s\n", commit, date, version, runtime.GOOS, runtime.GOARCH)
|
fmt.Printf("commit=%s, build date=%s, version=%s, os=%s, arch=%s\n", commit, date, version, runtime.GOOS, runtime.GOARCH)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
if *configFlag {
|
||||||
|
fmt.Printf("%s\n", config.GetDefaultConfig())
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
appConfig, err := config.NewAppConfig("lazygit", version, commit, date, debuggingFlag)
|
appConfig, err := config.NewAppConfig("lazygit", version, commit, date, debuggingFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -69,10 +69,7 @@ func NewApp(config config.AppConfigurer) (*App, error) {
|
|||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
app.Log = newLogger(config)
|
app.Log = newLogger(config)
|
||||||
app.OSCommand, err = commands.NewOSCommand(app.Log)
|
app.OSCommand = commands.NewOSCommand(app.Log)
|
||||||
if err != nil {
|
|
||||||
return app, err
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Tr = i18n.NewLocalizer(app.Log)
|
app.Tr = i18n.NewLocalizer(app.Log)
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ func (c *GitCommand) UsingGpg() bool {
|
|||||||
func (c *GitCommand) Commit(g *gocui.Gui, message string) (*exec.Cmd, error) {
|
func (c *GitCommand) Commit(g *gocui.Gui, message string) (*exec.Cmd, error) {
|
||||||
command := "git commit -m " + c.OSCommand.Quote(message)
|
command := "git commit -m " + c.OSCommand.Quote(message)
|
||||||
if c.UsingGpg() {
|
if c.UsingGpg() {
|
||||||
return c.OSCommand.PrepareSubProcess(c.OSCommand.Platform.shell, c.OSCommand.Platform.shellArg, command)
|
return c.OSCommand.PrepareSubProcess(c.OSCommand.Platform.shell, c.OSCommand.Platform.shellArg, command), nil
|
||||||
}
|
}
|
||||||
return nil, c.OSCommand.RunCommand(command)
|
return nil, c.OSCommand.RunCommand(command)
|
||||||
}
|
}
|
||||||
@ -391,12 +391,12 @@ func (c *GitCommand) Checkout(branch string, force bool) error {
|
|||||||
|
|
||||||
// AddPatch prepares a subprocess for adding a patch by patch
|
// AddPatch prepares a subprocess for adding a patch by patch
|
||||||
// this will eventually be swapped out for a better solution inside the Gui
|
// this will eventually be swapped out for a better solution inside the Gui
|
||||||
func (c *GitCommand) AddPatch(filename string) (*exec.Cmd, error) {
|
func (c *GitCommand) AddPatch(filename string) *exec.Cmd {
|
||||||
return c.OSCommand.PrepareSubProcess("git", "add", "--patch", filename)
|
return c.OSCommand.PrepareSubProcess("git", "add", "--patch", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrepareCommitSubProcess prepares a subprocess for `git commit`
|
// PrepareCommitSubProcess prepares a subprocess for `git commit`
|
||||||
func (c *GitCommand) PrepareCommitSubProcess() (*exec.Cmd, error) {
|
func (c *GitCommand) PrepareCommitSubProcess() *exec.Cmd {
|
||||||
return c.OSCommand.PrepareSubProcess("git", "commit")
|
return c.OSCommand.PrepareSubProcess("git", "commit")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,28 +9,21 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getDummyLog() *logrus.Entry {
|
func newDummyLog() *logrus.Entry {
|
||||||
log := logrus.New()
|
log := logrus.New()
|
||||||
log.Out = ioutil.Discard
|
log.Out = ioutil.Discard
|
||||||
return log.WithField("test", "test")
|
return log.WithField("test", "test")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDummyOSCommand() *OSCommand {
|
func newDummyGitCommand() *GitCommand {
|
||||||
return &OSCommand{
|
|
||||||
Log: getDummyLog(),
|
|
||||||
Platform: getPlatform(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getDummyGitCommand() *GitCommand {
|
|
||||||
return &GitCommand{
|
return &GitCommand{
|
||||||
Log: getDummyLog(),
|
Log: newDummyLog(),
|
||||||
OSCommand: getDummyOSCommand(),
|
OSCommand: newDummyOSCommand(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDiff(t *testing.T) {
|
func TestDiff(t *testing.T) {
|
||||||
gitCommand := getDummyGitCommand()
|
gitCommand := newDummyGitCommand()
|
||||||
if err := test.GenerateRepo("lots_of_diffs.sh"); err != nil {
|
if err := test.GenerateRepo("lots_of_diffs.sh"); err != nil {
|
||||||
t.Error(err.Error())
|
t.Error(err.Error())
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
@ -25,17 +24,22 @@ type Platform struct {
|
|||||||
|
|
||||||
// OSCommand holds all the os commands
|
// OSCommand holds all the os commands
|
||||||
type OSCommand struct {
|
type OSCommand struct {
|
||||||
Log *logrus.Entry
|
Log *logrus.Entry
|
||||||
Platform *Platform
|
Platform *Platform
|
||||||
|
command func(string, ...string) *exec.Cmd
|
||||||
|
getGlobalGitConfig func(string) (string, error)
|
||||||
|
getenv func(string) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOSCommand os command runner
|
// NewOSCommand os command runner
|
||||||
func NewOSCommand(log *logrus.Entry) (*OSCommand, error) {
|
func NewOSCommand(log *logrus.Entry) *OSCommand {
|
||||||
osCommand := &OSCommand{
|
return &OSCommand{
|
||||||
Log: log,
|
Log: log,
|
||||||
Platform: getPlatform(),
|
Platform: getPlatform(),
|
||||||
|
command: exec.Command,
|
||||||
|
getGlobalGitConfig: gitconfig.Global,
|
||||||
|
getenv: os.Getenv,
|
||||||
}
|
}
|
||||||
return osCommand, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunCommandWithOutput wrapper around commands returning their output and error
|
// RunCommandWithOutput wrapper around commands returning their output and error
|
||||||
@ -43,8 +47,10 @@ func (c *OSCommand) RunCommandWithOutput(command string) (string, error) {
|
|||||||
c.Log.WithField("command", command).Info("RunCommand")
|
c.Log.WithField("command", command).Info("RunCommand")
|
||||||
splitCmd := str.ToArgv(command)
|
splitCmd := str.ToArgv(command)
|
||||||
c.Log.Info(splitCmd)
|
c.Log.Info(splitCmd)
|
||||||
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput()
|
|
||||||
return sanitisedCommandOutput(cmdOut, err)
|
return sanitisedCommandOutput(
|
||||||
|
c.command(splitCmd[0], splitCmd[1:]...).CombinedOutput(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunCommand runs a command and just returns the error
|
// RunCommand runs a command and just returns the error
|
||||||
@ -59,10 +65,11 @@ func (c *OSCommand) RunDirectCommand(command string) (string, error) {
|
|||||||
args := str.ToArgv(c.Platform.shellArg + " " + command)
|
args := str.ToArgv(c.Platform.shellArg + " " + command)
|
||||||
c.Log.Info(spew.Sdump(args))
|
c.Log.Info(spew.Sdump(args))
|
||||||
|
|
||||||
cmdOut, err := exec.
|
return sanitisedCommandOutput(
|
||||||
Command(c.Platform.shell, args...).
|
exec.
|
||||||
CombinedOutput()
|
Command(c.Platform.shell, args...).
|
||||||
return sanitisedCommandOutput(cmdOut, err)
|
CombinedOutput(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||||
@ -75,33 +82,15 @@ func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
|||||||
return outputString, nil
|
return outputString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPlatform() *Platform {
|
// getOpenCommand get open command
|
||||||
switch runtime.GOOS {
|
func (c *OSCommand) getOpenCommand() (string, string, error) {
|
||||||
case "windows":
|
|
||||||
return &Platform{
|
|
||||||
os: "windows",
|
|
||||||
shell: "cmd",
|
|
||||||
shellArg: "/c",
|
|
||||||
escapedQuote: "\\\"",
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return &Platform{
|
|
||||||
os: runtime.GOOS,
|
|
||||||
shell: "bash",
|
|
||||||
shellArg: "-c",
|
|
||||||
escapedQuote: "\"",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOpenCommand get open command
|
|
||||||
func (c *OSCommand) GetOpenCommand() (string, string, error) {
|
|
||||||
//NextStep open equivalents: xdg-open (linux), cygstart (cygwin), open (OSX)
|
//NextStep open equivalents: xdg-open (linux), cygstart (cygwin), open (OSX)
|
||||||
trailMap := map[string]string{
|
trailMap := map[string]string{
|
||||||
"xdg-open": " &>/dev/null &",
|
"xdg-open": " &>/dev/null &",
|
||||||
"cygstart": "",
|
"cygstart": "",
|
||||||
"open": "",
|
"open": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, trail := range trailMap {
|
for name, trail := range trailMap {
|
||||||
if err := c.RunCommand("which " + name); err == nil {
|
if err := c.RunCommand("which " + name); err == nil {
|
||||||
return name, trail, nil
|
return name, trail, nil
|
||||||
@ -126,24 +115,25 @@ func (c *OSCommand) SublimeOpenFile(filename string) (*exec.Cmd, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenFile opens a file with the given
|
// OpenFile opens a file with the given
|
||||||
func (c *OSCommand) OpenFile(filename string) (*exec.Cmd, error) {
|
func (c *OSCommand) OpenFile(filename string) error {
|
||||||
cmdName, cmdTrail, err := c.GetOpenCommand()
|
cmdName, cmdTrail, err := c.getOpenCommand()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
err = c.RunCommand(cmdName + " " + c.Quote(filename) + cmdTrail) // TODO: test on linux
|
|
||||||
return nil, err
|
return c.RunCommand(cmdName + " " + c.Quote(filename) + cmdTrail) // TODO: test on linux
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditFile opens a file in a subprocess using whatever editor is available,
|
// EditFile opens a file in a subprocess using whatever editor is available,
|
||||||
// falling back to core.editor, VISUAL, EDITOR, then vi
|
// falling back to core.editor, VISUAL, EDITOR, then vi
|
||||||
func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
|
func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
|
||||||
editor, _ := gitconfig.Global("core.editor")
|
editor, _ := c.getGlobalGitConfig("core.editor")
|
||||||
|
|
||||||
if editor == "" {
|
if editor == "" {
|
||||||
editor = os.Getenv("VISUAL")
|
editor = c.getenv("VISUAL")
|
||||||
}
|
}
|
||||||
if editor == "" {
|
if editor == "" {
|
||||||
editor = os.Getenv("EDITOR")
|
editor = c.getenv("EDITOR")
|
||||||
}
|
}
|
||||||
if editor == "" {
|
if editor == "" {
|
||||||
if err := c.RunCommand("which vi"); err == nil {
|
if err := c.RunCommand("which vi"); err == nil {
|
||||||
@ -153,13 +143,13 @@ func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
|
|||||||
if editor == "" {
|
if editor == "" {
|
||||||
return nil, errors.New("No editor defined in $VISUAL, $EDITOR, or git config")
|
return nil, errors.New("No editor defined in $VISUAL, $EDITOR, or git config")
|
||||||
}
|
}
|
||||||
return c.PrepareSubProcess(editor, filename)
|
|
||||||
|
return c.PrepareSubProcess(editor, filename), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrepareSubProcess iniPrepareSubProcessrocess then tells the Gui to switch to it
|
// PrepareSubProcess iniPrepareSubProcessrocess then tells the Gui to switch to it
|
||||||
func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) (*exec.Cmd, error) {
|
func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) *exec.Cmd {
|
||||||
subprocess := exec.Command(cmdName, commandArgs...)
|
return c.command(cmdName, commandArgs...)
|
||||||
return subprocess, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quote wraps a message in platform-specific quotation marks
|
// Quote wraps a message in platform-specific quotation marks
|
||||||
@ -171,8 +161,7 @@ func (c *OSCommand) Quote(message string) string {
|
|||||||
// Unquote removes wrapping quotations marks if they are present
|
// Unquote removes wrapping quotations marks if they are present
|
||||||
// this is needed for removing quotes from staged filenames with spaces
|
// this is needed for removing quotes from staged filenames with spaces
|
||||||
func (c *OSCommand) Unquote(message string) string {
|
func (c *OSCommand) Unquote(message string) string {
|
||||||
message = strings.Replace(message, `"`, "", -1)
|
return strings.Replace(message, `"`, "", -1)
|
||||||
return message
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendLineToFile adds a new line in file
|
// AppendLineToFile adds a new line in file
|
||||||
|
16
pkg/commands/os_default_platform.go
Normal file
16
pkg/commands/os_default_platform.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getPlatform() *Platform {
|
||||||
|
return &Platform{
|
||||||
|
os: runtime.GOOS,
|
||||||
|
shell: "bash",
|
||||||
|
shellArg: "-c",
|
||||||
|
escapedQuote: "\"",
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,299 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
|
||||||
func TestQuote(t *testing.T) {
|
"github.com/stretchr/testify/assert"
|
||||||
osCommand := &OSCommand{
|
)
|
||||||
Log: nil,
|
|
||||||
Platform: getPlatform(),
|
func newDummyOSCommand() *OSCommand {
|
||||||
|
return NewOSCommand(newDummyLog())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOSCommandRunCommandWithOutput(t *testing.T) {
|
||||||
|
type scenario struct {
|
||||||
|
command string
|
||||||
|
test func(string, error)
|
||||||
}
|
}
|
||||||
test := "hello `test`"
|
|
||||||
expected := osCommand.Platform.escapedQuote + "hello \\`test\\`" + osCommand.Platform.escapedQuote
|
scenarios := []scenario{
|
||||||
test = osCommand.Quote(test)
|
{
|
||||||
if test != expected {
|
"echo -n '123'",
|
||||||
t.Error("Expected " + expected + ", got " + test)
|
func(output string, err error) {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, "123", output)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rmdir unexisting-folder",
|
||||||
|
func(output string, err error) {
|
||||||
|
assert.Regexp(t, ".*No such file or directory.*", err.Error())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
s.test(newDummyOSCommand().RunCommandWithOutput(s.command))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOSCommandRunCommand(t *testing.T) {
|
||||||
|
type scenario struct {
|
||||||
|
command string
|
||||||
|
test func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []scenario{
|
||||||
|
{
|
||||||
|
"rmdir unexisting-folder",
|
||||||
|
func(err error) {
|
||||||
|
assert.Regexp(t, ".*No such file or directory.*", err.Error())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
s.test(newDummyOSCommand().RunCommand(s.command))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOSCommandGetOpenCommand(t *testing.T) {
|
||||||
|
type scenario struct {
|
||||||
|
command func(string, ...string) *exec.Cmd
|
||||||
|
test func(string, string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []scenario{
|
||||||
|
{
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
return exec.Command("exit", "1")
|
||||||
|
},
|
||||||
|
func(name string, trail string, err error) {
|
||||||
|
assert.EqualError(t, err, "Unsure what command to use to open this file")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
assert.Equal(t, "which", name)
|
||||||
|
assert.Len(t, arg, 1)
|
||||||
|
assert.Regexp(t, "xdg-open|cygstart|open", arg[0])
|
||||||
|
return exec.Command("echo")
|
||||||
|
},
|
||||||
|
func(name string, trail string, err error) {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Regexp(t, "xdg-open|cygstart|open", name)
|
||||||
|
assert.Regexp(t, " \\&\\>/dev/null \\&|", trail)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
OSCmd := newDummyOSCommand()
|
||||||
|
OSCmd.command = s.command
|
||||||
|
|
||||||
|
s.test(OSCmd.getOpenCommand())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOSCommandOpenFile(t *testing.T) {
|
||||||
|
type scenario struct {
|
||||||
|
filename string
|
||||||
|
command func(string, ...string) *exec.Cmd
|
||||||
|
test func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []scenario{
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
return exec.Command("exit", "1")
|
||||||
|
},
|
||||||
|
func(err error) {
|
||||||
|
assert.EqualError(t, err, "Unsure what command to use to open this file")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
if name == "which" {
|
||||||
|
return exec.Command("echo")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(arg) {
|
||||||
|
case 1:
|
||||||
|
assert.Regexp(t, "open|cygstart", name)
|
||||||
|
assert.EqualValues(t, "test", arg[0])
|
||||||
|
case 3:
|
||||||
|
assert.Equal(t, "xdg-open", name)
|
||||||
|
assert.EqualValues(t, "test", arg[0])
|
||||||
|
assert.Regexp(t, " \\&\\>/dev/null \\&|", arg[1])
|
||||||
|
assert.EqualValues(t, "&", arg[2])
|
||||||
|
default:
|
||||||
|
assert.Fail(t, "Unexisting command given")
|
||||||
|
}
|
||||||
|
|
||||||
|
return exec.Command("echo")
|
||||||
|
},
|
||||||
|
func(err error) {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
OSCmd := newDummyOSCommand()
|
||||||
|
OSCmd.command = s.command
|
||||||
|
|
||||||
|
s.test(OSCmd.OpenFile(s.filename))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOSCommandEditFile(t *testing.T) {
|
||||||
|
type scenario struct {
|
||||||
|
filename string
|
||||||
|
command func(string, ...string) *exec.Cmd
|
||||||
|
getenv func(string) string
|
||||||
|
getGlobalGitConfig func(string) (string, error)
|
||||||
|
test func(*exec.Cmd, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []scenario{
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
return exec.Command("exit", "1")
|
||||||
|
},
|
||||||
|
func(env string) string {
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
func(cf string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
},
|
||||||
|
func(cmd *exec.Cmd, err error) {
|
||||||
|
assert.EqualError(t, err, "No editor defined in $VISUAL, $EDITOR, or git config")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
if name == "which" {
|
||||||
|
return exec.Command("exit", "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.EqualValues(t, "nano", name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
func(env string) string {
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
func(cf string) (string, error) {
|
||||||
|
return "nano", nil
|
||||||
|
},
|
||||||
|
func(cmd *exec.Cmd, err error) {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
if name == "which" {
|
||||||
|
return exec.Command("exit", "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.EqualValues(t, "nano", name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
func(env string) string {
|
||||||
|
if env == "VISUAL" {
|
||||||
|
return "nano"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
func(cf string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
},
|
||||||
|
func(cmd *exec.Cmd, err error) {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
if name == "which" {
|
||||||
|
return exec.Command("exit", "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.EqualValues(t, "emacs", name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
func(env string) string {
|
||||||
|
if env == "EDITOR" {
|
||||||
|
return "emacs"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
func(cf string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
},
|
||||||
|
func(cmd *exec.Cmd, err error) {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test",
|
||||||
|
func(name string, arg ...string) *exec.Cmd {
|
||||||
|
if name == "which" {
|
||||||
|
return exec.Command("echo")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.EqualValues(t, "vi", name)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
OSCmd := newDummyOSCommand()
|
||||||
|
OSCmd.command = s.command
|
||||||
|
OSCmd.getGlobalGitConfig = s.getGlobalGitConfig
|
||||||
|
OSCmd.getenv = s.getenv
|
||||||
|
|
||||||
|
s.test(OSCmd.EditFile(s.filename))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOSCommandQuote(t *testing.T) {
|
||||||
|
osCommand := newDummyOSCommand()
|
||||||
|
|
||||||
|
actual := osCommand.Quote("hello `test`")
|
||||||
|
|
||||||
|
expected := osCommand.Platform.escapedQuote + "hello \\`test\\`" + osCommand.Platform.escapedQuote
|
||||||
|
|
||||||
|
assert.EqualValues(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOSCommandUnquote(t *testing.T) {
|
||||||
|
osCommand := newDummyOSCommand()
|
||||||
|
|
||||||
|
actual := osCommand.Unquote(`hello "test"`)
|
||||||
|
|
||||||
|
expected := "hello test"
|
||||||
|
|
||||||
|
assert.EqualValues(t, expected, actual)
|
||||||
|
}
|
||||||
|
10
pkg/commands/os_windows.go
Normal file
10
pkg/commands/os_windows.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
func getPlatform() *Platform {
|
||||||
|
return &Platform{
|
||||||
|
os: "windows",
|
||||||
|
shell: "cmd",
|
||||||
|
shellArg: "/c",
|
||||||
|
escapedQuote: "\\\"",
|
||||||
|
}
|
||||||
|
}
|
@ -101,7 +101,7 @@ func LoadUserConfig() (*viper.Viper, error) {
|
|||||||
|
|
||||||
// LoadDefaultConfig loads in the defaults defined in this file
|
// LoadDefaultConfig loads in the defaults defined in this file
|
||||||
func LoadDefaultConfig(v *viper.Viper) error {
|
func LoadDefaultConfig(v *viper.Viper) error {
|
||||||
defaults := getDefaultConfig()
|
defaults := GetDefaultConfig()
|
||||||
return v.ReadConfig(bytes.NewBuffer(defaults))
|
return v.ReadConfig(bytes.NewBuffer(defaults))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +139,10 @@ func (c *AppConfig) InsertToUserConfig(key, value string) error {
|
|||||||
return v.WriteConfig()
|
return v.WriteConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultConfig() []byte {
|
func GetDefaultConfig() []byte {
|
||||||
return []byte(`
|
return []byte(
|
||||||
gui:
|
`gui:
|
||||||
## stuff relating to the UI
|
# stuff relating to the UI
|
||||||
scrollHeight: 2
|
scrollHeight: 2
|
||||||
theme:
|
theme:
|
||||||
activeBorderColor:
|
activeBorderColor:
|
||||||
|
@ -85,11 +85,8 @@ func (gui *Gui) handleAddPatch(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if !file.Tracked {
|
if !file.Tracked {
|
||||||
return gui.createErrorPanel(g, gui.Tr.SLocalize("CannotGitAdd"))
|
return gui.createErrorPanel(g, gui.Tr.SLocalize("CannotGitAdd"))
|
||||||
}
|
}
|
||||||
sub, err := gui.GitCommand.AddPatch(file.Name)
|
|
||||||
if err != nil {
|
gui.SubProcess = gui.GitCommand.AddPatch(file.Name)
|
||||||
return err
|
|
||||||
}
|
|
||||||
gui.SubProcess = sub
|
|
||||||
return gui.Errors.ErrSubProcess
|
return gui.Errors.ErrSubProcess
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,16 +215,11 @@ func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrepareSubProcess - prepare a subprocess for execution and tell the gui to switch to it
|
// PrepareSubProcess - prepare a subprocess for execution and tell the gui to switch to it
|
||||||
func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) error {
|
func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) {
|
||||||
sub, err := gui.GitCommand.PrepareCommitSubProcess()
|
gui.SubProcess = gui.GitCommand.PrepareCommitSubProcess()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
gui.SubProcess = sub
|
|
||||||
g.Update(func(g *gocui.Gui) error {
|
g.Update(func(g *gocui.Gui) error {
|
||||||
return gui.Errors.ErrSubProcess
|
return gui.Errors.ErrSubProcess
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, filename string, open func(string) (*exec.Cmd, error)) error {
|
func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, filename string, open func(string) (*exec.Cmd, error)) error {
|
||||||
@ -256,7 +248,7 @@ func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.OpenFile)
|
return gui.openFile(file.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||||
@ -425,3 +417,10 @@ func (gui *Gui) handleResetHard(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.refreshFiles(g)
|
return gui.refreshFiles(g)
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) openFile(filename string) error {
|
||||||
|
if err := gui.OSCommand.OpenFile(filename); err != nil {
|
||||||
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -65,8 +65,7 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleOpenConfig(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleOpenConfig(g *gocui.Gui, v *gocui.View) error {
|
||||||
filename := gui.Config.GetUserConfig().ConfigFileUsed()
|
return gui.openFile(gui.Config.GetUserConfig().ConfigFileUsed())
|
||||||
return gui.genericFileOpen(g, v, filename, gui.OSCommand.OpenFile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleEditConfig(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleEditConfig(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user