mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-05 15:15:49 +02:00
refactor commands to depend less on the shell
This commit is contained in:
parent
95c7df4c61
commit
9ecd7908aa
@ -41,7 +41,7 @@ func (c *GitCommand) SetupGit() {
|
|||||||
// GetStashEntries stash entryies
|
// GetStashEntries stash entryies
|
||||||
func (c *GitCommand) GetStashEntries() []StashEntry {
|
func (c *GitCommand) GetStashEntries() []StashEntry {
|
||||||
stashEntries := make([]StashEntry, 0)
|
stashEntries := make([]StashEntry, 0)
|
||||||
rawString, _ := c.OSCommand.RunDirectCommand("git stash list --pretty='%gs'")
|
rawString, _ := c.OSCommand.RunCommandWithOutput("git stash list --pretty='%gs'")
|
||||||
for i, line := range utils.SplitLines(rawString) {
|
for i, line := range utils.SplitLines(rawString) {
|
||||||
stashEntries = append(stashEntries, stashEntryFromLine(line, i))
|
stashEntries = append(stashEntries, stashEntryFromLine(line, i))
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ func stashEntryFromLine(line string, index int) StashEntry {
|
|||||||
|
|
||||||
// GetStashEntryDiff stash diff
|
// GetStashEntryDiff stash diff
|
||||||
func (c *GitCommand) GetStashEntryDiff(index int) (string, error) {
|
func (c *GitCommand) GetStashEntryDiff(index int) (string, error) {
|
||||||
return c.OSCommand.RunCommand("git stash show -p --color stash@{" + fmt.Sprint(index) + "}")
|
return c.OSCommand.RunCommandWithOutput("git stash show -p --color stash@{" + fmt.Sprint(index) + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func includes(array []string, str string) bool {
|
func includes(array []string, str string) bool {
|
||||||
@ -98,22 +98,14 @@ func (c *GitCommand) GetStatusFiles() []File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StashDo modify stash
|
// StashDo modify stash
|
||||||
func (c *GitCommand) StashDo(index int, method string) (string, error) {
|
func (c *GitCommand) StashDo(index int, method string) error {
|
||||||
return c.OSCommand.RunCommand("git stash " + method + " stash@{" + fmt.Sprint(index) + "}")
|
return c.OSCommand.RunCommand("git stash " + method + " stash@{" + fmt.Sprint(index) + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// StashSave save stash
|
// StashSave save stash
|
||||||
func (c *GitCommand) StashSave(message string) (string, error) {
|
// TODO: before calling this, check if there is anything to save
|
||||||
output, err := c.OSCommand.RunCommand("git stash save " + c.OSCommand.Quote(message))
|
func (c *GitCommand) StashSave(message string) error {
|
||||||
if err != nil {
|
return c.OSCommand.RunCommand("git stash save " + c.OSCommand.Quote(message))
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
// if there are no local changes to save, the exit code is 0, but we want
|
|
||||||
// to raise an error
|
|
||||||
if output == "No local changes to save\n" {
|
|
||||||
return output, errors.New(output)
|
|
||||||
}
|
|
||||||
return output, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MergeStatusFiles merge status files
|
// MergeStatusFiles merge status files
|
||||||
@ -147,7 +139,7 @@ func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []File) []File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) verifyInGitRepo() {
|
func (c *GitCommand) verifyInGitRepo() {
|
||||||
if output, err := c.OSCommand.RunCommand("git status"); err != nil {
|
if output, err := c.OSCommand.RunCommandWithOutput("git status"); err != nil {
|
||||||
fmt.Println(output)
|
fmt.Println(output)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -155,7 +147,7 @@ func (c *GitCommand) verifyInGitRepo() {
|
|||||||
|
|
||||||
// GetBranchName branch name
|
// GetBranchName branch name
|
||||||
func (c *GitCommand) GetBranchName() (string, error) {
|
func (c *GitCommand) GetBranchName() (string, error) {
|
||||||
return c.OSCommand.RunDirectCommand("git symbolic-ref --short HEAD")
|
return c.OSCommand.RunCommandWithOutput("git symbolic-ref --short HEAD")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) navigateToRepoRootDirectory() {
|
func (c *GitCommand) navigateToRepoRootDirectory() {
|
||||||
@ -189,11 +181,11 @@ func (c *GitCommand) ResetHard() error {
|
|||||||
// UpstreamDifferenceCount checks how many pushables/pullables there are for the
|
// UpstreamDifferenceCount checks how many pushables/pullables there are for the
|
||||||
// current branch
|
// current branch
|
||||||
func (c *GitCommand) UpstreamDifferenceCount() (string, string) {
|
func (c *GitCommand) UpstreamDifferenceCount() (string, string) {
|
||||||
pushableCount, err := c.OSCommand.RunDirectCommand("git rev-list @{u}..head --count")
|
pushableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..head --count")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "?", "?"
|
return "?", "?"
|
||||||
}
|
}
|
||||||
pullableCount, err := c.OSCommand.RunDirectCommand("git rev-list head..@{u} --count")
|
pullableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list head..@{u} --count")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "?", "?"
|
return "?", "?"
|
||||||
}
|
}
|
||||||
@ -203,7 +195,7 @@ func (c *GitCommand) UpstreamDifferenceCount() (string, string) {
|
|||||||
// GetCommitsToPush Returns the sha's of the commits that have not yet been pushed
|
// GetCommitsToPush Returns the sha's of the commits that have not yet been pushed
|
||||||
// to the remote branch of the current branch
|
// to the remote branch of the current branch
|
||||||
func (c *GitCommand) GetCommitsToPush() []string {
|
func (c *GitCommand) GetCommitsToPush() []string {
|
||||||
pushables, err := c.OSCommand.RunDirectCommand("git rev-list @{u}..head --abbrev-commit")
|
pushables, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..head --abbrev-commit")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]string, 0)
|
return make([]string, 0)
|
||||||
}
|
}
|
||||||
@ -211,43 +203,43 @@ func (c *GitCommand) GetCommitsToPush() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RenameCommit renames the topmost commit with the given name
|
// RenameCommit renames the topmost commit with the given name
|
||||||
func (c *GitCommand) RenameCommit(name string) (string, error) {
|
func (c *GitCommand) RenameCommit(name string) error {
|
||||||
return c.OSCommand.RunDirectCommand("git commit --allow-empty --amend -m " + c.OSCommand.Quote(name))
|
return c.OSCommand.RunCommand("git commit --allow-empty --amend -m " + c.OSCommand.Quote(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch fetch git repo
|
// Fetch fetch git repo
|
||||||
func (c *GitCommand) Fetch() (string, error) {
|
func (c *GitCommand) Fetch() error {
|
||||||
return c.OSCommand.RunDirectCommand("git fetch")
|
return c.OSCommand.RunCommand("git fetch")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetToCommit reset to commit
|
// ResetToCommit reset to commit
|
||||||
func (c *GitCommand) ResetToCommit(sha string) (string, error) {
|
func (c *GitCommand) ResetToCommit(sha string) error {
|
||||||
return c.OSCommand.RunDirectCommand("git reset " + sha)
|
return c.OSCommand.RunCommand("git reset " + sha)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBranch create new branch
|
// NewBranch create new branch
|
||||||
func (c *GitCommand) NewBranch(name string) (string, error) {
|
func (c *GitCommand) NewBranch(name string) error {
|
||||||
return c.OSCommand.RunDirectCommand("git checkout -b " + name)
|
return c.OSCommand.RunCommand("git checkout -b " + name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBranch delete branch
|
// DeleteBranch delete branch
|
||||||
func (c *GitCommand) DeleteBranch(branch string) (string, error) {
|
func (c *GitCommand) DeleteBranch(branch string) error {
|
||||||
return c.OSCommand.RunCommand("git branch -d " + branch)
|
return c.OSCommand.RunCommand("git branch -d " + branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListStash list stash
|
// ListStash list stash
|
||||||
func (c *GitCommand) ListStash() (string, error) {
|
func (c *GitCommand) ListStash() (string, error) {
|
||||||
return c.OSCommand.RunDirectCommand("git stash list")
|
return c.OSCommand.RunCommandWithOutput("git stash list")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge merge
|
// Merge merge
|
||||||
func (c *GitCommand) Merge(branchName string) (string, error) {
|
func (c *GitCommand) Merge(branchName string) error {
|
||||||
return c.OSCommand.RunDirectCommand("git merge --no-edit " + branchName)
|
return c.OSCommand.RunCommand("git merge --no-edit " + branchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AbortMerge abort merge
|
// AbortMerge abort merge
|
||||||
func (c *GitCommand) AbortMerge() (string, error) {
|
func (c *GitCommand) AbortMerge() error {
|
||||||
return c.OSCommand.RunDirectCommand("git merge --abort")
|
return c.OSCommand.RunCommand("git merge --abort")
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsingGpg tells us whether the user has gpg enabled so that we can know
|
// UsingGpg tells us whether the user has gpg enabled so that we can know
|
||||||
@ -269,30 +261,29 @@ func (c *GitCommand) Commit(g *gocui.Gui, message string) (*exec.Cmd, error) {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
// TODO: make these runDirectCommand functions just return an error
|
return nil, c.OSCommand.RunCommand(command)
|
||||||
_, err := c.OSCommand.RunDirectCommand(command)
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull pull from repo
|
// Pull pull from repo
|
||||||
func (c *GitCommand) Pull() (string, error) {
|
func (c *GitCommand) Pull() error {
|
||||||
return c.OSCommand.RunCommand("git pull --no-edit")
|
return c.OSCommand.RunCommand("git pull --no-edit")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push push to a branch
|
// Push push to a branch
|
||||||
func (c *GitCommand) Push(branchName string) (string, error) {
|
func (c *GitCommand) Push(branchName string) error {
|
||||||
return c.OSCommand.RunDirectCommand("git push -u origin " + branchName)
|
return c.OSCommand.RunCommand("git push -u origin " + branchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SquashPreviousTwoCommits squashes a commit down to the one below it
|
// SquashPreviousTwoCommits squashes a commit down to the one below it
|
||||||
// retaining the message of the higher commit
|
// retaining the message of the higher commit
|
||||||
func (c *GitCommand) SquashPreviousTwoCommits(message string) (string, error) {
|
func (c *GitCommand) SquashPreviousTwoCommits(message string) error {
|
||||||
return c.OSCommand.RunDirectCommand("git reset --soft HEAD^ && git commit --amend -m " + c.OSCommand.Quote(message))
|
// TODO: test this
|
||||||
|
return c.OSCommand.RunCommand("git reset --soft HEAD^ && git commit --amend -m " + c.OSCommand.Quote(message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SquashFixupCommit squashes a 'FIXUP' commit into the commit beneath it,
|
// SquashFixupCommit squashes a 'FIXUP' commit into the commit beneath it,
|
||||||
// retaining the commit message of the lower commit
|
// retaining the commit message of the lower commit
|
||||||
func (c *GitCommand) SquashFixupCommit(branchName string, shaValue string) (string, error) {
|
func (c *GitCommand) SquashFixupCommit(branchName string, shaValue string) error {
|
||||||
var err error
|
var err error
|
||||||
commands := []string{
|
commands := []string{
|
||||||
"git checkout -q " + shaValue,
|
"git checkout -q " + shaValue,
|
||||||
@ -303,7 +294,7 @@ func (c *GitCommand) SquashFixupCommit(branchName string, shaValue string) (stri
|
|||||||
ret := ""
|
ret := ""
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
c.Log.Info(command)
|
c.Log.Info(command)
|
||||||
output, err := c.OSCommand.RunDirectCommand(command)
|
output, err := c.OSCommand.RunCommandWithOutput(command)
|
||||||
ret += output
|
ret += output
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Info(ret)
|
c.Log.Info(ret)
|
||||||
@ -313,23 +304,25 @@ func (c *GitCommand) SquashFixupCommit(branchName string, shaValue string) (stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// We are already in an error state here so we're just going to append
|
// We are already in an error state here so we're just going to append
|
||||||
// the output of these commands
|
// the output of these commands
|
||||||
output, _ := c.OSCommand.RunDirectCommand("git branch -d " + shaValue)
|
output, _ := c.OSCommand.RunCommandWithOutput("git branch -d " + shaValue)
|
||||||
ret += output
|
ret += output
|
||||||
output, _ = c.OSCommand.RunDirectCommand("git checkout " + branchName)
|
output, _ = c.OSCommand.RunCommandWithOutput("git checkout " + branchName)
|
||||||
ret += output
|
ret += output
|
||||||
}
|
}
|
||||||
return ret, err
|
if err != nil {
|
||||||
|
return errors.New(ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CatFile obtain the contents of a file
|
// CatFile obtain the contents of a file
|
||||||
func (c *GitCommand) CatFile(file string) (string, error) {
|
func (c *GitCommand) CatFile(file string) (string, error) {
|
||||||
return c.OSCommand.RunDirectCommand("cat " + file)
|
return c.OSCommand.RunCommandWithOutput("cat " + file)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StageFile stages a file
|
// StageFile stages a file
|
||||||
func (c *GitCommand) StageFile(file string) error {
|
func (c *GitCommand) StageFile(file string) error {
|
||||||
_, err := c.OSCommand.RunCommand("git add " + file)
|
return c.OSCommand.RunCommand("git add " + file)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnStageFile unstages a file
|
// UnStageFile unstages a file
|
||||||
@ -340,18 +333,17 @@ func (c *GitCommand) UnStageFile(file string, tracked bool) error {
|
|||||||
} else {
|
} else {
|
||||||
command = "git rm --cached "
|
command = "git rm --cached "
|
||||||
}
|
}
|
||||||
_, err := c.OSCommand.RunCommand(command + file)
|
return c.OSCommand.RunCommand(command + file)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitStatus returns the plaintext short status of the repo
|
// GitStatus returns the plaintext short status of the repo
|
||||||
func (c *GitCommand) GitStatus() (string, error) {
|
func (c *GitCommand) GitStatus() (string, error) {
|
||||||
return c.OSCommand.RunCommand("git status --untracked-files=all --short")
|
return c.OSCommand.RunCommandWithOutput("git status --untracked-files=all --short")
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInMergeState states whether we are still mid-merge
|
// IsInMergeState states whether we are still mid-merge
|
||||||
func (c *GitCommand) IsInMergeState() (bool, error) {
|
func (c *GitCommand) IsInMergeState() (bool, error) {
|
||||||
output, err := c.OSCommand.RunCommand("git status --untracked-files=all")
|
output, err := c.OSCommand.RunCommandWithOutput("git status --untracked-files=all")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -362,16 +354,14 @@ func (c *GitCommand) IsInMergeState() (bool, error) {
|
|||||||
func (c *GitCommand) RemoveFile(file File) error {
|
func (c *GitCommand) RemoveFile(file File) error {
|
||||||
// if the file isn't tracked, we assume you want to delete it
|
// if the file isn't tracked, we assume you want to delete it
|
||||||
if !file.Tracked {
|
if !file.Tracked {
|
||||||
_, err := c.OSCommand.RunCommand("rm -rf ./" + file.Name)
|
return c.OSCommand.RunCommand("rm -rf ./" + file.Name)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// if the file is tracked, we assume you want to just check it out
|
// if the file is tracked, we assume you want to just check it out
|
||||||
_, err := c.OSCommand.RunCommand("git checkout " + file.Name)
|
return c.OSCommand.RunCommand("git checkout " + file.Name)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checkout checks out a branch, with --force if you set the force arg to true
|
// Checkout checks out a branch, with --force if you set the force arg to true
|
||||||
func (c *GitCommand) Checkout(branch string, force bool) (string, error) {
|
func (c *GitCommand) Checkout(branch string, force bool) error {
|
||||||
forceArg := ""
|
forceArg := ""
|
||||||
if force {
|
if force {
|
||||||
forceArg = "--force "
|
forceArg = "--force "
|
||||||
@ -394,7 +384,7 @@ func (c *GitCommand) PrepareCommitSubProcess() (*exec.Cmd, error) {
|
|||||||
// Currently it limits the result to 100 commits, but when we get async stuff
|
// Currently it limits the result to 100 commits, but when we get async stuff
|
||||||
// working we can do lazy loading
|
// working we can do lazy loading
|
||||||
func (c *GitCommand) GetBranchGraph(branchName string) (string, error) {
|
func (c *GitCommand) GetBranchGraph(branchName string) (string, error) {
|
||||||
return c.OSCommand.RunCommand("git log --graph --color --abbrev-commit --decorate --date=relative --pretty=medium -100 " + branchName)
|
return c.OSCommand.RunCommandWithOutput("git log --graph --color --abbrev-commit --decorate --date=relative --pretty=medium -100 " + branchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map (from https://gobyexample.com/collection-functions)
|
// Map (from https://gobyexample.com/collection-functions)
|
||||||
@ -452,7 +442,7 @@ func (c *GitCommand) GetCommits() []Commit {
|
|||||||
func (c *GitCommand) GetLog() string {
|
func (c *GitCommand) GetLog() string {
|
||||||
// currently limiting to 30 for performance reasons
|
// currently limiting to 30 for performance reasons
|
||||||
// TODO: add lazyloading when you scroll down
|
// TODO: add lazyloading when you scroll down
|
||||||
result, err := c.OSCommand.RunDirectCommand("git log --oneline -30")
|
result, err := c.OSCommand.RunCommandWithOutput("git log --oneline -30")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// assume if there is an error there are no commits yet for this branch
|
// assume if there is an error there are no commits yet for this branch
|
||||||
return ""
|
return ""
|
||||||
@ -469,7 +459,7 @@ func (c *GitCommand) Ignore(filename string) {
|
|||||||
|
|
||||||
// Show shows the diff of a commit
|
// Show shows the diff of a commit
|
||||||
func (c *GitCommand) Show(sha string) string {
|
func (c *GitCommand) Show(sha string) string {
|
||||||
result, err := c.OSCommand.RunDirectCommand("git show --color " + sha)
|
result, err := c.OSCommand.RunCommandWithOutput("git show --color " + sha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -492,6 +482,6 @@ func (c *GitCommand) Diff(file File) string {
|
|||||||
}
|
}
|
||||||
command := "git diff --color " + cachedArg + deletedArg + trackedArg + file.Name
|
command := "git diff --color " + cachedArg + deletedArg + trackedArg + file.Name
|
||||||
// for now we assume an error means the file was deleted
|
// for now we assume an error means the file was deleted
|
||||||
s, _ := c.OSCommand.RunCommand(command)
|
s, _ := c.OSCommand.RunCommandWithOutput(command)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
"github.com/mgutz/str"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
gitconfig "github.com/tcnksm/go-gitconfig"
|
gitconfig "github.com/tcnksm/go-gitconfig"
|
||||||
@ -41,30 +44,41 @@ func NewOSCommand(log *logrus.Logger) (*OSCommand, error) {
|
|||||||
return osCommand, nil
|
return osCommand, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunCommand wrapper around commands
|
// RunCommandWithOutput wrapper around commands returning their output and error
|
||||||
func (c *OSCommand) RunCommand(command string) (string, error) {
|
func (c *OSCommand) RunCommandWithOutput(command string) (string, error) {
|
||||||
c.Log.WithField("command", command).Info("RunCommand")
|
c.Log.WithField("command", command).Info("RunCommand")
|
||||||
splitCmd := strings.Split(command, " ")
|
splitCmd := str.ToArgv(command)
|
||||||
|
c.Log.Info(splitCmd)
|
||||||
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput()
|
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput()
|
||||||
return sanitisedCommandOutput(cmdOut, err)
|
return sanitisedCommandOutput(cmdOut, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunCommand runs a command and just returns the error
|
||||||
|
func (c *OSCommand) RunCommand(command string) error {
|
||||||
|
_, err := c.RunCommandWithOutput(command)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// RunDirectCommand wrapper around direct commands
|
// RunDirectCommand wrapper around direct commands
|
||||||
func (c *OSCommand) RunDirectCommand(command string) (string, error) {
|
func (c *OSCommand) RunDirectCommand(command string) (string, error) {
|
||||||
c.Log.WithField("command", command).Info("RunDirectCommand")
|
c.Log.WithField("command", command).Info("RunDirectCommand")
|
||||||
|
args := str.ToArgv(c.Platform.shellArg + " " + command)
|
||||||
|
c.Log.Info(spew.Sdump(args))
|
||||||
|
|
||||||
cmdOut, err := exec.
|
cmdOut, err := exec.
|
||||||
Command(c.Platform.shell, c.Platform.shellArg, command).
|
Command(c.Platform.shell, args...).
|
||||||
CombinedOutput()
|
CombinedOutput()
|
||||||
return sanitisedCommandOutput(cmdOut, err)
|
return sanitisedCommandOutput(cmdOut, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||||
outputString := string(output)
|
outputString := string(output)
|
||||||
if outputString == "" && err != nil {
|
if err != nil {
|
||||||
return err.Error(), err
|
// errors like 'exit status 1' are not very useful so we'll create an error
|
||||||
|
// from the combined output
|
||||||
|
return outputString, errors.New(outputString)
|
||||||
}
|
}
|
||||||
return outputString, err
|
return outputString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPlatform() platform {
|
func getPlatform() platform {
|
||||||
@ -95,7 +109,7 @@ func (c *OSCommand) GetOpenCommand() (string, string, error) {
|
|||||||
"open": "",
|
"open": "",
|
||||||
}
|
}
|
||||||
for name, trail := range trailMap {
|
for name, trail := range trailMap {
|
||||||
if out, _ := c.RunCommand("which " + name); out != "exit status 1" {
|
if out, _ := c.RunCommandWithOutput("which " + name); out != "exit status 1" {
|
||||||
return name, trail, nil
|
return name, trail, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,15 +122,13 @@ func (c *OSCommand) GetOpenCommand() (string, string, error) {
|
|||||||
// they're being passed as arguments into another function,
|
// they're being passed as arguments into another function,
|
||||||
// but only editFile actually returns a *exec.Cmd
|
// but only editFile actually returns a *exec.Cmd
|
||||||
func (c *OSCommand) VsCodeOpenFile(filename string) (*exec.Cmd, error) {
|
func (c *OSCommand) VsCodeOpenFile(filename string) (*exec.Cmd, error) {
|
||||||
_, err := c.RunCommand("code -r " + filename)
|
return nil, c.RunCommand("code -r " + filename)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SublimeOpenFile opens the filein sublime
|
// SublimeOpenFile opens the filein sublime
|
||||||
// may be deprecated in the future
|
// may be deprecated in the future
|
||||||
func (c *OSCommand) SublimeOpenFile(filename string) (*exec.Cmd, error) {
|
func (c *OSCommand) SublimeOpenFile(filename string) (*exec.Cmd, error) {
|
||||||
_, err := c.RunCommand("subl " + filename)
|
return nil, c.RunCommand("subl " + filename)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenFile opens a file with the given
|
// OpenFile opens a file with the given
|
||||||
@ -125,8 +137,7 @@ func (c *OSCommand) OpenFile(filename string) (*exec.Cmd, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = c.RunCommand(cmdName + " " + filename + cmdTrail)
|
return nil, c.RunCommand(cmdName + " " + filename + cmdTrail) // TODO: ensure this works given that it's not rundirectcommand
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditFile opens a file in a subprocess using whatever editor is available,
|
// EditFile opens a file in a subprocess using whatever editor is available,
|
||||||
@ -140,7 +151,7 @@ func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
|
|||||||
editor = os.Getenv("EDITOR")
|
editor = os.Getenv("EDITOR")
|
||||||
}
|
}
|
||||||
if editor == "" {
|
if editor == "" {
|
||||||
if _, err := c.RunCommand("which vi"); err == nil {
|
if err := c.RunCommand("which vi"); err == nil {
|
||||||
editor = "vi"
|
editor = "vi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,10 @@ func NewBranchListBuilder(log *logrus.Logger, gitCommand *commands.GitCommand) (
|
|||||||
func (b *BranchListBuilder) obtainCurrentBranch() commands.Branch {
|
func (b *BranchListBuilder) obtainCurrentBranch() commands.Branch {
|
||||||
// I used go-git for this, but that breaks if you've just done a git init,
|
// I used go-git for this, but that breaks if you've just done a git init,
|
||||||
// even though you're on 'master'
|
// even though you're on 'master'
|
||||||
branchName, _ := b.GitCommand.OSCommand.RunDirectCommand("git symbolic-ref --short HEAD")
|
branchName, err := b.GitCommand.OSCommand.RunCommandWithOutput("git symbolic-ref --short HEAD")
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
return commands.Branch{Name: strings.TrimSpace(branchName), Recency: " *"}
|
return commands.Branch{Name: strings.TrimSpace(branchName), Recency: " *"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.createErrorPanel(g, "You have already checked out this branch")
|
return gui.createErrorPanel(g, "You have already checked out this branch")
|
||||||
}
|
}
|
||||||
branch := gui.getSelectedBranch(v)
|
branch := gui.getSelectedBranch(v)
|
||||||
if output, err := gui.GitCommand.Checkout(branch.Name, false); err != nil {
|
if err := gui.GitCommand.Checkout(branch.Name, false); err != nil {
|
||||||
gui.createErrorPanel(g, output)
|
gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
}
|
}
|
||||||
@ -24,8 +24,8 @@ func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error {
|
|||||||
func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
|
||||||
branch := gui.getSelectedBranch(v)
|
branch := gui.getSelectedBranch(v)
|
||||||
return gui.createConfirmationPanel(g, v, "Force Checkout Branch", "Are you sure you want force checkout? You will lose all local changes", func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(g, v, "Force Checkout Branch", "Are you sure you want force checkout? You will lose all local changes", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.Checkout(branch.Name, true); err != nil {
|
if err := gui.GitCommand.Checkout(branch.Name, true); err != nil {
|
||||||
gui.createErrorPanel(g, output)
|
gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -33,8 +33,8 @@ func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
|
|||||||
|
|
||||||
func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
|
||||||
gui.createPromptPanel(g, v, "Branch Name:", func(g *gocui.Gui, v *gocui.View) error {
|
gui.createPromptPanel(g, v, "Branch Name:", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.Checkout(gui.trimmedContent(v), false); err != nil {
|
if err := gui.GitCommand.Checkout(gui.trimmedContent(v), false); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
})
|
})
|
||||||
@ -44,8 +44,8 @@ func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
|
|||||||
func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error {
|
||||||
branch := gui.State.Branches[0]
|
branch := gui.State.Branches[0]
|
||||||
gui.createPromptPanel(g, v, "New Branch Name (Branch is off of "+branch.Name+")", func(g *gocui.Gui, v *gocui.View) error {
|
gui.createPromptPanel(g, v, "New Branch Name (Branch is off of "+branch.Name+")", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.NewBranch(gui.trimmedContent(v)); err != nil {
|
if err := gui.GitCommand.NewBranch(gui.trimmedContent(v)); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
gui.refreshSidePanels(g)
|
gui.refreshSidePanels(g)
|
||||||
return gui.handleBranchSelect(g, v)
|
return gui.handleBranchSelect(g, v)
|
||||||
@ -60,8 +60,8 @@ func (gui *Gui) handleDeleteBranch(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.createErrorPanel(g, "You cannot delete the checked out branch!")
|
return gui.createErrorPanel(g, "You cannot delete the checked out branch!")
|
||||||
}
|
}
|
||||||
return gui.createConfirmationPanel(g, v, "Delete Branch", "Are you sure you want delete the branch "+selectedBranch.Name+" ?", func(g *gocui.Gui, v *gocui.View) error {
|
return gui.createConfirmationPanel(g, v, "Delete Branch", "Are you sure you want delete the branch "+selectedBranch.Name+" ?", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.DeleteBranch(selectedBranch.Name); err != nil {
|
if err := gui.GitCommand.DeleteBranch(selectedBranch.Name); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -74,8 +74,8 @@ func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if checkedOutBranch.Name == selectedBranch.Name {
|
if checkedOutBranch.Name == selectedBranch.Name {
|
||||||
return gui.createErrorPanel(g, "You cannot merge a branch into itself")
|
return gui.createErrorPanel(g, "You cannot merge a branch into itself")
|
||||||
}
|
}
|
||||||
if output, err := gui.GitCommand.Merge(selectedBranch.Name); err != nil {
|
if err := gui.GitCommand.Merge(selectedBranch.Name); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ func (gui *Gui) handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if output, err := gui.GitCommand.ResetToCommit(commit.Sha); err != nil {
|
if err := gui.GitCommand.ResetToCommit(commit.Sha); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
if err := gui.refreshCommits(g); err != nil {
|
if err := gui.refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -99,8 +99,8 @@ func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if output, err := gui.GitCommand.SquashPreviousTwoCommits(commit.Name); err != nil {
|
if err := gui.GitCommand.SquashPreviousTwoCommits(commit.Name); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
if err := gui.refreshCommits(g); err != nil {
|
if err := gui.refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -132,8 +132,8 @@ func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
gui.createConfirmationPanel(g, v, "Fixup", "Are you sure you want to fixup this commit? The commit beneath will be squashed up into this one", func(g *gocui.Gui, v *gocui.View) error {
|
gui.createConfirmationPanel(g, v, "Fixup", "Are you sure you want to fixup this commit? The commit beneath will be squashed up into this one", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.SquashFixupCommit(branch.Name, commit.Sha); err != nil {
|
if err := gui.GitCommand.SquashFixupCommit(branch.Name, commit.Sha); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
if err := gui.refreshCommits(g); err != nil {
|
if err := gui.refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -148,8 +148,8 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.createErrorPanel(g, "Can only rename topmost commit")
|
return gui.createErrorPanel(g, "Can only rename topmost commit")
|
||||||
}
|
}
|
||||||
gui.createPromptPanel(g, v, "Rename Commit", func(g *gocui.Gui, v *gocui.View) error {
|
gui.createPromptPanel(g, v, "Rename Commit", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.RenameCommit(v.Buffer()); err != nil {
|
if err := gui.GitCommand.RenameCommit(v.Buffer()); err != nil {
|
||||||
return gui.createErrorPanel(g, output)
|
return gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
if err := gui.refreshCommits(g); err != nil {
|
if err := gui.refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -323,8 +323,8 @@ func (gui *Gui) refreshFiles(g *gocui.Gui) error {
|
|||||||
func (gui *Gui) pullFiles(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) pullFiles(g *gocui.Gui, v *gocui.View) error {
|
||||||
gui.createMessagePanel(g, v, "", "Pulling...")
|
gui.createMessagePanel(g, v, "", "Pulling...")
|
||||||
go func() {
|
go func() {
|
||||||
if output, err := gui.GitCommand.Pull(); err != nil {
|
if err := gui.GitCommand.Pull(); err != nil {
|
||||||
gui.createErrorPanel(g, output)
|
gui.createErrorPanel(g, err.Error())
|
||||||
} else {
|
} else {
|
||||||
gui.closeConfirmationPrompt(g)
|
gui.closeConfirmationPrompt(g)
|
||||||
gui.refreshCommits(g)
|
gui.refreshCommits(g)
|
||||||
@ -339,8 +339,8 @@ func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
|||||||
gui.createMessagePanel(g, v, "", "Pushing...")
|
gui.createMessagePanel(g, v, "", "Pushing...")
|
||||||
go func() {
|
go func() {
|
||||||
branchName := gui.State.Branches[0].Name
|
branchName := gui.State.Branches[0].Name
|
||||||
if output, err := gui.GitCommand.Push(branchName); err != nil {
|
if err := gui.GitCommand.Push(branchName); err != nil {
|
||||||
gui.createErrorPanel(g, output)
|
gui.createErrorPanel(g, err.Error())
|
||||||
} else {
|
} else {
|
||||||
gui.closeConfirmationPrompt(g)
|
gui.closeConfirmationPrompt(g)
|
||||||
gui.refreshCommits(g)
|
gui.refreshCommits(g)
|
||||||
@ -370,9 +370,8 @@ func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleAbortMerge(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleAbortMerge(g *gocui.Gui, v *gocui.View) error {
|
||||||
output, err := gui.GitCommand.AbortMerge()
|
if err := gui.GitCommand.AbortMerge(); err != nil {
|
||||||
if err != nil {
|
return gui.createErrorPanel(g, err.Error())
|
||||||
return gui.createErrorPanel(g, output)
|
|
||||||
}
|
}
|
||||||
gui.createMessagePanel(g, v, "", "Merge aborted")
|
gui.createMessagePanel(g, v, "", "Merge aborted")
|
||||||
gui.refreshStatus(g)
|
gui.refreshStatus(g)
|
||||||
|
@ -75,8 +75,8 @@ func (gui *Gui) stashDo(g *gocui.Gui, v *gocui.View, method string) error {
|
|||||||
if stashEntry == nil {
|
if stashEntry == nil {
|
||||||
return gui.createErrorPanel(g, "No stash to "+method)
|
return gui.createErrorPanel(g, "No stash to "+method)
|
||||||
}
|
}
|
||||||
if output, err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil {
|
if err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil {
|
||||||
gui.createErrorPanel(g, output)
|
gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
gui.refreshStashEntries(g)
|
gui.refreshStashEntries(g)
|
||||||
return gui.refreshFiles(g)
|
return gui.refreshFiles(g)
|
||||||
@ -84,8 +84,8 @@ func (gui *Gui) stashDo(g *gocui.Gui, v *gocui.View, method string) error {
|
|||||||
|
|
||||||
func (gui *Gui) handleStashSave(g *gocui.Gui, filesView *gocui.View) error {
|
func (gui *Gui) handleStashSave(g *gocui.Gui, filesView *gocui.View) error {
|
||||||
gui.createPromptPanel(g, filesView, "Stash changes", func(g *gocui.Gui, v *gocui.View) error {
|
gui.createPromptPanel(g, filesView, "Stash changes", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gui.GitCommand.StashSave(gui.trimmedContent(v)); err != nil {
|
if err := gui.GitCommand.StashSave(gui.trimmedContent(v)); err != nil {
|
||||||
gui.createErrorPanel(g, output)
|
gui.createErrorPanel(g, err.Error())
|
||||||
}
|
}
|
||||||
gui.refreshStashEntries(g)
|
gui.refreshStashEntries(g)
|
||||||
return gui.refreshFiles(g)
|
return gui.refreshFiles(g)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user