mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-19 21:28:28 +02:00
fetching branches without checking out
This commit is contained in:
parent
ca3afa2a39
commit
ff856b7630
@ -52,6 +52,9 @@ func newLogger(config config.AppConfigurer) *logrus.Entry {
|
|||||||
} else {
|
} else {
|
||||||
log = newProductionLogger(config)
|
log = newProductionLogger(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// highly recommended: tail -f development.log | humanlog
|
||||||
|
// https://github.com/aybabtme/humanlog
|
||||||
log.Formatter = &logrus.JSONFormatter{}
|
log.Formatter = &logrus.JSONFormatter{}
|
||||||
|
|
||||||
if config.GetUserConfig().GetString("reporting") == "on" {
|
if config.GetUserConfig().GetString("reporting") == "on" {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
@ -10,13 +11,21 @@ import (
|
|||||||
// Branch : A git branch
|
// Branch : A git branch
|
||||||
// duplicating this for now
|
// duplicating this for now
|
||||||
type Branch struct {
|
type Branch struct {
|
||||||
Name string
|
Name string
|
||||||
Recency string
|
Recency string
|
||||||
|
Pushables string
|
||||||
|
Pullables string
|
||||||
|
Selected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisplayStrings returns the dispaly string of branch
|
// GetDisplayStrings returns the dispaly string of branch
|
||||||
func (b *Branch) GetDisplayStrings() []string {
|
func (b *Branch) GetDisplayStrings() []string {
|
||||||
return []string{b.Recency, utils.ColoredString(b.Name, b.GetColor())}
|
displayName := utils.ColoredString(b.Name, b.GetColor())
|
||||||
|
if b.Selected && b.Pushables != "" && b.Pullables != "" {
|
||||||
|
displayName = fmt.Sprintf("↑%s↓%s %s", b.Pushables, b.Pullables, displayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return []string{b.Recency, displayName}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetColor branch color
|
// GetColor branch color
|
||||||
|
@ -130,17 +130,6 @@ func (c *GitCommand) GetStashEntryDiff(index int) (string, error) {
|
|||||||
|
|
||||||
// GetStatusFiles git status files
|
// GetStatusFiles git status files
|
||||||
func (c *GitCommand) GetStatusFiles() []*File {
|
func (c *GitCommand) GetStatusFiles() []*File {
|
||||||
|
|
||||||
// files := []*File{}
|
|
||||||
// for i := 0; i < 100; i++ {
|
|
||||||
// files = append(files, &File{
|
|
||||||
// Name: strconv.Itoa(i),
|
|
||||||
// DisplayString: strconv.Itoa(i),
|
|
||||||
// Type: "file",
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// return files
|
|
||||||
|
|
||||||
statusOutput, _ := c.GitStatus()
|
statusOutput, _ := c.GitStatus()
|
||||||
statusStrings := utils.SplitLines(statusOutput)
|
statusStrings := utils.SplitLines(statusOutput)
|
||||||
files := []*File{}
|
files := []*File{}
|
||||||
@ -165,7 +154,6 @@ func (c *GitCommand) GetStatusFiles() []*File {
|
|||||||
}
|
}
|
||||||
files = append(files, file)
|
files = append(files, file)
|
||||||
}
|
}
|
||||||
c.Log.Info(files) // TODO: use a dumper-esque log here
|
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,14 +216,24 @@ func (c *GitCommand) ResetAndClean() error {
|
|||||||
return c.OSCommand.RunCommand("git clean -fd")
|
return c.OSCommand.RunCommand("git clean -fd")
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpstreamDifferenceCount checks how many pushables/pullables there are for the
|
func (c *GitCommand) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
|
||||||
|
return c.GetCommitDifferences("HEAD", "@{u}")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GitCommand) GetBranchUpstreamDifferenceCount(branchName string) (string, string) {
|
||||||
|
upstream := "origin" // hardcoded for now
|
||||||
|
return c.GetCommitDifferences(branchName, fmt.Sprintf("%s/%s", upstream, branchName))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitDifferences checks how many pushables/pullables there are for the
|
||||||
// current branch
|
// current branch
|
||||||
func (c *GitCommand) UpstreamDifferenceCount() (string, string) {
|
func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
|
||||||
pushableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..HEAD --count")
|
command := "git rev-list %s..%s --count"
|
||||||
|
pushableCount, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf(command, to, from))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "?", "?"
|
return "?", "?"
|
||||||
}
|
}
|
||||||
pullableCount, err := c.OSCommand.RunCommandWithOutput("git rev-list HEAD..@{u} --count")
|
pullableCount, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf(command, from, to))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "?", "?"
|
return "?", "?"
|
||||||
}
|
}
|
||||||
@ -618,3 +616,8 @@ func (c *GitCommand) ApplyPatch(patch string) (string, error) {
|
|||||||
|
|
||||||
return c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git apply --cached %s", filename))
|
return c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git apply --cached %s", filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *GitCommand) FastForward(branchName string) error {
|
||||||
|
upstream := "origin" // hardcoding for now
|
||||||
|
return c.OSCommand.RunCommand(fmt.Sprintf("git fetch %s %s:%s", upstream, branchName, branchName))
|
||||||
|
}
|
||||||
|
@ -557,8 +557,8 @@ func TestGitCommandMergeStatusFiles(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestGitCommandUpstreamDifferentCount is a function.
|
// TestGitCommandGetCommitDifferences is a function.
|
||||||
func TestGitCommandUpstreamDifferentCount(t *testing.T) {
|
func TestGitCommandGetCommitDifferences(t *testing.T) {
|
||||||
type scenario struct {
|
type scenario struct {
|
||||||
testName string
|
testName string
|
||||||
command func(string, ...string) *exec.Cmd
|
command func(string, ...string) *exec.Cmd
|
||||||
@ -610,7 +610,7 @@ func TestGitCommandUpstreamDifferentCount(t *testing.T) {
|
|||||||
t.Run(s.testName, func(t *testing.T) {
|
t.Run(s.testName, func(t *testing.T) {
|
||||||
gitCmd := newDummyGitCommand()
|
gitCmd := newDummyGitCommand()
|
||||||
gitCmd.OSCommand.command = s.command
|
gitCmd.OSCommand.command = s.command
|
||||||
s.test(gitCmd.UpstreamDifferenceCount())
|
s.test(gitCmd.GetCommitDifferences("HEAD", "@{u}"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/git"
|
"github.com/jesseduffield/lazygit/pkg/git"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// list panel functions
|
// list panel functions
|
||||||
@ -31,6 +30,9 @@ func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err := gui.focusPoint(0, gui.State.Panels.Branches.SelectedLine, v); err != nil {
|
if err := gui.focusPoint(0, gui.State.Panels.Branches.SelectedLine, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
_ = gui.RenderSelectedBranchUpstreamDifferences()
|
||||||
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
graph, err := gui.GitCommand.GetBranchGraph(branch.Name)
|
graph, err := gui.GitCommand.GetBranchGraph(branch.Name)
|
||||||
if err != nil && strings.HasPrefix(graph, "fatal: ambiguous argument") {
|
if err != nil && strings.HasPrefix(graph, "fatal: ambiguous argument") {
|
||||||
@ -41,14 +43,23 @@ func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) RenderSelectedBranchUpstreamDifferences() error {
|
||||||
|
// here we tell the selected branch that it is selected.
|
||||||
|
// this is necessary for showing stats on a branch that is selected, because
|
||||||
|
// the displaystring function doesn't have access to gui state to tell if it's selected
|
||||||
|
for i, branch := range gui.State.Branches {
|
||||||
|
branch.Selected = i == gui.State.Panels.Branches.SelectedLine
|
||||||
|
}
|
||||||
|
|
||||||
|
branch := gui.getSelectedBranch()
|
||||||
|
branch.Pushables, branch.Pullables = gui.GitCommand.GetBranchUpstreamDifferenceCount(branch.Name)
|
||||||
|
return gui.renderListPanel(gui.getBranchesView(gui.g), gui.State.Branches)
|
||||||
|
}
|
||||||
|
|
||||||
// gui.refreshStatus is called at the end of this because that's when we can
|
// gui.refreshStatus is called at the end of this because that's when we can
|
||||||
// be sure there is a state.Branches array to pick the current branch from
|
// be sure there is a state.Branches array to pick the current branch from
|
||||||
func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
||||||
g.Update(func(g *gocui.Gui) error {
|
g.Update(func(g *gocui.Gui) error {
|
||||||
v, err := g.View("branches")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
builder, err := git.NewBranchListBuilder(gui.Log, gui.GitCommand)
|
builder, err := git.NewBranchListBuilder(gui.Log, gui.GitCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -56,16 +67,13 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
|||||||
gui.State.Branches = builder.Build()
|
gui.State.Branches = builder.Build()
|
||||||
|
|
||||||
gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
|
gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
|
||||||
|
if err := gui.resetOrigin(gui.getBranchesView(gui.g)); err != nil {
|
||||||
v.Clear()
|
return err
|
||||||
list, err := utils.RenderList(gui.State.Branches)
|
}
|
||||||
if err != nil {
|
if err := gui.RenderSelectedBranchUpstreamDifferences(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(v, list)
|
|
||||||
|
|
||||||
gui.resetOrigin(v)
|
|
||||||
return gui.refreshStatus(g)
|
return gui.refreshStatus(g)
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
@ -74,7 +82,6 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
|||||||
func (gui *Gui) handleBranchesNextLine(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleBranchesNextLine(g *gocui.Gui, v *gocui.View) error {
|
||||||
panelState := gui.State.Panels.Branches
|
panelState := gui.State.Panels.Branches
|
||||||
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Branches), false)
|
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Branches), false)
|
||||||
|
|
||||||
return gui.handleBranchSelect(gui.g, v)
|
return gui.handleBranchSelect(gui.g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +106,10 @@ func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err := gui.createErrorPanel(g, err.Error()); err != nil {
|
if err := gui.createErrorPanel(g, err.Error()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
gui.State.Panels.Branches.SelectedLine = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,3 +223,37 @@ func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
branch := gui.getSelectedBranch()
|
||||||
|
if branch == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if branch.Pushables == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if branch.Pushables == "?" {
|
||||||
|
return gui.createErrorPanel(gui.g, "Cannot fast-forward a branch with no upstream")
|
||||||
|
}
|
||||||
|
if branch.Pushables != "0" {
|
||||||
|
return gui.createErrorPanel(gui.g, "Cannot fast-forward a branch with commits to push")
|
||||||
|
}
|
||||||
|
upstream := "origin" // hardcoding for now
|
||||||
|
message := gui.Tr.TemplateLocalize(
|
||||||
|
"Fetching",
|
||||||
|
Teml{
|
||||||
|
"from": fmt.Sprintf("%s/%s", upstream, branch.Name),
|
||||||
|
"to": branch.Name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
go func() {
|
||||||
|
_ = gui.createMessagePanel(gui.g, v, "", message)
|
||||||
|
if err := gui.GitCommand.FastForward(branch.Name); err != nil {
|
||||||
|
_ = gui.createErrorPanel(gui.g, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = gui.closeConfirmationPrompt(gui.g)
|
||||||
|
_ = gui.RenderSelectedBranchUpstreamDifferences()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -24,10 +24,10 @@ func (gui *Gui) handleCommitConfirm(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return gui.Errors.ErrSubProcess
|
return gui.Errors.ErrSubProcess
|
||||||
}
|
}
|
||||||
v.Clear()
|
v.Clear()
|
||||||
v.SetCursor(0, 0)
|
_ = v.SetCursor(0, 0)
|
||||||
v.SetOrigin(0, 0)
|
_ = v.SetOrigin(0, 0)
|
||||||
g.SetViewOnBottom("commitMessage")
|
_, _ = g.SetViewOnBottom("commitMessage")
|
||||||
gui.switchFocus(g, v, gui.getFilesView(g))
|
_ = gui.switchFocus(g, v, gui.getFilesView(g))
|
||||||
return gui.refreshSidePanels(g)
|
return gui.refreshSidePanels(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,8 @@ func (gui *Gui) handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
gui.resetOrigin(commitView)
|
gui.resetOrigin(commitView)
|
||||||
return gui.handleCommitSelect(g, nil)
|
gui.State.Panels.Commits.SelectedLine = 0
|
||||||
|
return gui.handleCommitSelect(g, commitView)
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ func (gui *Gui) wrappedConfirmationFunction(function func(*gocui.Gui, *gocui.Vie
|
|||||||
func (gui *Gui) closeConfirmationPrompt(g *gocui.Gui) error {
|
func (gui *Gui) closeConfirmationPrompt(g *gocui.Gui) error {
|
||||||
view, err := g.View("confirmation")
|
view, err := g.View("confirmation")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return nil // if it's already been closed we can just return
|
||||||
}
|
}
|
||||||
if err := gui.returnFocus(g, view); err != nil {
|
if err := gui.returnFocus(g, view); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -77,11 +77,10 @@ func (gui *Gui) prepareConfirmationPanel(currentView *gocui.View, title, prompt
|
|||||||
confirmationView.Wrap = true
|
confirmationView.Wrap = true
|
||||||
confirmationView.FgColor = gocui.ColorWhite
|
confirmationView.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
confirmationView.Clear()
|
gui.g.Update(func(g *gocui.Gui) error {
|
||||||
|
confirmationView.Clear()
|
||||||
if err := gui.switchFocus(gui.g, currentView, confirmationView); err != nil {
|
return gui.switchFocus(gui.g, currentView, confirmationView)
|
||||||
return nil, err
|
})
|
||||||
}
|
|
||||||
return confirmationView, nil
|
return confirmationView, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func (gui *Gui) refreshFiles(g *gocui.Gui) error {
|
|||||||
fmt.Fprint(filesView, list)
|
fmt.Fprint(filesView, list)
|
||||||
|
|
||||||
if filesView == g.CurrentView() {
|
if filesView == g.CurrentView() {
|
||||||
gui.handleFileSelect(g, filesView)
|
return gui.handleFileSelect(g, filesView)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -411,7 +411,7 @@ func (gui *Gui) pushWithForceFlag(currentView *gocui.View, force bool) error {
|
|||||||
|
|
||||||
func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
||||||
// if we have pullables we'll ask if the user wants to force push
|
// if we have pullables we'll ask if the user wants to force push
|
||||||
_, pullables := gui.GitCommand.UpstreamDifferenceCount()
|
_, pullables := gui.GitCommand.GetCurrentBranchUpstreamDifferenceCount()
|
||||||
if pullables == "?" || pullables == "0" {
|
if pullables == "?" || pullables == "0" {
|
||||||
return gui.pushWithForceFlag(v, false)
|
return gui.pushWithForceFlag(v, false)
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,9 @@ type Gui struct {
|
|||||||
statusManager *statusManager
|
statusManager *statusManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for now the staging panel state, unlike the other panel states, is going to be
|
||||||
|
// non-mutative, so that we don't accidentally end up
|
||||||
|
// with mismatches of data. We might change this in the future
|
||||||
type stagingPanelState struct {
|
type stagingPanelState struct {
|
||||||
SelectedLine int
|
SelectedLine int
|
||||||
StageableLines []int
|
StageableLines []int
|
||||||
@ -233,7 +236,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
g.SetViewOnBottom("limit")
|
_, _ = g.SetViewOnBottom("limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
g.DeleteView("limit")
|
g.DeleteView("limit")
|
||||||
@ -364,14 +367,14 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.g.SetCurrentView(filesView.Name())
|
if _, err := gui.g.SetCurrentView(filesView.Name()); err != nil {
|
||||||
|
return err
|
||||||
gui.refreshSidePanels(gui.g)
|
|
||||||
if gui.g.CurrentView().Name() != "menu" {
|
|
||||||
if err := gui.renderGlobalOptions(g); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := gui.refreshSidePanels(gui.g); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := gui.switchFocus(g, nil, filesView); err != nil {
|
if err := gui.switchFocus(g, nil, filesView); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -394,8 +397,10 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: comment-out
|
// here is a good place log some stuff
|
||||||
gui.Log.Info(utils.AsJson(gui.State))
|
// if you download humanlog and do tail -f development.log | humanlog
|
||||||
|
// this will let you see these branches as prettified json
|
||||||
|
// gui.Log.Info(utils.AsJson(gui.State.Branches[0:4]))
|
||||||
|
|
||||||
return gui.resizeCurrentPopupPanel(g)
|
return gui.resizeCurrentPopupPanel(g)
|
||||||
}
|
}
|
||||||
@ -435,8 +440,8 @@ func (gui *Gui) renderAppStatus(g *gocui.Gui) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderGlobalOptions(g *gocui.Gui) error {
|
func (gui *Gui) renderGlobalOptions() error {
|
||||||
return gui.renderOptionsMap(g, map[string]string{
|
return gui.renderOptionsMap(map[string]string{
|
||||||
"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
|
"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
|
||||||
"← → ↑ ↓": gui.Tr.SLocalize("navigate"),
|
"← → ↑ ↓": gui.Tr.SLocalize("navigate"),
|
||||||
"esc/q": gui.Tr.SLocalize("close"),
|
"esc/q": gui.Tr.SLocalize("close"),
|
||||||
@ -467,7 +472,7 @@ func (gui *Gui) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gui.goEvery(g, time.Second*60, gui.fetch)
|
gui.goEvery(g, time.Second*60, gui.fetch)
|
||||||
// gui.goEvery(g, time.Second*2, gui.refreshFiles) // TODO: comment back in
|
gui.goEvery(g, time.Second*2, gui.refreshFiles)
|
||||||
gui.goEvery(g, time.Millisecond*50, gui.updateLoader)
|
gui.goEvery(g, time.Millisecond*50, gui.updateLoader)
|
||||||
gui.goEvery(g, time.Millisecond*50, gui.renderAppStatus)
|
gui.goEvery(g, time.Millisecond*50, gui.renderAppStatus)
|
||||||
|
|
||||||
|
@ -219,12 +219,7 @@ func (gui *Gui) GetKeybindings() []*Binding {
|
|||||||
Handler: gui.handleSwitchToStagingPanel,
|
Handler: gui.handleSwitchToStagingPanel,
|
||||||
Description: gui.Tr.SLocalize("StageLines"),
|
Description: gui.Tr.SLocalize("StageLines"),
|
||||||
KeyReadable: "enter",
|
KeyReadable: "enter",
|
||||||
},
|
}, {
|
||||||
{ViewName: "files", Key: 'k', Modifier: gocui.ModNone, Handler: gui.handleFilesPrevLine},
|
|
||||||
{ViewName: "files", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleFilesPrevLine},
|
|
||||||
{ViewName: "files", Key: 'j', Modifier: gocui.ModNone, Handler: gui.handleFilesNextLine},
|
|
||||||
{ViewName: "files", Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.handleFilesNextLine},
|
|
||||||
{
|
|
||||||
ViewName: "main",
|
ViewName: "main",
|
||||||
Key: gocui.KeyEsc,
|
Key: gocui.KeyEsc,
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
@ -327,12 +322,13 @@ func (gui *Gui) GetKeybindings() []*Binding {
|
|||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleMerge,
|
Handler: gui.handleMerge,
|
||||||
Description: gui.Tr.SLocalize("mergeIntoCurrentBranch"),
|
Description: gui.Tr.SLocalize("mergeIntoCurrentBranch"),
|
||||||
},
|
}, {
|
||||||
{ViewName: "branches", Key: 'k', Modifier: gocui.ModNone, Handler: gui.handleBranchesPrevLine},
|
ViewName: "branches",
|
||||||
{ViewName: "branches", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleBranchesPrevLine},
|
Key: 'f',
|
||||||
{ViewName: "branches", Key: 'j', Modifier: gocui.ModNone, Handler: gui.handleBranchesNextLine},
|
Modifier: gocui.ModNone,
|
||||||
{ViewName: "branches", Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.handleBranchesNextLine},
|
Handler: gui.handleFastForward,
|
||||||
{
|
Description: gui.Tr.SLocalize("FastForward"),
|
||||||
|
}, {
|
||||||
ViewName: "commits",
|
ViewName: "commits",
|
||||||
Key: 's',
|
Key: 's',
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
@ -362,12 +358,7 @@ func (gui *Gui) GetKeybindings() []*Binding {
|
|||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleCommitFixup,
|
Handler: gui.handleCommitFixup,
|
||||||
Description: gui.Tr.SLocalize("fixupCommit"),
|
Description: gui.Tr.SLocalize("fixupCommit"),
|
||||||
},
|
}, {
|
||||||
{ViewName: "commits", Key: 'k', Modifier: gocui.ModNone, Handler: gui.handleCommitsPrevLine},
|
|
||||||
{ViewName: "commits", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleCommitsPrevLine},
|
|
||||||
{ViewName: "commits", Key: 'j', Modifier: gocui.ModNone, Handler: gui.handleCommitsNextLine},
|
|
||||||
{ViewName: "commits", Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.handleCommitsNextLine},
|
|
||||||
{
|
|
||||||
ViewName: "stash",
|
ViewName: "stash",
|
||||||
Key: gocui.KeySpace,
|
Key: gocui.KeySpace,
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
@ -386,12 +377,7 @@ func (gui *Gui) GetKeybindings() []*Binding {
|
|||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleStashDrop,
|
Handler: gui.handleStashDrop,
|
||||||
Description: gui.Tr.SLocalize("drop"),
|
Description: gui.Tr.SLocalize("drop"),
|
||||||
},
|
}, {
|
||||||
{ViewName: "stash", Key: 'k', Modifier: gocui.ModNone, Handler: gui.handleStashPrevLine},
|
|
||||||
{ViewName: "stash", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleStashPrevLine},
|
|
||||||
{ViewName: "stash", Key: 'j', Modifier: gocui.ModNone, Handler: gui.handleStashNextLine},
|
|
||||||
{ViewName: "stash", Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.handleStashNextLine},
|
|
||||||
{
|
|
||||||
ViewName: "commitMessage",
|
ViewName: "commitMessage",
|
||||||
Key: gocui.KeyEnter,
|
Key: gocui.KeyEnter,
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
@ -411,11 +397,7 @@ func (gui *Gui) GetKeybindings() []*Binding {
|
|||||||
Key: 'q',
|
Key: 'q',
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: gui.handleMenuClose,
|
Handler: gui.handleMenuClose,
|
||||||
},
|
}, {
|
||||||
{ViewName: "menu", Key: 'k', Modifier: gocui.ModNone, Handler: gui.handleMenuPrevLine},
|
|
||||||
{ViewName: "menu", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleMenuPrevLine},
|
|
||||||
{ViewName: "menu", Key: 'j', Modifier: gocui.ModNone, Handler: gui.handleMenuNextLine},
|
|
||||||
{ViewName: "menu", Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.handleMenuNextLine}, {
|
|
||||||
ViewName: "staging",
|
ViewName: "staging",
|
||||||
Key: gocui.KeyEsc,
|
Key: gocui.KeyEsc,
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
@ -487,6 +469,26 @@ func (gui *Gui) GetKeybindings() []*Binding {
|
|||||||
}...)
|
}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listPanelMap := map[string]struct {
|
||||||
|
prevLine func(*gocui.Gui, *gocui.View) error
|
||||||
|
nextLine func(*gocui.Gui, *gocui.View) error
|
||||||
|
}{
|
||||||
|
"menu": {prevLine: gui.handleMenuPrevLine, nextLine: gui.handleMenuNextLine},
|
||||||
|
"files": {prevLine: gui.handleFilesPrevLine, nextLine: gui.handleFilesNextLine},
|
||||||
|
"branches": {prevLine: gui.handleBranchesPrevLine, nextLine: gui.handleBranchesNextLine},
|
||||||
|
"commits": {prevLine: gui.handleCommitsPrevLine, nextLine: gui.handleCommitsNextLine},
|
||||||
|
"stash": {prevLine: gui.handleStashPrevLine, nextLine: gui.handleStashNextLine},
|
||||||
|
}
|
||||||
|
|
||||||
|
for viewName, functions := range listPanelMap {
|
||||||
|
bindings = append(bindings, []*Binding{
|
||||||
|
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: functions.prevLine},
|
||||||
|
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: functions.prevLine},
|
||||||
|
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: functions.nextLine},
|
||||||
|
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: functions.nextLine},
|
||||||
|
}...)
|
||||||
|
}
|
||||||
|
|
||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,22 +25,18 @@ func (gui *Gui) handleMenuPrevLine(g *gocui.Gui, v *gocui.View) error {
|
|||||||
panelState := gui.State.Panels.Menu
|
panelState := gui.State.Panels.Menu
|
||||||
gui.changeSelectedLine(&panelState.SelectedLine, v.LinesHeight(), true)
|
gui.changeSelectedLine(&panelState.SelectedLine, v.LinesHeight(), true)
|
||||||
|
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Commits.SelectedLine, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return gui.handleMenuSelect(g, v)
|
return gui.handleMenuSelect(g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// specific functions
|
// specific functions
|
||||||
|
|
||||||
func (gui *Gui) renderMenuOptions(g *gocui.Gui) error {
|
func (gui *Gui) renderMenuOptions() error {
|
||||||
optionsMap := map[string]string{
|
optionsMap := map[string]string{
|
||||||
"esc/q": gui.Tr.SLocalize("close"),
|
"esc/q": gui.Tr.SLocalize("close"),
|
||||||
"↑ ↓": gui.Tr.SLocalize("navigate"),
|
"↑ ↓": gui.Tr.SLocalize("navigate"),
|
||||||
"space": gui.Tr.SLocalize("execute"),
|
"space": gui.Tr.SLocalize("execute"),
|
||||||
}
|
}
|
||||||
return gui.renderOptionsMap(g, optionsMap)
|
return gui.renderOptionsMap(optionsMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleMenuClose(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleMenuClose(g *gocui.Gui, v *gocui.View) error {
|
||||||
@ -68,10 +64,6 @@ func (gui *Gui) createMenu(items interface{}, handlePress func(int) error) error
|
|||||||
fmt.Fprint(menuView, list)
|
fmt.Fprint(menuView, list)
|
||||||
gui.State.Panels.Menu.SelectedLine = 0
|
gui.State.Panels.Menu.SelectedLine = 0
|
||||||
|
|
||||||
if err := gui.renderMenuOptions(gui.g); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
wrappedHandlePress := func(g *gocui.Gui, v *gocui.View) error {
|
wrappedHandlePress := func(g *gocui.Gui, v *gocui.View) error {
|
||||||
selectedLine := gui.State.Panels.Menu.SelectedLine
|
selectedLine := gui.State.Panels.Menu.SelectedLine
|
||||||
return handlePress(selectedLine)
|
return handlePress(selectedLine)
|
||||||
|
@ -194,9 +194,6 @@ func (gui *Gui) refreshMergePanel(g *gocui.Gui) error {
|
|||||||
gui.State.ConflictIndex = len(gui.State.Conflicts) - 1
|
gui.State.ConflictIndex = len(gui.State.Conflicts) - 1
|
||||||
}
|
}
|
||||||
hasFocus := gui.currentViewName(g) == "main"
|
hasFocus := gui.currentViewName(g) == "main"
|
||||||
if hasFocus {
|
|
||||||
gui.renderMergeOptions(g)
|
|
||||||
}
|
|
||||||
content, err := gui.coloredConflictFile(cat, gui.State.Conflicts, gui.State.ConflictIndex, gui.State.ConflictTop, hasFocus)
|
content, err := gui.coloredConflictFile(cat, gui.State.Conflicts, gui.State.ConflictIndex, gui.State.ConflictTop, hasFocus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -233,8 +230,8 @@ func (gui *Gui) switchToMerging(g *gocui.Gui) error {
|
|||||||
return gui.refreshMergePanel(g)
|
return gui.refreshMergePanel(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderMergeOptions(g *gocui.Gui) error {
|
func (gui *Gui) renderMergeOptions() error {
|
||||||
return gui.renderOptionsMap(g, map[string]string{
|
return gui.renderOptionsMap(map[string]string{
|
||||||
"↑ ↓": gui.Tr.SLocalize("selectHunk"),
|
"↑ ↓": gui.Tr.SLocalize("selectHunk"),
|
||||||
"← →": gui.Tr.SLocalize("navigateConflicts"),
|
"← →": gui.Tr.SLocalize("navigateConflicts"),
|
||||||
"space": gui.Tr.SLocalize("pickHunk"),
|
"space": gui.Tr.SLocalize("pickHunk"),
|
||||||
|
@ -30,7 +30,7 @@ func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
go func() {
|
go func() {
|
||||||
// doing this asynchronously cos it can take time
|
// doing this asynchronously cos it can take time
|
||||||
diff, _ := gui.GitCommand.GetStashEntryDiff(stashEntry.Index)
|
diff, _ := gui.GitCommand.GetStashEntryDiff(stashEntry.Index)
|
||||||
gui.renderString(g, "main", diff)
|
_ = gui.renderString(g, "main", diff)
|
||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ func (gui *Gui) refreshStatus(g *gocui.Gui) error {
|
|||||||
// contents end up cleared
|
// contents end up cleared
|
||||||
g.Update(func(*gocui.Gui) error {
|
g.Update(func(*gocui.Gui) error {
|
||||||
v.Clear()
|
v.Clear()
|
||||||
pushables, pullables := gui.GitCommand.UpstreamDifferenceCount()
|
pushables, pullables := gui.GitCommand.GetCurrentBranchUpstreamDifferenceCount()
|
||||||
fmt.Fprint(v, "↑"+pushables+"↓"+pullables)
|
fmt.Fprint(v, "↑"+pushables+"↓"+pullables)
|
||||||
branches := gui.State.Branches
|
branches := gui.State.Branches
|
||||||
if err := gui.updateHasMergeConflictStatus(); err != nil {
|
if err := gui.updateHasMergeConflictStatus(); err != nil {
|
||||||
@ -48,6 +48,8 @@ func (gui *Gui) handleCheckForUpdate(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
blue := color.New(color.FgBlue)
|
||||||
|
|
||||||
dashboardString := strings.Join(
|
dashboardString := strings.Join(
|
||||||
[]string{
|
[]string{
|
||||||
lazygitTitle(),
|
lazygitTitle(),
|
||||||
@ -56,7 +58,7 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
"Config Options: https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md",
|
"Config Options: https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md",
|
||||||
"Tutorial: https://youtu.be/VDXvbHZYeKY",
|
"Tutorial: https://youtu.be/VDXvbHZYeKY",
|
||||||
"Raise an Issue: https://github.com/jesseduffield/lazygit/issues",
|
"Raise an Issue: https://github.com/jesseduffield/lazygit/issues",
|
||||||
"Buy Jesse a coffee: https://donorbox.org/lazygit",
|
blue.Sprint("Buy Jesse a coffee: https://donorbox.org/lazygit"), // caffeine ain't free
|
||||||
}, "\n\n")
|
}, "\n\n")
|
||||||
|
|
||||||
return gui.renderString(g, "main", dashboardString)
|
return gui.renderString(g, "main", dashboardString)
|
||||||
|
@ -13,11 +13,16 @@ import (
|
|||||||
var cyclableViews = []string{"status", "files", "branches", "commits", "stash"}
|
var cyclableViews = []string{"status", "files", "branches", "commits", "stash"}
|
||||||
|
|
||||||
func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
|
func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
|
||||||
gui.refreshBranches(g)
|
if err := gui.refreshBranches(g); err != nil {
|
||||||
gui.refreshFiles(g)
|
return err
|
||||||
gui.refreshCommits(g)
|
}
|
||||||
gui.refreshStashEntries(g)
|
if err := gui.refreshFiles(g); err != nil {
|
||||||
return nil
|
return err
|
||||||
|
}
|
||||||
|
if err := gui.refreshCommits(g); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return gui.refreshStashEntries(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
||||||
@ -81,7 +86,7 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
|||||||
func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
|
||||||
switch v.Name() {
|
switch v.Name() {
|
||||||
case "menu":
|
case "menu":
|
||||||
return nil
|
return gui.handleMenuSelect(g, v)
|
||||||
case "status":
|
case "status":
|
||||||
return gui.handleStatusSelect(g, v)
|
return gui.handleStatusSelect(g, v)
|
||||||
case "files":
|
case "files":
|
||||||
@ -160,6 +165,10 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error {
|
|||||||
|
|
||||||
g.Cursor = newView.Editable
|
g.Cursor = newView.Editable
|
||||||
|
|
||||||
|
if err := gui.renderPanelOptions(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return gui.newLineFocused(g, newView)
|
return gui.newLineFocused(g, newView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,8 +249,8 @@ func (gui *Gui) optionsMapToString(optionsMap map[string]string) string {
|
|||||||
return strings.Join(optionsArray, ", ")
|
return strings.Join(optionsArray, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderOptionsMap(g *gocui.Gui, optionsMap map[string]string) error {
|
func (gui *Gui) renderOptionsMap(optionsMap map[string]string) error {
|
||||||
return gui.renderString(g, "options", gui.optionsMapToString(optionsMap))
|
return gui.renderString(gui.g, "options", gui.optionsMapToString(optionsMap))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor properly
|
// TODO: refactor properly
|
||||||
@ -312,22 +321,6 @@ func (gui *Gui) resizePopupPanel(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// focusLine focuses and selects the given line
|
|
||||||
func (gui *Gui) focusLine(lineNumber int, v *gocui.View) error {
|
|
||||||
_, height := v.Size()
|
|
||||||
overScroll := lineNumber - height + 1
|
|
||||||
if overScroll < 0 {
|
|
||||||
overScroll = 0
|
|
||||||
}
|
|
||||||
if err := v.SetOrigin(0, overScroll); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := v.SetCursor(0, lineNumber-overScroll); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// generalFocusLine takes a lineNumber to focus, and a bottomLine to ensure we can see
|
// generalFocusLine takes a lineNumber to focus, and a bottomLine to ensure we can see
|
||||||
func (gui *Gui) generalFocusLine(lineNumber int, bottomLine int, v *gocui.View) error {
|
func (gui *Gui) generalFocusLine(lineNumber int, bottomLine int, v *gocui.View) error {
|
||||||
_, height := v.Size()
|
_, height := v.Size()
|
||||||
@ -367,3 +360,28 @@ func (gui *Gui) refreshSelectedLine(line *int, total int) {
|
|||||||
*line = total - 1
|
*line = total - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) renderListPanel(v *gocui.View, items interface{}) error {
|
||||||
|
gui.g.Update(func(g *gocui.Gui) error {
|
||||||
|
list, err := utils.RenderList(items)
|
||||||
|
if err != nil {
|
||||||
|
return gui.createErrorPanel(gui.g, err.Error())
|
||||||
|
}
|
||||||
|
v.Clear()
|
||||||
|
fmt.Fprint(v, list)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) renderPanelOptions() error {
|
||||||
|
currentView := gui.g.CurrentView()
|
||||||
|
switch currentView.Name() {
|
||||||
|
case "menu":
|
||||||
|
return gui.renderMenuOptions()
|
||||||
|
case "main":
|
||||||
|
return gui.renderMergeOptions()
|
||||||
|
default:
|
||||||
|
return gui.renderGlobalOptions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -435,6 +435,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
|||||||
}, &i18n.Message{
|
}, &i18n.Message{
|
||||||
ID: "CantFindHunk",
|
ID: "CantFindHunk",
|
||||||
Other: `Could not find hunk`,
|
Other: `Could not find hunk`,
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "FastForward",
|
||||||
|
Other: `fast-forward this branch from its upstream`,
|
||||||
|
}, &i18n.Message{
|
||||||
|
ID: "Fetching",
|
||||||
|
Other: "fetching and fast-forwarding {{.from}} -> {{.to}} ...",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -517,3 +517,14 @@ func TestPrevIndex(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAsJson(t *testing.T) {
|
||||||
|
type myStruct struct {
|
||||||
|
a string
|
||||||
|
}
|
||||||
|
|
||||||
|
output := AsJson(&myStruct{a: "foo"})
|
||||||
|
|
||||||
|
// no idea why this is returning empty hashes but it's works in the app ¯\_(ツ)_/¯
|
||||||
|
assert.EqualValues(t, "{}", output)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user