1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-14 11:23:09 +02:00
lazygit/pkg/gui/submodules_panel.go

275 lines
8.6 KiB
Go

package gui
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/style"
)
func (gui *Gui) getSelectedSubmodule() *models.SubmoduleConfig {
selectedLine := gui.State.Panels.Submodules.SelectedLineIdx
if selectedLine == -1 || len(gui.State.Submodules) == 0 {
return nil
}
return gui.State.Submodules[selectedLine]
}
func (gui *Gui) handleSubmoduleSelect() error {
var task updateTask
submodule := gui.getSelectedSubmodule()
if submodule == nil {
task = NewRenderStringTask("No submodules")
} else {
prefix := fmt.Sprintf(
"Name: %s\nPath: %s\nUrl: %s\n\n",
style.FgGreen.Sprint(submodule.Name),
style.FgYellow.Sprint(submodule.Path),
style.FgCyan.Sprint(submodule.Url),
)
file := gui.fileForSubmodule(submodule)
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)
}
}
return gui.refreshMainViews(refreshMainOpts{
main: &viewUpdateOpts{
title: "Submodule",
task: task,
},
})
}
func (gui *Gui) refreshStateSubmoduleConfigs() error {
configs, err := gui.GitCommand.GetSubmoduleConfigs()
if err != nil {
return err
}
gui.State.Submodules = configs
return nil
}
func (gui *Gui) handleSubmoduleEnter(submodule *models.SubmoduleConfig) error {
return gui.enterSubmodule(submodule)
}
func (gui *Gui) enterSubmodule(submodule *models.SubmoduleConfig) error {
wd, err := os.Getwd()
if err != nil {
return err
}
gui.RepoPathStack = append(gui.RepoPathStack, wd)
return gui.dispatchSwitchToRepo(submodule.Path, true)
}
func (gui *Gui) removeSubmodule(submodule *models.SubmoduleConfig) error {
return gui.ask(askOpts{
title: gui.Tr.RemoveSubmodule,
prompt: fmt.Sprintf(gui.Tr.RemoveSubmodulePrompt, submodule.Name),
handleConfirm: func() error {
if err := gui.GitCommand.WithSpan(gui.Tr.Spans.RemoveSubmodule).SubmoduleDelete(submodule); err != nil {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES, FILES}})
},
})
}
func (gui *Gui) handleResetSubmodule(submodule *models.SubmoduleConfig) error {
return gui.WithWaitingStatus(gui.Tr.LcResettingSubmoduleStatus, func() error {
return gui.resetSubmodule(submodule)
})
}
func (gui *Gui) fileForSubmodule(submodule *models.SubmoduleConfig) *models.File {
for _, file := range gui.State.FileManager.GetAllFiles() {
if file.IsSubmodule([]*models.SubmoduleConfig{submodule}) {
return file
}
}
return nil
}
func (gui *Gui) resetSubmodule(submodule *models.SubmoduleConfig) error {
gitCommand := gui.GitCommand.WithSpan(gui.Tr.Spans.ResetSubmodule)
file := gui.fileForSubmodule(submodule)
if file != nil {
if err := gitCommand.UnStageFile(file.Names(), file.Tracked); err != nil {
return gui.surfaceError(err)
}
}
if err := gitCommand.SubmoduleStash(submodule); err != nil {
return gui.surfaceError(err)
}
if err := gitCommand.SubmoduleReset(submodule); err != nil {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{FILES, SUBMODULES}})
}
func (gui *Gui) handleAddSubmodule() error {
return gui.prompt(promptOpts{
title: gui.Tr.LcNewSubmoduleUrl,
handleConfirm: func(submoduleUrl string) error {
nameSuggestion := filepath.Base(strings.TrimSuffix(submoduleUrl, filepath.Ext(submoduleUrl)))
return gui.prompt(promptOpts{
title: gui.Tr.LcNewSubmoduleName,
initialContent: nameSuggestion,
handleConfirm: func(submoduleName string) error {
return gui.prompt(promptOpts{
title: gui.Tr.LcNewSubmodulePath,
initialContent: submoduleName,
handleConfirm: func(submodulePath string) error {
return gui.WithWaitingStatus(gui.Tr.LcAddingSubmoduleStatus, func() error {
err := gui.GitCommand.WithSpan(gui.Tr.Spans.AddSubmodule).SubmoduleAdd(submoduleName, submodulePath, submoduleUrl)
gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
},
})
},
})
},
})
}
func (gui *Gui) handleEditSubmoduleUrl(submodule *models.SubmoduleConfig) error {
return gui.prompt(promptOpts{
title: fmt.Sprintf(gui.Tr.LcUpdateSubmoduleUrl, submodule.Name),
initialContent: submodule.Url,
handleConfirm: func(newUrl string) error {
return gui.WithWaitingStatus(gui.Tr.LcUpdatingSubmoduleUrlStatus, func() error {
err := gui.GitCommand.WithSpan(gui.Tr.Spans.UpdateSubmoduleUrl).SubmoduleUpdateUrl(submodule.Name, submodule.Path, newUrl)
gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
},
})
}
func (gui *Gui) handleSubmoduleInit(submodule *models.SubmoduleConfig) error {
return gui.WithWaitingStatus(gui.Tr.LcInitializingSubmoduleStatus, func() error {
err := gui.GitCommand.WithSpan(gui.Tr.Spans.InitialiseSubmodule).SubmoduleInit(submodule.Path)
gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
}
func (gui *Gui) forSubmodule(callback func(*models.SubmoduleConfig) error) func() error {
return func() error {
submodule := gui.getSelectedSubmodule()
if submodule == nil {
return nil
}
return callback(submodule)
}
}
func (gui *Gui) handleResetRemoveSubmodule(submodule *models.SubmoduleConfig) error {
menuItems := []*menuItem{
{
displayString: gui.Tr.LcSubmoduleStashAndReset,
onPress: func() error {
return gui.resetSubmodule(submodule)
},
},
{
displayString: gui.Tr.LcRemoveSubmodule,
onPress: func() error {
return gui.removeSubmodule(submodule)
},
},
}
return gui.createMenu(submodule.Name, menuItems, createMenuOptions{showCancel: true})
}
func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
menuItems := []*menuItem{
{
displayStrings: []string{gui.Tr.LcBulkInitSubmodules, style.FgGreen.Sprint(gui.GitCommand.SubmoduleBulkInitCmdStr())},
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 {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
},
},
{
displayStrings: []string{gui.Tr.LcBulkUpdateSubmodules, style.FgYellow.Sprint(gui.GitCommand.SubmoduleBulkUpdateCmdStr())},
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 {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
},
},
{
displayStrings: []string{gui.Tr.LcSubmoduleStashAndReset, style.FgRed.Sprintf("git stash in each submodule && %s", gui.GitCommand.SubmoduleForceBulkUpdateCmdStr())},
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 {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
},
},
{
displayStrings: []string{gui.Tr.LcBulkDeinitSubmodules, style.FgRed.Sprint(gui.GitCommand.SubmoduleBulkDeinitCmdStr())},
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 {
return gui.surfaceError(err)
}
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
},
},
}
return gui.createMenu(gui.Tr.LcBulkSubmoduleOptions, menuItems, createMenuOptions{showCancel: true})
}
func (gui *Gui) handleUpdateSubmodule(submodule *models.SubmoduleConfig) error {
return gui.WithWaitingStatus(gui.Tr.LcUpdatingSubmoduleStatus, func() error {
err := gui.GitCommand.WithSpan(gui.Tr.Spans.UpdateSubmodule).SubmoduleUpdate(submodule.Path)
gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{SUBMODULES}})
})
}