mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-27 12:32:37 +02:00
WIP
This commit is contained in:
parent
157dd309f7
commit
b4c078d565
@ -146,7 +146,7 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
|
||||
}
|
||||
|
||||
func (app *App) validateGitVersion() error {
|
||||
output, err := app.OSCommand.RunCommandWithOutput("git --version")
|
||||
output, err := app.OSCommand.RunWithOutput(app.OSCommand.NewCmdObj("git --version"))
|
||||
// if we get an error anywhere here we'll show the same status
|
||||
minVersionError := errors.New(app.Tr.MinGitVersionError)
|
||||
if err != nil {
|
||||
@ -231,7 +231,7 @@ func (app *App) setupRepo() (bool, error) {
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := app.OSCommand.RunCommand("git init"); err != nil {
|
||||
if err := app.OSCommand.Run(app.OSCommand.NewCmdObj("git init")); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,19 @@ import (
|
||||
|
||||
// NewBranch create new branch
|
||||
func (c *GitCommand) NewBranch(name string, base string) error {
|
||||
return c.RunCommand("git checkout -b %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(base))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git checkout -b %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(base))))
|
||||
}
|
||||
|
||||
// CurrentBranchName get the current branch name and displayname.
|
||||
// the first returned string is the name and the second is the displayname
|
||||
// e.g. name is 123asdf and displayname is '(HEAD detached at 123asdf)'
|
||||
func (c *GitCommand) CurrentBranchName() (string, string, error) {
|
||||
branchName, err := c.RunCommandWithOutput("git symbolic-ref --short HEAD")
|
||||
branchName, err := c.RunWithOutput(c.NewCmdObj("git symbolic-ref --short HEAD"))
|
||||
if err == nil && branchName != "HEAD\n" {
|
||||
trimmedBranchName := strings.TrimSpace(branchName)
|
||||
return trimmedBranchName, trimmedBranchName, nil
|
||||
}
|
||||
output, err := c.RunCommandWithOutput("git branch --contains")
|
||||
output, err := c.RunWithOutput(c.NewCmdObj("git branch --contains"))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
@ -47,7 +47,7 @@ func (c *GitCommand) DeleteBranch(branch string, force bool) error {
|
||||
command = "git branch -D"
|
||||
}
|
||||
|
||||
return c.OSCommand.RunCommand("%s %s", command, c.OSCommand.Quote(branch))
|
||||
return c.OSCommand.Run(c.OSCommand.NewCmdObj(fmt.Sprintf("%s %s", command, c.OSCommand.Quote(branch))))
|
||||
}
|
||||
|
||||
// Checkout checks out a branch (or commit), with --force if you set the force arg to true
|
||||
@ -61,36 +61,42 @@ func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error {
|
||||
if options.Force {
|
||||
forceArg = " --force"
|
||||
}
|
||||
return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git checkout%s %s", forceArg, c.OSCommand.Quote(branch)), oscommands.RunCommandOptions{EnvVars: options.EnvVars})
|
||||
|
||||
cmdObj := c.NewCmdObj(fmt.Sprintf("git checkout%s %s", forceArg, c.OSCommand.Quote(branch))).
|
||||
// prevents git from prompting us for input which would freeze the program
|
||||
// TODO: see if this is actually needed here
|
||||
AddEnvVars("GIT_TERMINAL_PROMPT=0").
|
||||
AddEnvVars(options.EnvVars...)
|
||||
|
||||
return c.OSCommand.Run(cmdObj)
|
||||
}
|
||||
|
||||
// GetBranchGraph gets the color-formatted graph of the log for the given branch
|
||||
// Currently it limits the result to 100 commits, but when we get async stuff
|
||||
// working we can do lazy loading
|
||||
func (c *GitCommand) GetBranchGraph(branchName string) (string, error) {
|
||||
cmdStr := c.GetBranchGraphCmdStr(branchName)
|
||||
return c.OSCommand.RunCommandWithOutput(cmdStr)
|
||||
return c.OSCommand.RunWithOutput(c.GetBranchGraphCmdObj(branchName))
|
||||
}
|
||||
|
||||
func (c *GitCommand) GetUpstreamForBranch(branchName string) (string, error) {
|
||||
output, err := c.RunCommandWithOutput("git rev-parse --abbrev-ref --symbolic-full-name %s@{u}", c.OSCommand.Quote(branchName))
|
||||
output, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git rev-parse --abbrev-ref --symbolic-full-name %s@{u}", c.OSCommand.Quote(branchName))))
|
||||
return strings.TrimSpace(output), err
|
||||
}
|
||||
|
||||
func (c *GitCommand) GetBranchGraphCmdStr(branchName string) string {
|
||||
func (c *GitCommand) GetBranchGraphCmdObj(branchName string) oscommands.ICmdObj {
|
||||
branchLogCmdTemplate := c.Config.GetUserConfig().Git.BranchLogCmd
|
||||
templateValues := map[string]string{
|
||||
"branchName": c.OSCommand.Quote(branchName),
|
||||
}
|
||||
return utils.ResolvePlaceholderString(branchLogCmdTemplate, templateValues)
|
||||
return c.NewCmdObj(utils.ResolvePlaceholderString(branchLogCmdTemplate, templateValues))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SetUpstreamBranch(upstream string) error {
|
||||
return c.RunCommand("git branch -u %s", c.OSCommand.Quote(upstream))
|
||||
return c.Run(c.NewCmdObj("git branch -u " + c.OSCommand.Quote(upstream)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SetBranchUpstream(remoteName string, remoteBranchName string, branchName string) error {
|
||||
return c.RunCommand("git branch --set-upstream-to=%s/%s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git branch --set-upstream-to=%s/%s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))))
|
||||
}
|
||||
|
||||
func (c *GitCommand) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
|
||||
@ -105,11 +111,11 @@ func (c *GitCommand) GetBranchUpstreamDifferenceCount(branchName string) (string
|
||||
// current branch
|
||||
func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
|
||||
command := "git rev-list %s..%s --count"
|
||||
pushableCount, err := c.OSCommand.RunCommandWithOutput(command, to, from)
|
||||
pushableCount, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf(command, to, from)))
|
||||
if err != nil {
|
||||
return "?", "?"
|
||||
}
|
||||
pullableCount, err := c.OSCommand.RunCommandWithOutput(command, from, to)
|
||||
pullableCount, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf(command, from, to)))
|
||||
if err != nil {
|
||||
return "?", "?"
|
||||
}
|
||||
@ -129,33 +135,33 @@ func (c *GitCommand) Merge(branchName string, opts MergeOpts) error {
|
||||
command = fmt.Sprintf("%s --ff-only", command)
|
||||
}
|
||||
|
||||
return c.OSCommand.RunCommand(command)
|
||||
return c.OSCommand.Run(c.OSCommand.NewCmdObj(command))
|
||||
}
|
||||
|
||||
// AbortMerge abort merge
|
||||
func (c *GitCommand) AbortMerge() error {
|
||||
return c.RunCommand("git merge --abort")
|
||||
return c.Run(c.NewCmdObj("git merge --abort"))
|
||||
}
|
||||
|
||||
func (c *GitCommand) IsHeadDetached() bool {
|
||||
err := c.RunCommand("git symbolic-ref -q HEAD")
|
||||
err := c.Run(c.NewCmdObj("git symbolic-ref -q HEAD"))
|
||||
return err != nil
|
||||
}
|
||||
|
||||
// ResetHardHead runs `git reset --hard`
|
||||
func (c *GitCommand) ResetHard(ref string) error {
|
||||
return c.RunCommand("git reset --hard " + c.OSCommand.Quote(ref))
|
||||
return c.Run(c.NewCmdObj("git reset --hard " + c.OSCommand.Quote(ref)))
|
||||
}
|
||||
|
||||
// ResetSoft runs `git reset --soft HEAD`
|
||||
func (c *GitCommand) ResetSoft(ref string) error {
|
||||
return c.RunCommand("git reset --soft " + c.OSCommand.Quote(ref))
|
||||
return c.Run(c.NewCmdObj("git reset --soft " + c.OSCommand.Quote(ref)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) ResetMixed(ref string) error {
|
||||
return c.RunCommand("git reset --mixed " + c.OSCommand.Quote(ref))
|
||||
return c.Run(c.NewCmdObj("git reset --mixed " + c.OSCommand.Quote(ref)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) RenameBranch(oldName string, newName string) error {
|
||||
return c.RunCommand("git branch --move %s %s", c.OSCommand.Quote(oldName), c.OSCommand.Quote(newName))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git branch --move %s %s", c.OSCommand.Quote(oldName), c.OSCommand.Quote(newName))))
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ func TestGitCommandGetAllBranchGraph(t *testing.T) {
|
||||
return secureexec.Command("echo")
|
||||
}
|
||||
cmdStr := gitCmd.Config.GetUserConfig().Git.AllBranchesLogCmd
|
||||
_, err := gitCmd.OSCommand.RunCommandWithOutput(cmdStr)
|
||||
_, err := gitCmd.OSCommand.RunWithOutput(gitCmd.NewCmdObj(cmdStr))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -10,15 +10,21 @@ import (
|
||||
|
||||
// RenameCommit renames the topmost commit with the given name
|
||||
func (c *GitCommand) RenameCommit(name string) error {
|
||||
return c.RunCommand("git commit --allow-empty --amend --only -m %s", c.OSCommand.Quote(name))
|
||||
return c.Run(c.NewCmdObj("git commit --allow-empty --amend --only -m " + c.OSCommand.Quote(name)))
|
||||
}
|
||||
|
||||
// ResetToCommit reset to commit
|
||||
func (c *GitCommand) ResetToCommit(sha string, strength string, options oscommands.RunCommandOptions) error {
|
||||
return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git reset --%s %s", strength, sha), options)
|
||||
func (c *GitCommand) ResetToCommit(sha string, strength string, envVars []string) error {
|
||||
cmdObj := c.NewCmdObj(fmt.Sprintf("git reset --%s %s", strength, sha)).
|
||||
// prevents git from prompting us for input which would freeze the program
|
||||
// TODO: see if this is actually needed here
|
||||
AddEnvVars("GIT_TERMINAL_PROMPT=0").
|
||||
AddEnvVars(envVars...)
|
||||
|
||||
return c.OSCommand.Run(cmdObj)
|
||||
}
|
||||
|
||||
func (c *GitCommand) CommitCmdStr(message string, flags string) string {
|
||||
func (c *GitCommand) CommitCmdObj(message string, flags string) oscommands.ICmdObj {
|
||||
splitMessage := strings.Split(message, "\n")
|
||||
lineArgs := ""
|
||||
for _, line := range splitMessage {
|
||||
@ -30,52 +36,53 @@ func (c *GitCommand) CommitCmdStr(message string, flags string) string {
|
||||
flagsStr = fmt.Sprintf(" %s", flags)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("git commit%s%s", flagsStr, lineArgs)
|
||||
return c.NewCmdObj(fmt.Sprintf("git commit%s%s", flagsStr, lineArgs))
|
||||
}
|
||||
|
||||
// Get the subject of the HEAD commit
|
||||
func (c *GitCommand) GetHeadCommitMessage() (string, error) {
|
||||
cmdStr := "git log -1 --pretty=%s"
|
||||
message, err := c.OSCommand.RunCommandWithOutput(cmdStr)
|
||||
message, err := c.RunWithOutput(c.NewCmdObj("git log -1 --pretty=%s"))
|
||||
return strings.TrimSpace(message), err
|
||||
}
|
||||
|
||||
func (c *GitCommand) GetCommitMessage(commitSha string) (string, error) {
|
||||
cmdStr := "git rev-list --format=%B --max-count=1 " + commitSha
|
||||
messageWithHeader, err := c.OSCommand.RunCommandWithOutput(cmdStr)
|
||||
messageWithHeader, err := c.RunWithOutput(c.NewCmdObj(cmdStr))
|
||||
message := strings.Join(strings.SplitAfter(messageWithHeader, "\n")[1:], "\n")
|
||||
return strings.TrimSpace(message), err
|
||||
}
|
||||
|
||||
func (c *GitCommand) GetCommitMessageFirstLine(sha string) (string, error) {
|
||||
return c.RunCommandWithOutput("git show --no-patch --pretty=format:%%s %s", sha)
|
||||
return c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git show --no-patch --pretty=format:%%s %s", sha)))
|
||||
}
|
||||
|
||||
// AmendHead amends HEAD with whatever is staged in your working tree
|
||||
func (c *GitCommand) AmendHead() error {
|
||||
return c.OSCommand.RunCommand(c.AmendHeadCmdStr())
|
||||
return c.OSCommand.Run(c.AmendHeadCmdObj())
|
||||
}
|
||||
|
||||
func (c *GitCommand) AmendHeadCmdStr() string {
|
||||
return "git commit --amend --no-edit --allow-empty"
|
||||
func (c *GitCommand) AmendHeadCmdObj() oscommands.ICmdObj {
|
||||
return c.NewCmdObj("git commit --amend --no-edit --allow-empty")
|
||||
}
|
||||
|
||||
func (c *GitCommand) ShowCmdStr(sha string, filterPath string) string {
|
||||
func (c *GitCommand) ShowCmdObj(sha string, filterPath string) oscommands.ICmdObj {
|
||||
contextSize := c.Config.GetUserConfig().Git.DiffContextSize
|
||||
filterPathArg := ""
|
||||
if filterPath != "" {
|
||||
filterPathArg = fmt.Sprintf(" -- %s", c.OSCommand.Quote(filterPath))
|
||||
}
|
||||
return fmt.Sprintf("git show --submodule --color=%s --unified=%d --no-renames --stat -p %s %s", c.colorArg(), contextSize, sha, filterPathArg)
|
||||
|
||||
cmdStr := fmt.Sprintf("git show --submodule --color=%s --unified=%d --no-renames --stat -p %s %s", c.colorArg(), contextSize, sha, filterPathArg)
|
||||
return c.NewCmdObj(cmdStr)
|
||||
}
|
||||
|
||||
// Revert reverts the selected commit by sha
|
||||
func (c *GitCommand) Revert(sha string) error {
|
||||
return c.RunCommand("git revert %s", sha)
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git revert %s", sha)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) RevertMerge(sha string, parentNumber int) error {
|
||||
return c.RunCommand("git revert %s -m %d", sha, parentNumber)
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git revert %s -m %d", sha, parentNumber)))
|
||||
}
|
||||
|
||||
// CherryPickCommits begins an interactive rebase with the given shas being cherry picked onto HEAD
|
||||
@ -90,10 +97,10 @@ func (c *GitCommand) CherryPickCommits(commits []*models.Commit) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.OSCommand.RunPreparedCommand(cmd)
|
||||
return c.OSCommand.Run(cmd)
|
||||
}
|
||||
|
||||
// CreateFixupCommit creates a commit that fixes up a previous commit
|
||||
func (c *GitCommand) CreateFixupCommit(sha string) error {
|
||||
return c.RunCommand("git commit --fixup=%s", sha)
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git commit --fixup=%s", sha)))
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
||||
"github.com/jesseduffield/lazygit/pkg/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -33,11 +32,11 @@ func TestGitCommandResetToCommit(t *testing.T) {
|
||||
return secureexec.Command("echo")
|
||||
}
|
||||
|
||||
assert.NoError(t, gitCmd.ResetToCommit("78976bc", "hard", oscommands.RunCommandOptions{}))
|
||||
assert.NoError(t, gitCmd.ResetToCommit("78976bc", "hard", []string{}))
|
||||
}
|
||||
|
||||
// TestGitCommandCommitStr is a function.
|
||||
func TestGitCommandCommitStr(t *testing.T) {
|
||||
// TestGitCommandCommitObj is a function.
|
||||
func TestGitCommandCommitObj(t *testing.T) {
|
||||
gitCmd := NewDummyGitCommand()
|
||||
|
||||
type scenario struct {
|
||||
@ -70,7 +69,7 @@ func TestGitCommandCommitStr(t *testing.T) {
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
cmdStr := gitCmd.CommitCmdStr(s.message, s.flags)
|
||||
cmdStr := gitCmd.CommitCmdObj(s.message, s.flags).ToString()
|
||||
assert.Equal(t, s.expected, cmdStr)
|
||||
})
|
||||
}
|
||||
@ -111,8 +110,8 @@ func TestGitCommandCreateFixupCommit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestGitCommandShowCmdStr is a function.
|
||||
func TestGitCommandShowCmdStr(t *testing.T) {
|
||||
// TestGitCommandShowCmdObj is a function.
|
||||
func TestGitCommandShowCmdObj(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
filterPath string
|
||||
@ -146,7 +145,7 @@ func TestGitCommandShowCmdStr(t *testing.T) {
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
gitCmd.Config.GetUserConfig().Git.DiffContextSize = s.contextSize
|
||||
cmdStr := gitCmd.ShowCmdStr("1234567890", s.filterPath)
|
||||
cmdStr := gitCmd.ShowCmdObj("1234567890", s.filterPath).ToString()
|
||||
assert.Equal(t, s.expected, cmdStr)
|
||||
})
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -23,27 +24,27 @@ func (c *GitCommand) CatFile(fileName string) (string, error) {
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
func (c *GitCommand) OpenMergeToolCmd() string {
|
||||
return "git mergetool"
|
||||
func (c *GitCommand) OpenMergeToolCmdObj() oscommands.ICmdObj {
|
||||
return c.NewCmdObj("git mergetool")
|
||||
}
|
||||
|
||||
func (c *GitCommand) OpenMergeTool() error {
|
||||
return c.OSCommand.RunCommand("git mergetool")
|
||||
return c.Run(c.OpenMergeToolCmdObj())
|
||||
}
|
||||
|
||||
// StageFile stages a file
|
||||
func (c *GitCommand) StageFile(fileName string) error {
|
||||
return c.RunCommand("git add -- %s", c.OSCommand.Quote(fileName))
|
||||
return c.Run(c.NewCmdObj("git add -- " + c.OSCommand.Quote(fileName)))
|
||||
}
|
||||
|
||||
// StageAll stages all files
|
||||
func (c *GitCommand) StageAll() error {
|
||||
return c.RunCommand("git add -A")
|
||||
return c.Run(c.NewCmdObj("git add -A"))
|
||||
}
|
||||
|
||||
// UnstageAll unstages all files
|
||||
func (c *GitCommand) UnstageAll() error {
|
||||
return c.RunCommand("git reset")
|
||||
return c.Run(c.NewCmdObj("git reset"))
|
||||
}
|
||||
|
||||
// UnStageFile unstages a file
|
||||
@ -56,7 +57,8 @@ func (c *GitCommand) UnStageFile(fileNames []string, reset bool) error {
|
||||
}
|
||||
|
||||
for _, name := range fileNames {
|
||||
if err := c.OSCommand.RunCommand(command, c.OSCommand.Quote(name)); err != nil {
|
||||
cmdObj := c.NewCmdObj(fmt.Sprintf(command, c.OSCommand.Quote(name)))
|
||||
if err := c.Run(cmdObj); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -120,22 +122,22 @@ func (c *GitCommand) DiscardAllFileChanges(file *models.File) error {
|
||||
quotedFileName := c.OSCommand.Quote(file.Name)
|
||||
|
||||
if file.ShortStatus == "AA" {
|
||||
if err := c.RunCommand("git checkout --ours -- %s", quotedFileName); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git checkout --ours -- " + quotedFileName)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.RunCommand("git add -- %s", quotedFileName); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git add -- " + quotedFileName)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if file.ShortStatus == "DU" {
|
||||
return c.RunCommand("git rm -- %s", quotedFileName)
|
||||
return c.Run(c.NewCmdObj("git rm -- " + quotedFileName))
|
||||
}
|
||||
|
||||
// if the file isn't tracked, we assume you want to delete it
|
||||
if file.HasStagedChanges || file.HasMergeConflicts {
|
||||
if err := c.RunCommand("git reset -- %s", quotedFileName); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git reset -- " + quotedFileName)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -161,7 +163,7 @@ func (c *GitCommand) DiscardUnstagedDirChanges(node *filetree.FileNode) error {
|
||||
}
|
||||
|
||||
quotedPath := c.OSCommand.Quote(node.GetPath())
|
||||
if err := c.RunCommand("git checkout -- %s", quotedPath); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git checkout -- " + quotedPath)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -186,7 +188,7 @@ func (c *GitCommand) RemoveUntrackedDirFiles(node *filetree.FileNode) error {
|
||||
// DiscardUnstagedFileChanges directly
|
||||
func (c *GitCommand) DiscardUnstagedFileChanges(file *models.File) error {
|
||||
quotedFileName := c.OSCommand.Quote(file.Name)
|
||||
return c.RunCommand("git checkout -- %s", quotedFileName)
|
||||
return c.Run(c.NewCmdObj("git checkout -- " + quotedFileName))
|
||||
}
|
||||
|
||||
// Ignore adds a file to the gitignore for the repo
|
||||
@ -197,11 +199,11 @@ func (c *GitCommand) Ignore(filename string) error {
|
||||
// WorktreeFileDiff returns the diff of a file
|
||||
func (c *GitCommand) WorktreeFileDiff(file *models.File, plain bool, cached bool, ignoreWhitespace bool) string {
|
||||
// for now we assume an error means the file was deleted
|
||||
s, _ := c.OSCommand.RunCommandWithOutput(c.WorktreeFileDiffCmdStr(file, plain, cached, ignoreWhitespace))
|
||||
s, _ := c.OSCommand.RunWithOutput(c.WorktreeFileDiffCmdObj(file, plain, cached, ignoreWhitespace))
|
||||
return s
|
||||
}
|
||||
|
||||
func (c *GitCommand) WorktreeFileDiffCmdStr(node models.IFile, plain bool, cached bool, ignoreWhitespace bool) string {
|
||||
func (c *GitCommand) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cached bool, ignoreWhitespace bool) oscommands.ICmdObj {
|
||||
cachedArg := ""
|
||||
trackedArg := "--"
|
||||
colorArg := c.colorArg()
|
||||
@ -221,7 +223,9 @@ func (c *GitCommand) WorktreeFileDiffCmdStr(node models.IFile, plain bool, cache
|
||||
ignoreWhitespaceArg = "--ignore-all-space"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --color=%s %s %s %s %s", contextSize, colorArg, ignoreWhitespaceArg, cachedArg, trackedArg, quotedPath)
|
||||
cmdStr := fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --color=%s %s %s %s %s", contextSize, colorArg, ignoreWhitespaceArg, cachedArg, trackedArg, quotedPath)
|
||||
|
||||
return c.NewCmdObj(cmdStr)
|
||||
}
|
||||
|
||||
func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
|
||||
@ -236,17 +240,17 @@ func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
|
||||
flagStr += " --" + flag
|
||||
}
|
||||
|
||||
return c.RunCommand("git apply %s %s", flagStr, c.OSCommand.Quote(filepath))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git apply %s %s", flagStr, c.OSCommand.Quote(filepath))))
|
||||
}
|
||||
|
||||
// ShowFileDiff get the diff of specified from and to. Typically this will be used for a single commit so it'll be 123abc^..123abc
|
||||
// but when we're in diff mode it could be any 'from' to any 'to'. The reverse flag is also here thanks to diff mode.
|
||||
func (c *GitCommand) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool) (string, error) {
|
||||
cmdStr := c.ShowFileDiffCmdStr(from, to, reverse, fileName, plain)
|
||||
return c.OSCommand.RunCommandWithOutput(cmdStr)
|
||||
cmdObj := c.ShowFileDiffCmdObj(from, to, reverse, fileName, plain)
|
||||
return c.RunWithOutput(cmdObj)
|
||||
}
|
||||
|
||||
func (c *GitCommand) ShowFileDiffCmdStr(from string, to string, reverse bool, fileName string, plain bool) string {
|
||||
func (c *GitCommand) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) oscommands.ICmdObj {
|
||||
colorArg := c.colorArg()
|
||||
contextSize := c.Config.GetUserConfig().Git.DiffContextSize
|
||||
if plain {
|
||||
@ -258,12 +262,12 @@ func (c *GitCommand) ShowFileDiffCmdStr(from string, to string, reverse bool, fi
|
||||
reverseFlag = " -R "
|
||||
}
|
||||
|
||||
return fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s %s %s %s -- %s", contextSize, colorArg, from, to, reverseFlag, c.OSCommand.Quote(fileName))
|
||||
return c.NewCmdObj(fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s %s %s %s -- %s", contextSize, colorArg, from, to, reverseFlag, c.OSCommand.Quote(fileName)))
|
||||
}
|
||||
|
||||
// CheckoutFile checks out the file for the given commit
|
||||
func (c *GitCommand) CheckoutFile(commitSha, fileName string) error {
|
||||
return c.RunCommand("git checkout %s -- %s", commitSha, c.OSCommand.Quote(fileName))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git checkout %s -- %s", commitSha, c.OSCommand.Quote(fileName))))
|
||||
}
|
||||
|
||||
// DiscardOldFileChanges discards changes to a file from an old commit
|
||||
@ -273,7 +277,7 @@ func (c *GitCommand) DiscardOldFileChanges(commits []*models.Commit, commitIndex
|
||||
}
|
||||
|
||||
// check if file exists in previous commit (this command returns an error if the file doesn't exist)
|
||||
if err := c.RunCommand("git cat-file -e HEAD^:%s", c.OSCommand.Quote(fileName)); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git cat-file -e HEAD^:" + c.OSCommand.Quote(fileName))); err != nil {
|
||||
if err := c.OSCommand.Remove(fileName); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -296,17 +300,17 @@ func (c *GitCommand) DiscardOldFileChanges(commits []*models.Commit, commitIndex
|
||||
|
||||
// DiscardAnyUnstagedFileChanges discards any unstages file changes via `git checkout -- .`
|
||||
func (c *GitCommand) DiscardAnyUnstagedFileChanges() error {
|
||||
return c.RunCommand("git checkout -- .")
|
||||
return c.Run(c.NewCmdObj("git checkout -- ."))
|
||||
}
|
||||
|
||||
// RemoveTrackedFiles will delete the given file(s) even if they are currently tracked
|
||||
func (c *GitCommand) RemoveTrackedFiles(name string) error {
|
||||
return c.RunCommand("git rm -r --cached -- %s", c.OSCommand.Quote(name))
|
||||
return c.Run(c.NewCmdObj("git rm -r --cached -- " + c.OSCommand.Quote(name)))
|
||||
}
|
||||
|
||||
// RemoveUntrackedFiles runs `git clean -fd`
|
||||
func (c *GitCommand) RemoveUntrackedFiles() error {
|
||||
return c.RunCommand("git clean -fd")
|
||||
return c.Run(c.NewCmdObj("git clean -fd"))
|
||||
}
|
||||
|
||||
// ResetAndClean removes all unstaged changes and removes all untracked files
|
||||
@ -346,7 +350,7 @@ func (c *GitCommand) EditFileCmdStr(filename string, lineNumber int) (string, er
|
||||
editor = c.OSCommand.Getenv("EDITOR")
|
||||
}
|
||||
if editor == "" {
|
||||
if err := c.OSCommand.RunCommand("which vi"); err == nil {
|
||||
if err := c.OSCommand.Run(c.NewCmdObj("which vi")); err == nil {
|
||||
editor = "vi"
|
||||
}
|
||||
}
|
||||
|
@ -223,22 +223,22 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam
|
||||
}
|
||||
|
||||
func VerifyInGitRepo(osCommand *oscommands.OSCommand) error {
|
||||
return osCommand.RunCommand("git rev-parse --git-dir")
|
||||
return osCommand.Run(osCommand.NewCmdObj("git rev-parse --git-dir"))
|
||||
}
|
||||
|
||||
func (c *GitCommand) RunCommand(formatString string, formatArgs ...interface{}) error {
|
||||
_, err := c.RunCommandWithOutput(formatString, formatArgs...)
|
||||
func (c *GitCommand) Run(cmdObj oscommands.ICmdObj) error {
|
||||
_, err := c.RunWithOutput(cmdObj)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *GitCommand) RunCommandWithOutput(formatString string, formatArgs ...interface{}) (string, error) {
|
||||
func (c *GitCommand) RunWithOutput(cmdObj oscommands.ICmdObj) (string, error) {
|
||||
// TODO: have this retry logic in other places we run the command
|
||||
waitTime := 50 * time.Millisecond
|
||||
retryCount := 5
|
||||
attempt := 0
|
||||
|
||||
for {
|
||||
output, err := c.OSCommand.RunCommandWithOutput(formatString, formatArgs...)
|
||||
output, err := c.OSCommand.RunWithOutput(cmdObj)
|
||||
if err != nil {
|
||||
// if we have an error based on the index lock, we should wait a bit and then retry
|
||||
if strings.Contains(output, ".git/index.lock") {
|
||||
@ -255,6 +255,12 @@ func (c *GitCommand) RunCommandWithOutput(formatString string, formatArgs ...int
|
||||
}
|
||||
}
|
||||
|
||||
func (c *GitCommand) NewCmdObjFromStr(cmdStr string) oscommands.ICmdObj {
|
||||
return c.OSCommand.NewCmdObjFromStr(cmdStr).AddEnvVars("GIT_OPTIONAL_LOCKS=0")
|
||||
func (c *GitCommand) NewCmdObj(cmdStr string) oscommands.ICmdObj {
|
||||
return c.OSCommand.NewCmdObj(cmdStr).AddEnvVars("GIT_OPTIONAL_LOCKS=0")
|
||||
}
|
||||
|
||||
func (c *GitCommand) NewCmdObjWithLog(cmdStr string) oscommands.ICmdObj {
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
c.OSCommand.LogCmdObj(cmdObj)
|
||||
return cmdObj
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func NewBranchListBuilder(log *logrus.Entry, gitCommand *GitCommand, reflogCommi
|
||||
|
||||
func (b *BranchListBuilder) obtainBranches() []*models.Branch {
|
||||
cmdStr := `git for-each-ref --sort=-committerdate --format="%(HEAD)|%(refname:short)|%(upstream:short)|%(upstream:track)" refs/heads`
|
||||
output, err := b.GitCommand.OSCommand.RunCommandWithOutput(cmdStr)
|
||||
output, err := b.GitCommand.RunWithOutput(b.GitCommand.NewCmdObj(cmdStr))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
@ -13,7 +14,7 @@ func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool) ([]*mo
|
||||
reverseFlag = " -R "
|
||||
}
|
||||
|
||||
filenames, err := c.RunCommandWithOutput("git diff --submodule --no-ext-diff --name-status -z --no-renames %s %s %s", reverseFlag, from, to)
|
||||
filenames, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git diff --submodule --no-ext-diff --name-status -z --no-renames %s %s %s", reverseFlag, from, to)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@ -153,9 +152,9 @@ func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Commit
|
||||
passedFirstPushedCommit = true
|
||||
}
|
||||
|
||||
cmd := c.getLogCmd(opts)
|
||||
cmdObj := c.getLogCmd(opts)
|
||||
|
||||
err = oscommands.RunLineOutputCmd(cmd, func(line string) (bool, error) {
|
||||
err = c.OSCommand.RunLineOutputCmd(cmdObj, func(line string) (bool, error) {
|
||||
if canExtractCommit(line) {
|
||||
commit := c.extractCommitFromLine(line)
|
||||
if commit.Sha == firstPushedCommit {
|
||||
@ -201,7 +200,7 @@ func (c *CommitListBuilder) getHydratedRebasingCommits(rebaseMode string) ([]*mo
|
||||
|
||||
// note that we're not filtering these as we do non-rebasing commits just because
|
||||
// I suspect that will cause some damage
|
||||
cmd := c.OSCommand.ExecutableFromString(
|
||||
cmdObj := c.OSCommand.NewCmdObj(
|
||||
fmt.Sprintf(
|
||||
"git show %s --no-patch --oneline %s --abbrev=%d",
|
||||
strings.Join(commitShas, " "),
|
||||
@ -212,7 +211,7 @@ func (c *CommitListBuilder) getHydratedRebasingCommits(rebaseMode string) ([]*mo
|
||||
|
||||
hydratedCommits := make([]*models.Commit, 0, len(commits))
|
||||
i := 0
|
||||
err = oscommands.RunLineOutputCmd(cmd, func(line string) (bool, error) {
|
||||
err = c.OSCommand.RunLineOutputCmd(cmdObj, func(line string) (bool, error) {
|
||||
if canExtractCommit(line) {
|
||||
commit := c.extractCommitFromLine(line)
|
||||
matchingCommit := commits[i]
|
||||
@ -374,7 +373,7 @@ func (c *CommitListBuilder) getMergeBase(refName string) (string, error) {
|
||||
}
|
||||
|
||||
// swallowing error because it's not a big deal; probably because there are no commits yet
|
||||
output, _ := c.OSCommand.RunCommandWithOutput("git merge-base %s %s", c.OSCommand.Quote(refName), c.OSCommand.Quote(baseBranch))
|
||||
output, _ := c.OSCommand.RunWithOutput(c.OSCommand.NewCmdObj(fmt.Sprintf("git merge-base %s %s", c.OSCommand.Quote(refName), c.OSCommand.Quote(baseBranch))))
|
||||
return ignoringWarnings(output), nil
|
||||
}
|
||||
|
||||
@ -391,7 +390,7 @@ func ignoringWarnings(commandOutput string) string {
|
||||
// getFirstPushedCommit returns the first commit SHA which has been pushed to the ref's upstream.
|
||||
// all commits above this are deemed unpushed and marked as such.
|
||||
func (c *CommitListBuilder) getFirstPushedCommit(refName string) (string, error) {
|
||||
output, err := c.OSCommand.RunCommandWithOutput("git merge-base %s %s@{u}", c.OSCommand.Quote(refName), c.OSCommand.Quote(refName))
|
||||
output, err := c.OSCommand.RunWithOutput(c.OSCommand.NewCmdObj(fmt.Sprintf("git merge-base %s %s@{u}", c.OSCommand.Quote(refName), c.OSCommand.Quote(refName))))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -400,7 +399,7 @@ func (c *CommitListBuilder) getFirstPushedCommit(refName string) (string, error)
|
||||
}
|
||||
|
||||
// getLog gets the git log.
|
||||
func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) *exec.Cmd {
|
||||
func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj {
|
||||
limitFlag := ""
|
||||
if opts.Limit {
|
||||
limitFlag = "-300"
|
||||
@ -419,7 +418,7 @@ func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) *exec.Cmd {
|
||||
allFlag = " --all"
|
||||
}
|
||||
|
||||
return c.OSCommand.ExecutableFromString(
|
||||
return c.OSCommand.NewCmdObj(
|
||||
fmt.Sprintf(
|
||||
"git log %s %s %s --oneline %s %s --abbrev=%d %s",
|
||||
c.OSCommand.Quote(opts.RefName),
|
||||
|
@ -80,7 +80,7 @@ func (c *GitCommand) GitStatus(opts GitStatusOptions) ([]FileStatus, error) {
|
||||
noRenamesFlag = "--no-renames"
|
||||
}
|
||||
|
||||
statusLines, err := c.RunCommandWithOutput("git status %s --porcelain -z %s", opts.UntrackedFilesArg, noRenamesFlag)
|
||||
statusLines, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git status %s --porcelain -z %s", opts.UntrackedFilesArg, noRenamesFlag)))
|
||||
if err != nil {
|
||||
return []FileStatus{}, err
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
)
|
||||
|
||||
// GetReflogCommits only returns the new reflog commits since the given lastReflogCommit
|
||||
@ -19,9 +18,9 @@ func (c *GitCommand) GetReflogCommits(lastReflogCommit *models.Commit, filterPat
|
||||
filterPathArg = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(filterPath))
|
||||
}
|
||||
|
||||
cmd := c.OSCommand.ExecutableFromString(fmt.Sprintf(`git log -g --abbrev=20 --format="%%h %%ct %%gs" %s`, filterPathArg))
|
||||
cmdObj := c.OSCommand.NewCmdObj(fmt.Sprintf(`git log -g --abbrev=20 --format="%%h %%ct %%gs" %s`, filterPathArg))
|
||||
onlyObtainedNewReflogCommits := false
|
||||
err := oscommands.RunLineOutputCmd(cmd, func(line string) (bool, error) {
|
||||
err := c.OSCommand.RunLineOutputCmd(cmdObj, func(line string) (bool, error) {
|
||||
fields := strings.SplitN(line, " ", 3)
|
||||
if len(fields) <= 2 {
|
||||
return false, nil
|
||||
|
@ -10,9 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func (c *GitCommand) GetRemotes() ([]*models.Remote, error) {
|
||||
// get remote branches
|
||||
unescaped := "git branch -r"
|
||||
remoteBranchesStr, err := c.OSCommand.RunCommandWithOutput(unescaped)
|
||||
remoteBranchesStr, err := c.RunWithOutput(c.NewCmdObj("git branch -r"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -10,8 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func (c *GitCommand) getUnfilteredStashEntries() []*models.StashEntry {
|
||||
unescaped := "git stash list --pretty='%gs'"
|
||||
rawString, _ := c.OSCommand.RunCommandWithOutput(unescaped)
|
||||
rawString, _ := c.RunWithOutput(c.NewCmdObj("git stash list --pretty='%gs'"))
|
||||
stashEntries := []*models.StashEntry{}
|
||||
for i, line := range utils.SplitLines(rawString) {
|
||||
stashEntries = append(stashEntries, stashEntryFromLine(line, i))
|
||||
@ -25,7 +24,7 @@ func (c *GitCommand) GetStashEntries(filterPath string) []*models.StashEntry {
|
||||
return c.getUnfilteredStashEntries()
|
||||
}
|
||||
|
||||
rawString, err := c.RunCommandWithOutput("git stash list --name-only")
|
||||
rawString, err := c.RunWithOutput(c.NewCmdObj("git stash list --name-only"))
|
||||
if err != nil {
|
||||
return c.getUnfilteredStashEntries()
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
func (c *GitCommand) GetTags() ([]*models.Tag, error) {
|
||||
// get remote branches, sorted by creation date (descending)
|
||||
// see: https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortltkeygt
|
||||
remoteBranchesStr, err := c.OSCommand.RunCommandWithOutput(`git tag --list --sort=-creatordate`)
|
||||
remoteBranchesStr, err := c.OSCommand.RunWithOutput(c.NewCmdObj(`git tag --list --sort=-creatordate`))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ type ICmdObj interface {
|
||||
GetCmd() *exec.Cmd
|
||||
ToString() string
|
||||
AddEnvVars(...string) ICmdObj
|
||||
GetEnvVars() []string
|
||||
}
|
||||
|
||||
type CmdObj struct {
|
||||
@ -31,3 +32,7 @@ func (self *CmdObj) AddEnvVars(vars ...string) ICmdObj {
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *CmdObj) GetEnvVars() []string {
|
||||
return self.cmd.Env
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
|
||||
@ -29,14 +30,25 @@ type Platform struct {
|
||||
OpenLinkCommand string
|
||||
}
|
||||
|
||||
type ICommander interface {
|
||||
Run(ICmdObj) error
|
||||
RunWithOutput(ICmdObj) (string, error)
|
||||
}
|
||||
|
||||
type RealCommander struct {
|
||||
}
|
||||
|
||||
func (self *RealCommander) Run(cmdObj ICmdObj) error {
|
||||
return cmdObj.GetCmd().Run()
|
||||
}
|
||||
|
||||
// OSCommand holds all the os commands
|
||||
type OSCommand struct {
|
||||
Log *logrus.Entry
|
||||
Platform *Platform
|
||||
Config config.AppConfigurer
|
||||
Command func(string, ...string) *exec.Cmd
|
||||
BeforeExecuteCmd func(*exec.Cmd)
|
||||
Getenv func(string) string
|
||||
Log *logrus.Entry
|
||||
Platform *Platform
|
||||
Config config.AppConfigurer
|
||||
Command func(string, ...string) *exec.Cmd
|
||||
Getenv func(string) string
|
||||
|
||||
// callback to run before running a command, i.e. for the purposes of logging
|
||||
onRunCommand func(CmdLogEntry)
|
||||
@ -45,6 +57,8 @@ type OSCommand struct {
|
||||
CmdLogSpan string
|
||||
|
||||
removeFile func(string) error
|
||||
|
||||
IRunner
|
||||
}
|
||||
|
||||
// TODO: make these fields private
|
||||
@ -79,15 +93,17 @@ func NewCmdLogEntry(cmdStr string, span string, commandLine bool) CmdLogEntry {
|
||||
|
||||
// NewOSCommand os command runner
|
||||
func NewOSCommand(log *logrus.Entry, config config.AppConfigurer) *OSCommand {
|
||||
return &OSCommand{
|
||||
Log: log,
|
||||
Platform: getPlatform(),
|
||||
Config: config,
|
||||
Command: secureexec.Command,
|
||||
BeforeExecuteCmd: func(*exec.Cmd) {},
|
||||
Getenv: os.Getenv,
|
||||
removeFile: os.RemoveAll,
|
||||
c := &OSCommand{
|
||||
Log: log,
|
||||
Platform: getPlatform(),
|
||||
Config: config,
|
||||
Command: secureexec.Command,
|
||||
Getenv: os.Getenv,
|
||||
removeFile: os.RemoveAll,
|
||||
}
|
||||
|
||||
c.IRunner = &RealRunner{c: c}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *OSCommand) WithSpan(span string) *OSCommand {
|
||||
@ -104,8 +120,8 @@ func (c *OSCommand) WithSpan(span string) *OSCommand {
|
||||
return newOSCommand
|
||||
}
|
||||
|
||||
func (c *OSCommand) LogExecCmd(cmd *exec.Cmd) {
|
||||
c.LogCommand(strings.Join(cmd.Args, " "), true)
|
||||
func (c *OSCommand) LogCmdObj(cmdObj ICmdObj) {
|
||||
c.LogCommand(cmdObj.ToString(), true)
|
||||
}
|
||||
|
||||
func (c *OSCommand) LogCommand(cmdStr string, commandLine bool) {
|
||||
@ -131,108 +147,6 @@ func (c *OSCommand) SetRemoveFile(f func(string) error) {
|
||||
c.removeFile = f
|
||||
}
|
||||
|
||||
func (c *OSCommand) SetBeforeExecuteCmd(cmd func(*exec.Cmd)) {
|
||||
c.BeforeExecuteCmd = cmd
|
||||
}
|
||||
|
||||
type RunCommandOptions struct {
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
func (c *OSCommand) RunCommandWithOutputWithOptions(command string, options RunCommandOptions) (string, error) {
|
||||
c.LogCommand(command, true)
|
||||
cmd := c.ExecutableFromString(command)
|
||||
|
||||
cmd.Env = append(cmd.Env, "GIT_TERMINAL_PROMPT=0") // prevents git from prompting us for input which would freeze the program
|
||||
cmd.Env = append(cmd.Env, options.EnvVars...)
|
||||
|
||||
return sanitisedCommandOutput(cmd.CombinedOutput())
|
||||
}
|
||||
|
||||
func (c *OSCommand) RunCommandWithOptions(command string, options RunCommandOptions) error {
|
||||
_, err := c.RunCommandWithOutputWithOptions(command, options)
|
||||
return err
|
||||
}
|
||||
|
||||
// RunCommandWithOutput wrapper around commands returning their output and error
|
||||
// NOTE: If you don't pass any formatArgs we'll just use the command directly,
|
||||
// however there's a bizarre compiler error/warning when you pass in a formatString
|
||||
// with a percent sign because it thinks it's supposed to be a formatString when
|
||||
// in that case it's not. To get around that error you'll need to define the string
|
||||
// in a variable and pass the variable into RunCommandWithOutput.
|
||||
func (c *OSCommand) RunCommandWithOutput(formatString string, formatArgs ...interface{}) (string, error) {
|
||||
command := formatString
|
||||
if formatArgs != nil {
|
||||
command = fmt.Sprintf(formatString, formatArgs...)
|
||||
}
|
||||
cmd := c.ExecutableFromString(command)
|
||||
c.LogExecCmd(cmd)
|
||||
output, err := sanitisedCommandOutput(cmd.CombinedOutput())
|
||||
if err != nil {
|
||||
c.Log.WithField("command", command).Error(output)
|
||||
}
|
||||
return output, err
|
||||
}
|
||||
|
||||
// RunExecutableWithOutput runs an executable file and returns its output
|
||||
func (c *OSCommand) RunExecutableWithOutput(cmd *exec.Cmd) (string, error) {
|
||||
c.LogExecCmd(cmd)
|
||||
c.BeforeExecuteCmd(cmd)
|
||||
return sanitisedCommandOutput(cmd.CombinedOutput())
|
||||
}
|
||||
|
||||
// RunExecutable runs an executable file and returns an error if there was one
|
||||
func (c *OSCommand) RunExecutable(cmd *exec.Cmd) error {
|
||||
_, err := c.RunExecutableWithOutput(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecutableFromString takes a string like `git status` and returns an executable command for it
|
||||
func (c *OSCommand) ExecutableFromString(commandStr string) *exec.Cmd {
|
||||
splitCmd := str.ToArgv(commandStr)
|
||||
cmd := c.Command(splitCmd[0], splitCmd[1:]...)
|
||||
cmd.Env = append(os.Environ(), "GIT_OPTIONAL_LOCKS=0")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// ShellCommandFromString takes a string like `git commit` and returns an executable shell command for it
|
||||
func (c *OSCommand) ShellCommandFromString(commandStr string) *exec.Cmd {
|
||||
quotedCommand := ""
|
||||
// Windows does not seem to like quotes around the command
|
||||
if c.Platform.OS == "windows" {
|
||||
quotedCommand = strings.NewReplacer(
|
||||
"^", "^^",
|
||||
"&", "^&",
|
||||
"|", "^|",
|
||||
"<", "^<",
|
||||
">", "^>",
|
||||
"%", "^%",
|
||||
).Replace(commandStr)
|
||||
} else {
|
||||
quotedCommand = c.Quote(commandStr)
|
||||
}
|
||||
|
||||
shellCommand := fmt.Sprintf("%s %s %s", c.Platform.Shell, c.Platform.ShellArg, quotedCommand)
|
||||
return c.ExecutableFromString(shellCommand)
|
||||
}
|
||||
|
||||
// RunCommand runs a command and just returns the error
|
||||
func (c *OSCommand) RunCommand(formatString string, formatArgs ...interface{}) error {
|
||||
_, err := c.RunCommandWithOutput(formatString, formatArgs...)
|
||||
return err
|
||||
}
|
||||
|
||||
// RunShellCommand runs shell commands i.e. 'sh -c <command>'. Good for when you
|
||||
// need access to the shell
|
||||
func (c *OSCommand) RunShellCommand(command string) error {
|
||||
cmd := c.ShellCommandFromString(command)
|
||||
c.LogExecCmd(cmd)
|
||||
|
||||
_, err := sanitisedCommandOutput(cmd.CombinedOutput())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// FileType tells us if the file is a file, directory or other
|
||||
func (c *OSCommand) FileType(path string) string {
|
||||
fileInfo, err := os.Stat(path)
|
||||
@ -245,19 +159,6 @@ func (c *OSCommand) FileType(path string) string {
|
||||
return "file"
|
||||
}
|
||||
|
||||
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||
outputString := string(output)
|
||||
if err != nil {
|
||||
// errors like 'exit status 1' are not very useful so we'll create an error
|
||||
// from the combined output
|
||||
if outputString == "" {
|
||||
return "", utils.WrapError(err)
|
||||
}
|
||||
return outputString, errors.New(outputString)
|
||||
}
|
||||
return outputString, nil
|
||||
}
|
||||
|
||||
// OpenFile opens a file with the given
|
||||
func (c *OSCommand) OpenFile(filename string) error {
|
||||
commandTemplate := c.Config.GetUserConfig().OS.OpenCommand
|
||||
@ -265,7 +166,7 @@ func (c *OSCommand) OpenFile(filename string) error {
|
||||
"filename": c.Quote(filename),
|
||||
}
|
||||
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
||||
err := c.RunShellCommand(command)
|
||||
err := c.Run(c.NewShellCmdObjFromString(command))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -278,26 +179,10 @@ func (c *OSCommand) OpenLink(link string) error {
|
||||
}
|
||||
|
||||
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
||||
err := c.RunShellCommand(command)
|
||||
err := c.Run(c.NewShellCmdObjFromString(command))
|
||||
return err
|
||||
}
|
||||
|
||||
// PrepareSubProcess iniPrepareSubProcessrocess then tells the Gui to switch to it
|
||||
// TODO: see if this needs to exist, given that ExecutableFromString does the same things
|
||||
func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) *exec.Cmd {
|
||||
cmd := c.Command(cmdName, commandArgs...)
|
||||
if cmd != nil {
|
||||
cmd.Env = append(os.Environ(), "GIT_OPTIONAL_LOCKS=0")
|
||||
}
|
||||
c.LogExecCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// PrepareShellSubProcess returns the pointer to a custom command
|
||||
func (c *OSCommand) PrepareShellSubProcess(command string) *exec.Cmd {
|
||||
return c.PrepareSubProcess(c.Platform.Shell, c.Platform.ShellArg, command)
|
||||
}
|
||||
|
||||
// Quote wraps a message in platform-specific quotation marks
|
||||
func (c *OSCommand) Quote(message string) string {
|
||||
var quote string
|
||||
@ -390,24 +275,6 @@ func (c *OSCommand) FileExists(path string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// RunPreparedCommand takes a pointer to an exec.Cmd and runs it
|
||||
// this is useful if you need to give your command some environment variables
|
||||
// before running it
|
||||
func (c *OSCommand) RunPreparedCommand(cmd *exec.Cmd) error {
|
||||
c.BeforeExecuteCmd(cmd)
|
||||
c.LogExecCmd(cmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
outString := string(out)
|
||||
c.Log.Info(outString)
|
||||
if err != nil {
|
||||
if len(outString) == 0 {
|
||||
return err
|
||||
}
|
||||
return errors.New(outString)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLazygitPath returns the path of the currently executed file
|
||||
func (c *OSCommand) GetLazygitPath() string {
|
||||
ex, err := os.Executable() // get the executable path for git to use
|
||||
@ -426,7 +293,7 @@ func (c *OSCommand) PipeCommands(commandStrings ...string) error {
|
||||
logCmdStr += " | "
|
||||
}
|
||||
logCmdStr += str
|
||||
cmds[i] = c.ExecutableFromString(str)
|
||||
cmds[i] = c.NewCmdObj(str).GetCmd()
|
||||
}
|
||||
c.LogCommand(logCmdStr, true)
|
||||
|
||||
@ -489,7 +356,107 @@ func Kill(cmd *exec.Cmd) error {
|
||||
return cmd.Process.Kill()
|
||||
}
|
||||
|
||||
func RunLineOutputCmd(cmd *exec.Cmd, onLine func(line string) (bool, error)) error {
|
||||
func (c *OSCommand) CopyToClipboard(str string) error {
|
||||
escaped := strings.Replace(str, "\n", "\\n", -1)
|
||||
truncated := utils.TruncateWithEllipsis(escaped, 40)
|
||||
c.LogCommand(fmt.Sprintf("Copying '%s' to clipboard", truncated), false)
|
||||
return clipboard.WriteAll(str)
|
||||
}
|
||||
|
||||
func (c *OSCommand) RemoveFile(path string) error {
|
||||
c.LogCommand(fmt.Sprintf("Deleting path '%s'", path), false)
|
||||
|
||||
return c.removeFile(path)
|
||||
}
|
||||
|
||||
// builders
|
||||
|
||||
func (c *OSCommand) NewCmdObj(cmdStr string) ICmdObj {
|
||||
args := str.ToArgv(cmdStr)
|
||||
cmd := c.Command(args[0], args[1:]...)
|
||||
cmd.Env = os.Environ()
|
||||
|
||||
return &CmdObj{
|
||||
cmdStr: cmdStr,
|
||||
cmd: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *OSCommand) NewCmdObjFromArgs(args []string) ICmdObj {
|
||||
cmd := c.Command(args[0], args[1:]...)
|
||||
cmd.Env = os.Environ()
|
||||
|
||||
return &CmdObj{
|
||||
cmdStr: strings.Join(args, " "),
|
||||
cmd: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
// NewShellCmdObjFromString takes a string like `git commit` and returns an executable shell command for it
|
||||
func (c *OSCommand) NewShellCmdObjFromString(commandStr string) ICmdObj {
|
||||
quotedCommand := ""
|
||||
// Windows does not seem to like quotes around the command
|
||||
if c.Platform.OS == "windows" {
|
||||
quotedCommand = strings.NewReplacer(
|
||||
"^", "^^",
|
||||
"&", "^&",
|
||||
"|", "^|",
|
||||
"<", "^<",
|
||||
">", "^>",
|
||||
"%", "^%",
|
||||
).Replace(commandStr)
|
||||
} else {
|
||||
quotedCommand = c.Quote(commandStr)
|
||||
}
|
||||
|
||||
shellCommand := fmt.Sprintf("%s %s %s", c.Platform.Shell, c.Platform.ShellArg, quotedCommand)
|
||||
return c.NewCmdObj(shellCommand)
|
||||
}
|
||||
|
||||
// TODO: pick one of NewShellCmdObjFromString2 and ShellCommandFromString to use. I'm not sure
|
||||
// which one actually is better, but I suspect it's NewShellCmdObjFromString2
|
||||
func (c *OSCommand) NewShellCmdObjFromString2(command string) ICmdObj {
|
||||
return c.NewCmdObjFromArgs([]string{c.Platform.Shell, c.Platform.ShellArg, command})
|
||||
}
|
||||
|
||||
// runners
|
||||
|
||||
type IRunner interface {
|
||||
Run(cmdObj ICmdObj) error
|
||||
RunWithOutput(cmdObj ICmdObj) (string, error)
|
||||
RunLineOutputCmd(cmdObj ICmdObj, onLine func(line string) (bool, error)) error
|
||||
}
|
||||
|
||||
type RunExpectation func(ICmdObj) (string, error)
|
||||
|
||||
type FakeRunner struct {
|
||||
expectations []RunExpectation
|
||||
}
|
||||
|
||||
func (self *RealRunner) Run(cmdObj ICmdObj) error {
|
||||
|
||||
}
|
||||
|
||||
type RealRunner struct {
|
||||
c *OSCommand
|
||||
}
|
||||
|
||||
func (self *RealRunner) Run(cmdObj ICmdObj) error {
|
||||
_, err := self.RunWithOutput(cmdObj)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *RealRunner) RunWithOutput(cmdObj ICmdObj) (string, error) {
|
||||
self.c.LogCmdObj(cmdObj)
|
||||
output, err := sanitisedCommandOutput(cmdObj.GetCmd().CombinedOutput())
|
||||
if err != nil {
|
||||
self.c.Log.WithField("command", cmdObj.ToString()).Error(output)
|
||||
}
|
||||
return output, err
|
||||
}
|
||||
|
||||
func (self *RealRunner) RunLineOutputCmd(cmdObj ICmdObj, onLine func(line string) (bool, error)) error {
|
||||
cmd := cmdObj.GetCmd()
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -518,42 +485,15 @@ func RunLineOutputCmd(cmd *exec.Cmd, onLine func(line string) (bool, error)) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *OSCommand) CopyToClipboard(str string) error {
|
||||
escaped := strings.Replace(str, "\n", "\\n", -1)
|
||||
truncated := utils.TruncateWithEllipsis(escaped, 40)
|
||||
c.LogCommand(fmt.Sprintf("Copying '%s' to clipboard", truncated), false)
|
||||
return clipboard.WriteAll(str)
|
||||
}
|
||||
|
||||
func (c *OSCommand) RemoveFile(path string) error {
|
||||
c.LogCommand(fmt.Sprintf("Deleting path '%s'", path), false)
|
||||
|
||||
return c.removeFile(path)
|
||||
}
|
||||
|
||||
func (c *OSCommand) NewCmdObjFromStr(cmdStr string) ICmdObj {
|
||||
args := str.ToArgv(cmdStr)
|
||||
cmd := c.Command(args[0], args[1:]...)
|
||||
cmd.Env = os.Environ()
|
||||
|
||||
return &CmdObj{
|
||||
cmdStr: cmdStr,
|
||||
cmd: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *OSCommand) NewCmdObjFromArgs(args []string) ICmdObj {
|
||||
cmd := c.Command(args[0], args[1:]...)
|
||||
|
||||
return &CmdObj{
|
||||
cmdStr: strings.Join(args, " "),
|
||||
cmd: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *OSCommand) NewCmdObj(cmd *exec.Cmd) ICmdObj {
|
||||
return &CmdObj{
|
||||
cmdStr: strings.Join(cmd.Args, " "),
|
||||
cmd: cmd,
|
||||
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||
outputString := string(output)
|
||||
if err != nil {
|
||||
// errors like 'exit status 1' are not very useful so we'll create an error
|
||||
// from the combined output
|
||||
if outputString == "" {
|
||||
return "", utils.WrapError(err)
|
||||
}
|
||||
return outputString, errors.New(outputString)
|
||||
}
|
||||
return outputString, nil
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestOSCommandRunCommandWithOutput is a function.
|
||||
func TestOSCommandRunCommandWithOutput(t *testing.T) {
|
||||
// TestOSCommandRunWithOutput is a function.
|
||||
func TestOSCommandRunWithOutput(t *testing.T) {
|
||||
type scenario struct {
|
||||
command string
|
||||
test func(string, error)
|
||||
@ -32,12 +32,13 @@ func TestOSCommandRunCommandWithOutput(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s.test(NewDummyOSCommand().RunCommandWithOutput(s.command))
|
||||
c := NewDummyOSCommand()
|
||||
s.test(NewDummyOSCommand().RunWithOutput(c.NewCmdObj(s.command)))
|
||||
}
|
||||
}
|
||||
|
||||
// TestOSCommandRunCommand is a function.
|
||||
func TestOSCommandRunCommand(t *testing.T) {
|
||||
// TestOSCommandRun is a function.
|
||||
func TestOSCommandRun(t *testing.T) {
|
||||
type scenario struct {
|
||||
command string
|
||||
test func(error)
|
||||
@ -53,7 +54,8 @@ func TestOSCommandRunCommand(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s.test(NewDummyOSCommand().RunCommand(s.command))
|
||||
c := NewDummyOSCommand()
|
||||
s.test(c.Run(c.NewCmdObj(s.command)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ func (c *GitCommand) MovePatchToSelectedCommit(commits []*models.Commit, sourceC
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.OSCommand.RunPreparedCommand(cmd); err != nil {
|
||||
if err := c.OSCommand.Run(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ func (c *GitCommand) PullPatchIntoNewCommit(commits []*models.Commit, commitIdx
|
||||
|
||||
head_message, _ := c.GetHeadCommitMessage()
|
||||
new_message := fmt.Sprintf("Split from \"%s\"", head_message)
|
||||
err := c.OSCommand.RunCommand(c.CommitCmdStr(new_message, ""))
|
||||
err := c.OSCommand.Run(c.CommitCmdObj(new_message, ""))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3,17 +3,15 @@ package commands
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/mgutz/str"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
)
|
||||
|
||||
func (c *GitCommand) RewordCommit(commits []*models.Commit, index int) (*exec.Cmd, error) {
|
||||
func (c *GitCommand) RewordCommit(commits []*models.Commit, index int) (oscommands.ICmdObj, error) {
|
||||
todo, sha, err := c.GenerateGenericRebaseTodo(commits, index, "reword")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -40,7 +38,7 @@ func (c *GitCommand) MoveCommitDown(commits []*models.Commit, index int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.OSCommand.RunPreparedCommand(cmd)
|
||||
return c.OSCommand.Run(cmd)
|
||||
}
|
||||
|
||||
func (c *GitCommand) InteractiveRebase(commits []*models.Commit, index int, action string) error {
|
||||
@ -54,13 +52,13 @@ func (c *GitCommand) InteractiveRebase(commits []*models.Commit, index int, acti
|
||||
return err
|
||||
}
|
||||
|
||||
return c.OSCommand.RunPreparedCommand(cmd)
|
||||
return c.OSCommand.Run(cmd)
|
||||
}
|
||||
|
||||
// PrepareInteractiveRebaseCommand returns the cmd for an interactive rebase
|
||||
// we tell git to run lazygit to edit the todo list, and we pass the client
|
||||
// lazygit a todo string to write to the todo file
|
||||
func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string, overrideEditor bool) (*exec.Cmd, error) {
|
||||
func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string, overrideEditor bool) (oscommands.ICmdObj, error) {
|
||||
ex := c.OSCommand.GetLazygitPath()
|
||||
|
||||
debug := "FALSE"
|
||||
@ -70,9 +68,8 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string
|
||||
|
||||
cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty %s", baseSha)
|
||||
c.Log.WithField("command", cmdStr).Info("RunCommand")
|
||||
splitCmd := str.ToArgv(cmdStr)
|
||||
|
||||
cmd := c.OSCommand.Command(splitCmd[0], splitCmd[1:]...)
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
|
||||
gitSequenceEditor := ex
|
||||
if todo == "" {
|
||||
@ -81,9 +78,7 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string
|
||||
c.OSCommand.LogCommand(fmt.Sprintf("Creating TODO file for interactive rebase: \n\n%s", todo), false)
|
||||
}
|
||||
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(
|
||||
cmd.Env,
|
||||
cmdObj.AddEnvVars(
|
||||
"LAZYGIT_CLIENT_COMMAND=INTERACTIVE_REBASE",
|
||||
"LAZYGIT_REBASE_TODO="+todo,
|
||||
"DEBUG="+debug,
|
||||
@ -93,10 +88,10 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string
|
||||
)
|
||||
|
||||
if overrideEditor {
|
||||
cmd.Env = append(cmd.Env, "GIT_EDITOR="+ex)
|
||||
cmdObj.AddEnvVars("GIT_EDITOR=" + ex)
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
return cmdObj, nil
|
||||
}
|
||||
|
||||
func (c *GitCommand) GenerateGenericRebaseTodo(commits []*models.Commit, actionIndex int, action string) (string, string, error) {
|
||||
@ -227,7 +222,7 @@ func (c *GitCommand) BeginInteractiveRebaseForCommit(commits []*models.Commit, c
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.OSCommand.RunPreparedCommand(cmd); err != nil {
|
||||
if err := c.OSCommand.Run(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -241,7 +236,7 @@ func (c *GitCommand) RebaseBranch(branchName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.OSCommand.RunPreparedCommand(cmd)
|
||||
return c.OSCommand.Run(cmd)
|
||||
}
|
||||
|
||||
// GenericMerge takes a commandType of "merge" or "rebase" and a command of "abort", "skip" or "continue"
|
||||
@ -276,14 +271,13 @@ func (c *GitCommand) GenericMergeOrRebaseAction(commandType string, command stri
|
||||
}
|
||||
|
||||
func (c *GitCommand) runSkipEditorCommand(command string) error {
|
||||
cmd := c.OSCommand.ExecutableFromString(command)
|
||||
cmdObj := c.OSCommand.NewCmdObj(command)
|
||||
lazyGitPath := c.OSCommand.GetLazygitPath()
|
||||
cmd.Env = append(
|
||||
cmd.Env,
|
||||
cmdObj.AddEnvVars(
|
||||
"LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY",
|
||||
"GIT_EDITOR="+lazyGitPath,
|
||||
"EDITOR="+lazyGitPath,
|
||||
"VISUAL="+lazyGitPath,
|
||||
)
|
||||
return c.OSCommand.RunExecutable(cmd)
|
||||
return c.OSCommand.Run(cmdObj)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@ -62,31 +63,31 @@ func TestGitCommandRebaseBranch(t *testing.T) {
|
||||
func TestGitCommandSkipEditorCommand(t *testing.T) {
|
||||
cmd := NewDummyGitCommand()
|
||||
|
||||
cmd.OSCommand.SetBeforeExecuteCmd(func(cmd *exec.Cmd) {
|
||||
cmd.OSCommand.SetBeforeExecuteCmd(func(cmdObj oscommands.ICmdObj) {
|
||||
test.AssertContainsMatch(
|
||||
t,
|
||||
cmd.Env,
|
||||
cmdObj.GetEnvVars(),
|
||||
regexp.MustCompile("^VISUAL="),
|
||||
"expected VISUAL to be set for a non-interactive external command",
|
||||
)
|
||||
|
||||
test.AssertContainsMatch(
|
||||
t,
|
||||
cmd.Env,
|
||||
cmdObj.GetEnvVars(),
|
||||
regexp.MustCompile("^EDITOR="),
|
||||
"expected EDITOR to be set for a non-interactive external command",
|
||||
)
|
||||
|
||||
test.AssertContainsMatch(
|
||||
t,
|
||||
cmd.Env,
|
||||
cmdObj.GetEnvVars(),
|
||||
regexp.MustCompile("^GIT_EDITOR="),
|
||||
"expected GIT_EDITOR to be set for a non-interactive external command",
|
||||
)
|
||||
|
||||
test.AssertContainsMatch(
|
||||
t,
|
||||
cmd.Env,
|
||||
cmdObj.GetEnvVars(),
|
||||
regexp.MustCompile("^LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY$"),
|
||||
"expected LAZYGIT_CLIENT_COMMAND to be set for a non-interactive external command",
|
||||
)
|
||||
|
@ -7,24 +7,24 @@ import (
|
||||
)
|
||||
|
||||
func (c *GitCommand) AddRemote(name string, url string) error {
|
||||
return c.RunCommand("git remote add %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(url))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote add %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(url))))
|
||||
}
|
||||
|
||||
func (c *GitCommand) RemoveRemote(name string) error {
|
||||
return c.RunCommand("git remote remove %s", c.OSCommand.Quote(name))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote remove %s", c.OSCommand.Quote(name))))
|
||||
}
|
||||
|
||||
func (c *GitCommand) RenameRemote(oldRemoteName string, newRemoteName string) error {
|
||||
return c.RunCommand("git remote rename %s %s", c.OSCommand.Quote(oldRemoteName), c.OSCommand.Quote(newRemoteName))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote rename %s %s", c.OSCommand.Quote(oldRemoteName), c.OSCommand.Quote(newRemoteName))))
|
||||
}
|
||||
|
||||
func (c *GitCommand) UpdateRemoteUrl(remoteName string, updatedUrl string) error {
|
||||
return c.RunCommand("git remote set-url %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(updatedUrl))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote set-url %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(updatedUrl))))
|
||||
}
|
||||
|
||||
func (c *GitCommand) DeleteRemoteBranch(remoteName string, branchName string, promptUserForCredential func(string) string) error {
|
||||
command := fmt.Sprintf("git push %s --delete %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(branchName))
|
||||
cmdObj := c.NewCmdObjFromStr(command)
|
||||
cmdObj := c.NewCmdObj(command)
|
||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||
}
|
||||
|
||||
@ -34,10 +34,10 @@ func (c *GitCommand) DetectUnamePass(cmdObj oscommands.ICmdObj, promptUserForCre
|
||||
|
||||
// CheckRemoteBranchExists Returns remote branch
|
||||
func (c *GitCommand) CheckRemoteBranchExists(branchName string) bool {
|
||||
_, err := c.OSCommand.RunCommandWithOutput(
|
||||
"git show-ref --verify -- refs/remotes/origin/%s",
|
||||
c.OSCommand.Quote(branchName),
|
||||
)
|
||||
_, err := c.RunWithOutput(c.NewCmdObj(
|
||||
fmt.Sprintf("git show-ref --verify -- refs/remotes/origin/%s",
|
||||
c.OSCommand.Quote(branchName),
|
||||
)))
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ import "fmt"
|
||||
|
||||
// StashDo modify stash
|
||||
func (c *GitCommand) StashDo(index int, method string) error {
|
||||
return c.RunCommand("git stash %s stash@{%d}", method, index)
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git stash %s stash@{%d}", method, index)))
|
||||
}
|
||||
|
||||
// StashSave save stash
|
||||
// TODO: before calling this, check if there is anything to save
|
||||
func (c *GitCommand) StashSave(message string) error {
|
||||
return c.RunCommand("git stash save %s", c.OSCommand.Quote(message))
|
||||
return c.Run(c.NewCmdObj("git stash save " + c.OSCommand.Quote(message)))
|
||||
}
|
||||
|
||||
// GetStashEntryDiff stash diff
|
||||
@ -22,7 +22,7 @@ func (c *GitCommand) ShowStashEntryCmdStr(index int) string {
|
||||
// shoutouts to Joe on https://stackoverflow.com/questions/14759748/stashing-only-staged-changes-in-git-is-it-possible
|
||||
func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
||||
// wrap in 'writing', which uses a mutex
|
||||
if err := c.RunCommand("git stash --keep-index"); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git stash --keep-index")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.RunCommand("git stash apply stash@{1}"); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git stash apply stash@{1}")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.RunCommand("git stash drop stash@{1}"); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git stash drop stash@{1}")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,14 @@ package commands
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
)
|
||||
|
||||
// .gitmodules looks like this:
|
||||
@ -69,28 +71,28 @@ func (c *GitCommand) SubmoduleStash(submodule *models.SubmoduleConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.RunCommand("git -C %s stash --include-untracked", c.OSCommand.Quote(submodule.Path))
|
||||
return c.Run(c.NewCmdObj("git -C " + c.OSCommand.Quote(submodule.Path) + " stash --include-untracked"))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleReset(submodule *models.SubmoduleConfig) error {
|
||||
return c.RunCommand("git submodule update --init --force -- %s", c.OSCommand.Quote(submodule.Path))
|
||||
return c.Run(c.NewCmdObj("git submodule update --init --force -- " + c.OSCommand.Quote(submodule.Path)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleUpdateAll() error {
|
||||
// not doing an --init here because the user probably doesn't want that
|
||||
return c.RunCommand("git submodule update --force")
|
||||
return c.Run(c.NewCmdObj("git submodule update --force"))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
||||
// based on https://gist.github.com/myusuf3/7f645819ded92bda6677
|
||||
|
||||
if err := c.RunCommand("git submodule deinit --force -- %s", c.OSCommand.Quote(submodule.Path)); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git submodule deinit --force -- " + c.OSCommand.Quote(submodule.Path))); err != nil {
|
||||
if strings.Contains(err.Error(), "did not match any file(s) known to git") {
|
||||
if err := c.RunCommand("git config --file .gitmodules --remove-section submodule.%s", c.OSCommand.Quote(submodule.Name)); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git config --file .gitmodules --remove-section submodule." + c.OSCommand.Quote(submodule.Name))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.RunCommand("git config --remove-section submodule.%s", c.OSCommand.Quote(submodule.Name)); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git config --remove-section submodule." + c.OSCommand.Quote(submodule.Name))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -100,7 +102,7 @@ func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.RunCommand("git rm --force -r %s", submodule.Path); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git rm --force -r " + submodule.Path)); err != nil {
|
||||
// if the directory isn't there then that's fine
|
||||
c.Log.Error(err)
|
||||
}
|
||||
@ -109,21 +111,23 @@ func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleAdd(name string, path string, url string) error {
|
||||
return c.OSCommand.RunCommand(
|
||||
"git submodule add --force --name %s -- %s %s ",
|
||||
c.OSCommand.Quote(name),
|
||||
c.OSCommand.Quote(url),
|
||||
c.OSCommand.Quote(path),
|
||||
)
|
||||
return c.OSCommand.Run(
|
||||
c.OSCommand.NewCmdObj(
|
||||
fmt.Sprintf(
|
||||
"git submodule add --force --name %s -- %s %s ",
|
||||
c.OSCommand.Quote(name),
|
||||
c.OSCommand.Quote(url),
|
||||
c.OSCommand.Quote(path),
|
||||
)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleUpdateUrl(name string, path string, newUrl string) error {
|
||||
// the set-url command is only for later git versions so we're doing it manually here
|
||||
if err := c.RunCommand("git config --file .gitmodules submodule.%s.url %s", c.OSCommand.Quote(name), c.OSCommand.Quote(newUrl)); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git config --file .gitmodules submodule." + c.OSCommand.Quote(name) + ".url " + c.OSCommand.Quote(newUrl))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.RunCommand("git submodule sync -- %s", c.OSCommand.Quote(path)); err != nil {
|
||||
if err := c.Run(c.NewCmdObj("git submodule sync -- " + c.OSCommand.Quote(path))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -131,27 +135,27 @@ func (c *GitCommand) SubmoduleUpdateUrl(name string, path string, newUrl string)
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleInit(path string) error {
|
||||
return c.RunCommand("git submodule init -- %s", c.OSCommand.Quote(path))
|
||||
return c.Run(c.NewCmdObj("git submodule init -- " + c.OSCommand.Quote(path)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleUpdate(path string) error {
|
||||
return c.RunCommand("git submodule update --init -- %s", c.OSCommand.Quote(path))
|
||||
return c.Run(c.NewCmdObj("git submodule update --init -- " + c.OSCommand.Quote(path)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleBulkInitCmdStr() string {
|
||||
return "git submodule init"
|
||||
func (c *GitCommand) SubmoduleBulkInitCmdObj() oscommands.ICmdObj {
|
||||
return c.NewCmdObj("git submodule init")
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleBulkUpdateCmdStr() string {
|
||||
return "git submodule update"
|
||||
func (c *GitCommand) SubmoduleBulkUpdateCmdObj() oscommands.ICmdObj {
|
||||
return c.NewCmdObj("git submodule update")
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleForceBulkUpdateCmdStr() string {
|
||||
return "git submodule update --force"
|
||||
func (c *GitCommand) SubmoduleForceBulkUpdateCmdObj() oscommands.ICmdObj {
|
||||
return c.NewCmdObj("git submodule update --force")
|
||||
}
|
||||
|
||||
func (c *GitCommand) SubmoduleBulkDeinitCmdStr() string {
|
||||
return "git submodule deinit --all --force"
|
||||
func (c *GitCommand) SubmoduleBulkDeinitCmdObj() oscommands.ICmdObj {
|
||||
return c.NewCmdObj("git submodule deinit --all --force")
|
||||
}
|
||||
|
||||
func (c *GitCommand) ResetSubmodules(submodules []*models.SubmoduleConfig) error {
|
||||
|
@ -37,7 +37,7 @@ func (c *GitCommand) Push(opts PushOpts) error {
|
||||
cmdStr += " " + c.OSCommand.Quote(opts.UpstreamBranch)
|
||||
}
|
||||
|
||||
cmdObj := c.NewCmdObjFromStr(cmdStr)
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
return c.DetectUnamePass(cmdObj, opts.PromptUserForCredential)
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ func (c *GitCommand) Fetch(opts FetchOptions) error {
|
||||
cmdStr = fmt.Sprintf("%s %s", cmdStr, c.OSCommand.Quote(opts.BranchName))
|
||||
}
|
||||
|
||||
cmdObj := c.NewCmdObjFromStr(cmdStr)
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
return c.DetectUnamePass(cmdObj, func(question string) string {
|
||||
if opts.PromptUserForCredential != nil {
|
||||
return opts.PromptUserForCredential(question)
|
||||
@ -94,18 +94,18 @@ func (c *GitCommand) Pull(opts PullOptions) error {
|
||||
|
||||
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
|
||||
// has 'pull.rebase = interactive' configured.
|
||||
cmdObj := c.NewCmdObjFromStr(cmdStr).AddEnvVars("GIT_SEQUENCE_EDITOR=:")
|
||||
cmdObj := c.NewCmdObj(cmdStr).AddEnvVars("GIT_SEQUENCE_EDITOR=:")
|
||||
return c.DetectUnamePass(cmdObj, opts.PromptUserForCredential)
|
||||
}
|
||||
|
||||
func (c *GitCommand) FastForward(branchName string, remoteName string, remoteBranchName string, promptUserForCredential func(string) string) error {
|
||||
cmdStr := fmt.Sprintf("git fetch %s %s:%s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))
|
||||
cmdObj := c.NewCmdObjFromStr(cmdStr)
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||
}
|
||||
|
||||
func (c *GitCommand) FetchRemote(remoteName string, promptUserForCredential func(string) string) error {
|
||||
cmdStr := fmt.Sprintf("git fetch %s", c.OSCommand.Quote(remoteName))
|
||||
cmdObj := c.NewCmdObjFromStr(cmdStr)
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
func (c *GitCommand) CreateLightweightTag(tagName string, commitSha string) error {
|
||||
return c.RunCommand("git tag -- %s %s", c.OSCommand.Quote(tagName), commitSha)
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git tag -- %s %s", c.OSCommand.Quote(tagName), commitSha)))
|
||||
}
|
||||
|
||||
func (c *GitCommand) CreateAnnotatedTag(tagName, commitSha, msg string) error {
|
||||
@ -13,11 +13,11 @@ func (c *GitCommand) CreateAnnotatedTag(tagName, commitSha, msg string) error {
|
||||
}
|
||||
|
||||
func (c *GitCommand) DeleteTag(tagName string) error {
|
||||
return c.RunCommand("git tag -d %s", c.OSCommand.Quote(tagName))
|
||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git tag -d %s", c.OSCommand.Quote(tagName))))
|
||||
}
|
||||
|
||||
func (c *GitCommand) PushTag(remoteName string, tagName string, promptUserForCredential func(string) string) error {
|
||||
cmdStr := fmt.Sprintf("git push %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(tagName))
|
||||
cmdObj := c.NewCmdObjFromStr(cmdStr)
|
||||
cmdObj := c.NewCmdObj(cmdStr)
|
||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||
}
|
||||
|
@ -32,11 +32,9 @@ func (gui *Gui) branchesRenderToMain() error {
|
||||
if branch == nil {
|
||||
task = NewRenderStringTask(gui.Tr.NoBranchesThisRepo)
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(branch.Name),
|
||||
)
|
||||
cmdObj := gui.GitCommand.GetBranchGraphCmdObj(branch.Name)
|
||||
|
||||
task = NewRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -45,10 +45,8 @@ func (gui *Gui) commitFilesRenderToMain() error {
|
||||
to := gui.State.CommitFileManager.GetParent()
|
||||
from, reverse := gui.getFromAndReverseArgsForDiff(to)
|
||||
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowFileDiffCmdStr(from, to, reverse, node.GetPath(), false),
|
||||
)
|
||||
task := NewRunPtyTask(cmd)
|
||||
cmdObj := gui.GitCommand.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false)
|
||||
task := NewRunPtyTask(cmdObj.GetCmd())
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
|
@ -24,10 +24,11 @@ func (gui *Gui) handleCommitConfirm() error {
|
||||
flags = append(flags, "--signoff")
|
||||
}
|
||||
|
||||
cmdStr := gui.GitCommand.CommitCmdStr(message, strings.Join(flags, " "))
|
||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(cmdStr, gui.Tr.Spans.Commit, true))
|
||||
cmdObj := gui.GitCommand.CommitCmdObj(message, strings.Join(flags, " "))
|
||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(cmdObj.ToString(), gui.Tr.Spans.Commit, true))
|
||||
|
||||
_ = gui.returnFromContext()
|
||||
return gui.withGpgHandling(cmdStr, gui.Tr.CommittingStatus, func() error {
|
||||
return gui.withGpgHandling(cmdObj, gui.Tr.CommittingStatus, func() error {
|
||||
gui.Views.CommitMessage.ClearTextArea()
|
||||
return nil
|
||||
})
|
||||
|
@ -46,10 +46,8 @@ func (gui *Gui) branchCommitsRenderToMain() error {
|
||||
if commit == nil {
|
||||
task = NewRenderStringTask(gui.Tr.NoCommitsThisBranch)
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.Modes.Filtering.GetPath()),
|
||||
)
|
||||
task = NewRunPtyTask(cmd)
|
||||
cmdObj := gui.GitCommand.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath())
|
||||
task = NewRunPtyTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -203,7 +203,7 @@ func (gui *Gui) menuPromptFromCommand(prompt config.CustomCommandPrompt, promptR
|
||||
}
|
||||
|
||||
// Run and save output
|
||||
message, err := gui.GitCommand.RunCommandWithOutput(cmdStr)
|
||||
message, err := gui.GitCommand.RunWithOutput(gui.GitCommand.NewCmdObj(cmdStr))
|
||||
if err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
@ -244,7 +244,7 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
|
||||
}
|
||||
|
||||
if customCommand.Subprocess {
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(gui.OSCommand.PrepareShellSubProcess(cmdStr))
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(gui.OSCommand.NewShellCmdObjFromString2(cmdStr))
|
||||
}
|
||||
|
||||
loadingText := customCommand.LoadingText
|
||||
@ -252,7 +252,8 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
|
||||
loadingText = gui.Tr.LcRunningCustomCommandStatus
|
||||
}
|
||||
return gui.WithWaitingStatus(loadingText, func() error {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.CustomCommand).RunShellCommand(cmdStr); err != nil {
|
||||
cmdObj := gui.OSCommand.NewShellCmdObjFromString(cmdStr)
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.CustomCommand).Run(cmdObj); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
return gui.refreshSidePanels(refreshOptions{})
|
||||
|
@ -13,10 +13,10 @@ func (gui *Gui) exitDiffMode() error {
|
||||
}
|
||||
|
||||
func (gui *Gui) renderDiff() error {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
cmdObj := gui.OSCommand.NewCmdObj(
|
||||
fmt.Sprintf("git diff --submodule --no-ext-diff --color %s", gui.diffStr()),
|
||||
)
|
||||
task := NewRunPtyTask(cmd)
|
||||
task := NewRunPtyTask(cmdObj.GetCmd())
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
|
@ -58,22 +58,20 @@ func (gui *Gui) filesRenderToMain() error {
|
||||
return gui.refreshMergePanelWithLock()
|
||||
}
|
||||
|
||||
cmdStr := gui.GitCommand.WorktreeFileDiffCmdStr(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.State.IgnoreWhitespaceInDiffView)
|
||||
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
||||
cmdObj := gui.GitCommand.WorktreeFileDiffCmdObj(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
|
||||
title: gui.Tr.UnstagedChanges,
|
||||
task: NewRunPtyTask(cmd),
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
if node.GetHasStagedChanges() {
|
||||
cmdStr := gui.GitCommand.WorktreeFileDiffCmdStr(node, false, true, gui.State.IgnoreWhitespaceInDiffView)
|
||||
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
||||
cmdObj := gui.GitCommand.WorktreeFileDiffCmdObj(node, false, true, gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts.secondary = &viewUpdateOpts{
|
||||
title: gui.Tr.StagedChanges,
|
||||
task: NewRunPtyTask(cmd),
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -440,9 +438,9 @@ func (gui *Gui) handleAmendCommitPress() error {
|
||||
title: strings.Title(gui.Tr.AmendLastCommit),
|
||||
prompt: gui.Tr.SureToAmend,
|
||||
handleConfirm: func() error {
|
||||
cmdStr := gui.GitCommand.AmendHeadCmdStr()
|
||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(cmdStr, gui.Tr.Spans.AmendCommit, true))
|
||||
return gui.withGpgHandling(cmdStr, gui.Tr.AmendingStatus, nil)
|
||||
cmdObj := gui.GitCommand.AmendHeadCmdObj()
|
||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(cmdObj.ToString(), gui.Tr.Spans.AmendCommit, true))
|
||||
return gui.withGpgHandling(cmdObj, gui.Tr.AmendingStatus, nil)
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -464,8 +462,10 @@ func (gui *Gui) handleCommitEditorPress() error {
|
||||
args = append(args, "--signoff")
|
||||
}
|
||||
|
||||
cmdStr := "git " + strings.Join(args, " ")
|
||||
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.WithSpan(gui.Tr.Spans.Commit).PrepareSubProcess("git", args...),
|
||||
gui.GitCommand.WithSpan(gui.Tr.Spans.Commit).NewCmdObjWithLog(cmdStr),
|
||||
)
|
||||
}
|
||||
|
||||
@ -511,7 +511,7 @@ func (gui *Gui) editFileAtLine(filename string, lineNumber int) error {
|
||||
}
|
||||
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.WithSpan(gui.Tr.Spans.EditFile).ShellCommandFromString(cmdStr),
|
||||
gui.OSCommand.WithSpan(gui.Tr.Spans.EditFile).NewShellCmdObjFromString(cmdStr),
|
||||
)
|
||||
}
|
||||
|
||||
@ -923,7 +923,7 @@ func (gui *Gui) handleCustomCommand() error {
|
||||
|
||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(command, gui.Tr.Spans.CustomCommand, true))
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.PrepareShellSubProcess(command),
|
||||
gui.OSCommand.NewShellCmdObjFromString2(command),
|
||||
)
|
||||
},
|
||||
})
|
||||
@ -1004,7 +1004,7 @@ func (gui *Gui) handleOpenMergeTool() error {
|
||||
prompt: gui.Tr.MergeToolPrompt,
|
||||
handleConfirm: func() error {
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.ExecutableFromString(gui.GitCommand.OpenMergeToolCmd()),
|
||||
gui.GitCommand.OpenMergeToolCmdObj(),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -32,7 +32,7 @@ func (gui *Gui) gitFlowFinishBranch(gitFlowConfig string, branchName string) err
|
||||
}
|
||||
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.WithSpan(gui.Tr.Spans.GitFlowFinish).PrepareSubProcess("git", "flow", branchType, "finish", suffix),
|
||||
gui.GitCommand.WithSpan(gui.Tr.Spans.GitFlowFinish).NewCmdObjWithLog("git flow " + branchType + " finish " + suffix),
|
||||
)
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ func (gui *Gui) handleCreateGitFlowMenu() error {
|
||||
}
|
||||
|
||||
// get config
|
||||
gitFlowConfig, err := gui.GitCommand.RunCommandWithOutput("git config --local --get-regexp gitflow")
|
||||
gitFlowConfig, err := gui.GitCommand.RunWithOutput(gui.GitCommand.NewCmdObj("git config --local --get-regexp gitflow"))
|
||||
if err != nil {
|
||||
return gui.createErrorPanel("You need to install git-flow and enable it in this repo to use git-flow features")
|
||||
}
|
||||
@ -56,7 +56,7 @@ func (gui *Gui) handleCreateGitFlowMenu() error {
|
||||
title: title,
|
||||
handleConfirm: func(name string) error {
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||
gui.OSCommand.WithSpan(gui.Tr.Spans.GitFlowStart).PrepareSubProcess("git", "flow", branchType, "start", name),
|
||||
gui.GitCommand.WithSpan(gui.Tr.Spans.GitFlowStart).NewCmdObjWithLog("git flow " + branchType + " start " + name),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -3,6 +3,7 @@ package gui
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
)
|
||||
|
||||
@ -10,12 +11,11 @@ import (
|
||||
// WithWaitingStatus we get stuck there and can't return to lazygit. We could
|
||||
// fix this bug, or just stop running subprocesses from within there, given that
|
||||
// we don't need to see a loading status if we're in a subprocess.
|
||||
func (gui *Gui) withGpgHandling(cmdStr string, waitingStatus string, onSuccess func() error) error {
|
||||
// TODO: work out if we actually need to use a shell command here
|
||||
func (gui *Gui) withGpgHandling(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
||||
useSubprocess := gui.GitCommand.UsingGpg()
|
||||
if useSubprocess {
|
||||
// Need to remember why we use the shell for the subprocess but not in the other case
|
||||
// Maybe there's no good reason
|
||||
success, err := gui.runSubprocessWithSuspense(gui.OSCommand.ShellCommandFromString(cmdStr))
|
||||
success, err := gui.runSubprocessWithSuspense(gui.OSCommand.NewShellCmdObjFromString(cmdObj.ToString()))
|
||||
if success && onSuccess != nil {
|
||||
if err := onSuccess(); err != nil {
|
||||
return err
|
||||
@ -27,15 +27,16 @@ func (gui *Gui) withGpgHandling(cmdStr string, waitingStatus string, onSuccess f
|
||||
|
||||
return err
|
||||
} else {
|
||||
return gui.RunAndStream(cmdStr, waitingStatus, onSuccess)
|
||||
return gui.RunAndStream(cmdObj, waitingStatus, onSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) RunAndStream(cmdStr string, waitingStatus string, onSuccess func() error) error {
|
||||
func (gui *Gui) RunAndStream(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
||||
return gui.WithWaitingStatus(waitingStatus, func() error {
|
||||
cmd := gui.OSCommand.ShellCommandFromString(cmdStr)
|
||||
cmd.Env = append(cmd.Env, "TERM=dumb")
|
||||
cmdObj := gui.OSCommand.NewShellCmdObjFromString(cmdObj.ToString())
|
||||
cmdObj.AddEnvVars("TERM=dumb")
|
||||
cmdWriter := gui.getCmdWriter()
|
||||
cmd := cmdObj.GetCmd()
|
||||
cmd.Stdout = cmdWriter
|
||||
cmd.Stderr = cmdWriter
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -578,7 +577,7 @@ func (gui *Gui) RunAndHandleError() error {
|
||||
}
|
||||
|
||||
// returns whether command exited without error or not
|
||||
func (gui *Gui) runSubprocessWithSuspenseAndRefresh(subprocess *exec.Cmd) error {
|
||||
func (gui *Gui) runSubprocessWithSuspenseAndRefresh(subprocess oscommands.ICmdObj) error {
|
||||
_, err := gui.runSubprocessWithSuspense(subprocess)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -592,7 +591,7 @@ func (gui *Gui) runSubprocessWithSuspenseAndRefresh(subprocess *exec.Cmd) error
|
||||
}
|
||||
|
||||
// returns whether command exited without error or not
|
||||
func (gui *Gui) runSubprocessWithSuspense(subprocess *exec.Cmd) (bool, error) {
|
||||
func (gui *Gui) runSubprocessWithSuspense(subprocess oscommands.ICmdObj) (bool, error) {
|
||||
gui.Mutexes.SubprocessMutex.Lock()
|
||||
defer gui.Mutexes.SubprocessMutex.Unlock()
|
||||
|
||||
@ -621,7 +620,8 @@ func (gui *Gui) runSubprocessWithSuspense(subprocess *exec.Cmd) (bool, error) {
|
||||
return cmdErr == nil, gui.surfaceError(cmdErr)
|
||||
}
|
||||
|
||||
func (gui *Gui) runSubprocess(subprocess *exec.Cmd) error {
|
||||
func (gui *Gui) runSubprocess(cmdObj oscommands.ICmdObj) error {
|
||||
subprocess := cmdObj.GetCmd()
|
||||
subprocess.Stdout = os.Stdout
|
||||
subprocess.Stderr = os.Stdout
|
||||
subprocess.Stdin = os.Stdin
|
||||
|
@ -58,7 +58,7 @@ func (gui *Gui) genericMergeCommand(command string) error {
|
||||
|
||||
// it's impossible for a rebase to require a commit so we'll use a subprocess only if it's a merge
|
||||
if status == commands.REBASE_MODE_MERGING && command != REBASE_OPTION_ABORT && gui.Config.GetUserConfig().Git.Merging.ManualCommit {
|
||||
sub := gitCommand.OSCommand.PrepareSubProcess("git", commandType, fmt.Sprintf("--%s", command))
|
||||
sub := gitCommand.NewCmdObj("git " + commandType + " --" + command)
|
||||
if sub != nil {
|
||||
return gui.runSubprocessWithSuspenseAndRefresh(sub)
|
||||
}
|
||||
|
@ -38,10 +38,10 @@ func (gui *Gui) handleCreateRecentReposMenu() error {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleShowAllBranchLogs() error {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
cmdObj := gui.OSCommand.NewCmdObj(
|
||||
gui.Config.GetUserConfig().Git.AllBranchesLogCmd,
|
||||
)
|
||||
task := NewRunPtyTask(cmd)
|
||||
task := NewRunPtyTask(cmdObj.GetCmd())
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
|
@ -22,11 +22,9 @@ func (gui *Gui) reflogCommitsRenderToMain() error {
|
||||
if commit == nil {
|
||||
task = NewRenderStringTask("No reflog history")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.Modes.Filtering.GetPath()),
|
||||
)
|
||||
cmdObj := gui.GitCommand.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath())
|
||||
|
||||
task = NewRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -24,10 +24,8 @@ func (gui *Gui) remoteBranchesRenderToMain() error {
|
||||
if remoteBranch == nil {
|
||||
task = NewRenderStringTask("No branches for this remote")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(remoteBranch.FullName()),
|
||||
)
|
||||
task = NewRunCommandTask(cmd)
|
||||
cmdObj := gui.GitCommand.GetBranchGraphCmdObj(remoteBranch.FullName())
|
||||
task = NewRunCommandTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -3,12 +3,11 @@ package gui
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
)
|
||||
|
||||
func (gui *Gui) resetToRef(ref string, strength string, span string, options oscommands.RunCommandOptions) error {
|
||||
if err := gui.GitCommand.WithSpan(span).ResetToCommit(ref, strength, options); err != nil {
|
||||
func (gui *Gui) resetToRef(ref string, strength string, span string, envVars []string) error {
|
||||
if err := gui.GitCommand.WithSpan(span).ResetToCommit(ref, strength, envVars); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
@ -39,7 +38,7 @@ func (gui *Gui) createResetMenu(ref string) error {
|
||||
style.FgRed.Sprintf("reset --%s %s", strength, ref),
|
||||
},
|
||||
onPress: func() error {
|
||||
return gui.resetToRef(ref, strength, "Reset", oscommands.RunCommandOptions{})
|
||||
return gui.resetToRef(ref, strength, "Reset", []string{})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,10 @@ func (gui *Gui) stashRenderToMain() error {
|
||||
if stashEntry == nil {
|
||||
task = NewRenderStringTask(gui.Tr.NoStashEntries)
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
cmdObj := gui.OSCommand.NewCmdObj(
|
||||
gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index),
|
||||
)
|
||||
task = NewRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -23,11 +23,9 @@ func (gui *Gui) subCommitsRenderToMain() error {
|
||||
if commit == nil {
|
||||
task = NewRenderStringTask("No commits")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.Modes.Filtering.GetPath()),
|
||||
)
|
||||
cmdObj := gui.GitCommand.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath())
|
||||
|
||||
task = NewRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -36,9 +36,8 @@ func (gui *Gui) submodulesRenderToMain() error {
|
||||
if file == nil {
|
||||
task = NewRenderStringTask(prefix)
|
||||
} else {
|
||||
cmdStr := gui.GitCommand.WorktreeFileDiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges, gui.State.IgnoreWhitespaceInDiffView)
|
||||
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
||||
task = NewRunCommandTaskWithPrefix(cmd, prefix)
|
||||
cmdObj := gui.GitCommand.WorktreeFileDiffCmdObj(file, false, !file.HasUnstagedChanges && file.HasStagedChanges, gui.State.IgnoreWhitespaceInDiffView)
|
||||
task = NewRunCommandTaskWithPrefix(cmdObj.GetCmd(), prefix)
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,10 +211,10 @@ func (gui *Gui) handleResetRemoveSubmodule(submodule *models.SubmoduleConfig) er
|
||||
func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
||||
menuItems := []*menuItem{
|
||||
{
|
||||
displayStrings: []string{gui.Tr.LcBulkInitSubmodules, style.FgGreen.Sprint(gui.GitCommand.SubmoduleBulkInitCmdStr())},
|
||||
displayStrings: []string{gui.Tr.LcBulkInitSubmodules, style.FgGreen.Sprint(gui.GitCommand.SubmoduleBulkInitCmdObj().ToString())},
|
||||
onPress: func() error {
|
||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkInitialiseSubmodules).RunCommand(gui.GitCommand.SubmoduleBulkInitCmdStr()); err != nil {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkInitialiseSubmodules).Run(gui.GitCommand.SubmoduleBulkInitCmdObj()); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
@ -224,10 +223,10 @@ func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
displayStrings: []string{gui.Tr.LcBulkUpdateSubmodules, style.FgYellow.Sprint(gui.GitCommand.SubmoduleBulkUpdateCmdStr())},
|
||||
displayStrings: []string{gui.Tr.LcBulkUpdateSubmodules, style.FgYellow.Sprint(gui.GitCommand.SubmoduleBulkUpdateCmdObj().ToString())},
|
||||
onPress: func() error {
|
||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkUpdateSubmodules).RunCommand(gui.GitCommand.SubmoduleBulkUpdateCmdStr()); err != nil {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkUpdateSubmodules).Run(gui.GitCommand.SubmoduleBulkUpdateCmdObj()); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
@ -236,7 +235,7 @@ func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
displayStrings: []string{gui.Tr.LcSubmoduleStashAndReset, style.FgRed.Sprintf("git stash in each submodule && %s", gui.GitCommand.SubmoduleForceBulkUpdateCmdStr())},
|
||||
displayStrings: []string{gui.Tr.LcSubmoduleStashAndReset, style.FgRed.Sprintf("git stash in each submodule && %s", gui.GitCommand.SubmoduleForceBulkUpdateCmdObj().ToString())},
|
||||
onPress: func() error {
|
||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||
if err := gui.GitCommand.WithSpan(gui.Tr.Spans.BulkStashAndResetSubmodules).ResetSubmodules(gui.State.Submodules); err != nil {
|
||||
@ -248,10 +247,10 @@ func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
displayStrings: []string{gui.Tr.LcBulkDeinitSubmodules, style.FgRed.Sprint(gui.GitCommand.SubmoduleBulkDeinitCmdStr())},
|
||||
displayStrings: []string{gui.Tr.LcBulkDeinitSubmodules, style.FgRed.Sprint(gui.GitCommand.SubmoduleBulkDeinitCmdObj().ToString())},
|
||||
onPress: func() error {
|
||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkDeinitialiseSubmodules).RunCommand(gui.GitCommand.SubmoduleBulkDeinitCmdStr()); err != nil {
|
||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkDeinitialiseSubmodules).Run(gui.GitCommand.SubmoduleBulkDeinitCmdObj()); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,8 @@ func (gui *Gui) tagsRenderToMain() error {
|
||||
if tag == nil {
|
||||
task = NewRenderStringTask("No tags")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(tag.Name),
|
||||
)
|
||||
task = NewRunCommandTask(cmd)
|
||||
cmdObj := gui.GitCommand.GetBranchGraphCmdObj(tag.Name)
|
||||
task = NewRunCommandTask(cmdObj.GetCmd())
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -2,7 +2,6 @@ package gui
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
@ -169,7 +168,7 @@ func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHar
|
||||
gitCommand := gui.GitCommand.WithSpan(options.span)
|
||||
|
||||
reset := func() error {
|
||||
if err := gui.resetToRef(commitSha, "hard", options.span, oscommands.RunCommandOptions{EnvVars: options.EnvVars}); err != nil {
|
||||
if err := gui.resetToRef(commitSha, "hard", options.span, options.EnvVars); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
return nil
|
||||
|
@ -45,7 +45,7 @@ func RunTests(
|
||||
testDir := filepath.Join(rootDir, "test", "integration")
|
||||
|
||||
osCommand := oscommands.NewDummyOSCommand()
|
||||
err = osCommand.RunCommand("go build -o %s", tempLazygitPath())
|
||||
err = osCommand.Run(osCommand.NewCmdObj("go build -o " + tempLazygitPath()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -216,11 +216,10 @@ func GetRootDirectory() string {
|
||||
}
|
||||
|
||||
func createFixture(testPath, actualDir string) error {
|
||||
osCommand := oscommands.NewDummyOSCommand()
|
||||
bashScriptPath := filepath.Join(testPath, "setup.sh")
|
||||
cmd := secureexec.Command("bash", bashScriptPath, actualDir)
|
||||
|
||||
if err := osCommand.RunExecutable(cmd); err != nil {
|
||||
if _, err := cmd.CombinedOutput(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -320,7 +319,7 @@ func generateSnapshot(dir string) (string, error) {
|
||||
|
||||
for _, cmdStr := range cmdStrs {
|
||||
// ignoring error for now. If there's an error it could be that there are no results
|
||||
output, _ := osCommand.RunCommandWithOutput(cmdStr)
|
||||
output, _ := osCommand.RunWithOutput(osCommand.NewCmdObj(cmdStr))
|
||||
|
||||
snapshot += output + "\n"
|
||||
}
|
||||
@ -429,22 +428,16 @@ func getLazygitCommand(testPath string, rootDir string, record bool, speed float
|
||||
|
||||
cmdStr := fmt.Sprintf("%s -debug --use-config-dir=%s --path=%s %s", tempLazygitPath(), configDir, actualDir, extraCmdArgs)
|
||||
|
||||
cmd := osCommand.ExecutableFromString(cmdStr)
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("SPEED=%f", speed))
|
||||
cmdObj := osCommand.NewCmdObj(cmdStr)
|
||||
cmdObj.AddEnvVars(fmt.Sprintf("SPEED=%f", speed))
|
||||
|
||||
if record {
|
||||
cmd.Env = append(
|
||||
cmd.Env,
|
||||
fmt.Sprintf("RECORD_EVENTS_TO=%s", replayPath),
|
||||
)
|
||||
cmdObj.AddEnvVars(fmt.Sprintf("RECORD_EVENTS_TO=%s", replayPath))
|
||||
} else {
|
||||
cmd.Env = append(
|
||||
cmd.Env,
|
||||
fmt.Sprintf("REPLAY_EVENTS_FROM=%s", replayPath),
|
||||
)
|
||||
cmdObj.AddEnvVars(fmt.Sprintf("REPLAY_EVENTS_FROM=%s", replayPath))
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
return cmdObj.GetCmd(), nil
|
||||
}
|
||||
|
||||
func folderExists(path string) bool {
|
||||
|
@ -300,7 +300,8 @@ func (u *Updater) downloadAndInstall(rawUrl string) error {
|
||||
}
|
||||
|
||||
u.Log.Info("untarring tarball/unzipping zip file")
|
||||
if err := u.OSCommand.RunCommand("tar -zxf %s %s", u.OSCommand.Quote(zipPath), "lazygit"); err != nil {
|
||||
cmdObj := u.OSCommand.NewCmdObj(fmt.Sprintf("tar -zxf %s %s", u.OSCommand.Quote(zipPath), "lazygit"))
|
||||
if err := u.OSCommand.Run(cmdObj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user