Merge pull request #88 from pvande/feature/display-project-directory

Show Project Directory in Status Panel
This commit is contained in:
Jesse Duffield 2019-07-05 10:19:18 +10:00 committed by GitHub
commit 9207dc6faa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 94 additions and 78 deletions

View file

@ -26,6 +26,7 @@ NoViewMachingNewLineFocusedSwitchStatement
OpenConfig
pressEnterToReturn
previousContext
ProjectTitle
pruneImages
PruningStatus
remove
@ -40,7 +41,6 @@ RestartingStatus
RunningSubprocess
scroll
ServicesTitle
StatusTitle
stop
StopContainer
StoppingStatus
@ -59,4 +59,4 @@ f.lines.each_with_index do |line, index|
puts "#{key}: \"#{value}\","
end
end
end
end

View file

@ -46,7 +46,12 @@ func main() {
os.Exit(0)
}
appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles)
projectDir, err := os.Getwd()
if err != nil {
log.Fatal(err.Error())
}
appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles, projectDir)
if err != nil {
log.Fatal(err.Error())
}

View file

@ -362,10 +362,11 @@ type AppConfig struct {
BuildSource string `long:"build-source" env:"BUILD_SOURCE" default:""`
UserConfig *UserConfig
ConfigDir string
ProjectDir string
}
// NewAppConfig makes a new app config
func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag bool, composeFiles []string) (*AppConfig, error) {
func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag bool, composeFiles []string, projectDir string) (*AppConfig, error) {
configDir, err := findOrCreateConfigDir(name)
if err != nil {
return nil, err
@ -390,6 +391,7 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg
BuildSource: buildSource,
UserConfig: userConfig,
ConfigDir: configDir,
ProjectDir: projectDir,
}
return appConfig, nil

View file

@ -6,7 +6,7 @@ import (
func TestDockerComposeCommandNoFiles(t *testing.T) {
composeFiles := []string{}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles)
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
@ -21,7 +21,7 @@ func TestDockerComposeCommandNoFiles(t *testing.T) {
func TestDockerComposeCommandSingleFile(t *testing.T) {
composeFiles := []string{"one.yml"}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles)
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
@ -36,7 +36,7 @@ func TestDockerComposeCommandSingleFile(t *testing.T) {
func TestDockerComposeCommandMultipleFiles(t *testing.T) {
composeFiles := []string{"one.yml", "two.yml", "three.yml"}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles)
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)

View file

@ -81,7 +81,7 @@ type containerPanelState struct {
ContextIndex int // for specifying if you are looking at logs/stats/config/etc
}
type statusState struct {
type projectState struct {
ContextIndex int // for specifying if you are looking at credits/logs
}
@ -112,7 +112,7 @@ type panelStates struct {
Main *mainPanelState
Images *imagePanelState
Volumes *volumePanelState
Status *statusState
Project *projectState
}
type guiState struct {
@ -142,14 +142,14 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
Main: &mainPanelState{
ObjectKey: "",
},
Status: &statusState{ContextIndex: 0},
Project: &projectState{ContextIndex: 0},
},
SessionIndex: 0,
}
cyclableViews := []string{"status", "containers", "images", "volumes"}
cyclableViews := []string{"project", "containers", "images", "volumes"}
if dockerCommand.InDockerComposeProject {
cyclableViews = []string{"status", "services", "containers", "images", "volumes"}
cyclableViews = []string{"project", "services", "containers", "images", "volumes"}
}
gui := &Gui{
@ -271,6 +271,7 @@ func (gui *Gui) Run() error {
gui.waitForIntro.Wait()
gui.goEvery(time.Millisecond*50, gui.renderAppStatus)
gui.goEvery(time.Millisecond*30, gui.reRenderMain)
gui.goEvery(time.Millisecond*100, gui.refreshProject)
gui.goEvery(time.Millisecond*100, gui.refreshContainersAndServices)
gui.goEvery(time.Millisecond*100, gui.refreshVolumes)
gui.goEvery(time.Millisecond*1000, gui.DockerCommand.UpdateContainerDetails)

View file

@ -126,51 +126,51 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleCustomCommand,
},
{
ViewName: "status",
ViewName: "project",
Key: 'e',
Modifier: gocui.ModNone,
Handler: gui.handleEditConfig,
Description: gui.Tr.EditConfig,
},
{
ViewName: "status",
ViewName: "project",
Key: 'o',
Modifier: gocui.ModNone,
Handler: gui.handleOpenConfig,
Description: gui.Tr.OpenConfig,
},
{
ViewName: "status",
ViewName: "project",
Key: '[',
Modifier: gocui.ModNone,
Handler: gui.handleStatusPrevContext,
Handler: gui.handleProjectPrevContext,
Description: gui.Tr.PreviousContext,
},
{
ViewName: "status",
ViewName: "project",
Key: ']',
Modifier: gocui.ModNone,
Handler: gui.handleStatusNextContext,
Handler: gui.handleProjectNextContext,
Description: gui.Tr.NextContext,
},
{
ViewName: "status",
ViewName: "project",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
Handler: gui.handleStatusClick,
Handler: gui.handleProjectClick,
},
{
ViewName: "status",
ViewName: "project",
Key: 'm',
Modifier: gocui.ModNone,
Handler: gui.handleViewAllLogs,
Description: gui.Tr.ViewLogs,
},
{
ViewName: "status",
ViewName: "project",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
Handler: gui.handleStatusSelect,
Handler: gui.handleProjectSelect,
},
{
ViewName: "menu",
@ -430,7 +430,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
}
// TODO: add more views here
for _, viewName := range []string{"status", "services", "containers", "images", "volumes", "menu"} {
for _, viewName := range []string{"project", "services", "containers", "images", "volumes", "menu"} {
bindings = append(bindings, []*Binding{
{ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView},
{ViewName: viewName, Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.nextView},
@ -464,7 +464,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
}...)
}
for _, viewName := range []string{"status", "services", "containers", "images", "volumes"} {
for _, viewName := range []string{"project", "services", "containers", "images", "volumes"} {
bindings = append(bindings, &Binding{
ViewName: viewName,
Key: gocui.KeyEnter,

View file

@ -72,7 +72,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
g.Highlight = true
width, height := g.Size()
information := gui.Config.Version
information := "lazydocker " + gui.Config.Version
if gui.g.Mouse {
donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.Donate)
information = donate + " " + information
@ -117,7 +117,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
if gui.DockerCommand.InDockerComposeProject {
tallPanels++
vHeights = map[string]int{
"status": 3,
"project": 3,
"services": usableSpace/tallPanels + usableSpace%tallPanels,
"containers": usableSpace / tallPanels,
"images": usableSpace / tallPanels,
@ -126,7 +126,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
}
} else {
vHeights = map[string]int{
"status": 3,
"project": 3,
"containers": usableSpace/tallPanels + usableSpace%tallPanels,
"images": usableSpace / tallPanels,
"volumes": usableSpace / tallPanels,
@ -140,7 +140,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
defaultHeight = 1
}
vHeights = map[string]int{
"status": defaultHeight,
"project": defaultHeight,
"containers": defaultHeight,
"images": defaultHeight,
"volumes": defaultHeight,
@ -176,19 +176,19 @@ func (gui *Gui) layout(g *gocui.Gui) error {
v.IgnoreCarriageReturns = true
}
if v, err := g.SetView("status", 0, 0, leftSideWidth, vHeights["status"]-1, gocui.BOTTOM|gocui.RIGHT); err != nil {
if v, err := g.SetView("project", 0, 0, leftSideWidth, vHeights["project"]-1, gocui.BOTTOM|gocui.RIGHT); err != nil {
if err.Error() != "unknown view" {
return err
}
v.Title = gui.Tr.StatusTitle
v.Title = gui.Tr.ProjectTitle
v.FgColor = gocui.ColorDefault
}
var servicesView *gocui.View
aboveContainersView := "status"
aboveContainersView := "project"
if gui.DockerCommand.InDockerComposeProject {
aboveContainersView = "services"
servicesView, err = g.SetViewBeneath("services", "status", vHeights["services"])
servicesView, err = g.SetViewBeneath("services", "project", vHeights["services"])
if err != nil {
if err.Error() != "unknown view" {
return err

View file

@ -58,6 +58,9 @@ func (gui *Gui) onMainTabClick(tabIndex int) error {
}
switch viewName {
case "project":
gui.State.Panels.Project.ContextIndex = tabIndex
return gui.handleProjectSelect(gui.g, gui.getProjectView())
case "services":
gui.State.Panels.Services.ContextIndex = tabIndex
return gui.handleServiceSelect(gui.g, gui.getServicesView())
@ -70,9 +73,6 @@ func (gui *Gui) onMainTabClick(tabIndex int) error {
case "volumes":
gui.State.Panels.Volumes.ContextIndex = tabIndex
return gui.handleVolumeSelect(gui.g, gui.getVolumesView())
case "status":
gui.State.Panels.Status.ContextIndex = tabIndex
return gui.handleStatusSelect(gui.g, gui.getStatusView())
}
return nil

View file

@ -3,6 +3,7 @@ package gui
import (
"bytes"
"fmt"
"path"
"strings"
"github.com/fatih/color"
@ -13,33 +14,43 @@ import (
"github.com/jesseduffield/yaml"
)
func (gui *Gui) getStatusContexts() []string {
func (gui *Gui) getProjectContexts() []string {
if gui.DockerCommand.InDockerComposeProject {
return []string{"logs", "credits", "config"}
return []string{"logs", "config", "credits"}
}
return []string{"credits"}
}
func (gui *Gui) getStatusContextTitles() []string {
func (gui *Gui) getProjectContextTitles() []string {
if gui.DockerCommand.InDockerComposeProject {
return []string{gui.Tr.LogsTitle, gui.Tr.CreditsTitle, gui.Tr.DockerComposeConfigTitle}
return []string{gui.Tr.LogsTitle, gui.Tr.DockerComposeConfigTitle, gui.Tr.CreditsTitle}
}
return []string{gui.Tr.CreditsTitle}
}
func (gui *Gui) refreshStatus() error {
v := gui.getStatusView()
func (gui *Gui) refreshProject() error {
v := gui.getProjectView()
projectName := path.Base(gui.Config.ProjectDir)
if gui.DockerCommand.InDockerComposeProject {
for _, service := range gui.DockerCommand.Services {
if service.Container != nil {
projectName = service.Container.Details.Config.Labels["com.docker.compose.project"]
break
}
}
}
gui.g.Update(func(*gocui.Gui) error {
v.Clear()
fmt.Fprint(v, "lazydocker")
fmt.Fprint(v, projectName)
return nil
})
return nil
}
func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleProjectClick(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}
@ -48,15 +59,15 @@ func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error {
return err
}
return gui.handleStatusSelect(g, v)
return gui.handleProjectSelect(g, v)
}
func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleProjectSelect(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}
key := gui.getStatusContexts()[gui.State.Panels.Status.ContextIndex]
key := gui.getProjectContexts()[gui.State.Panels.Project.ContextIndex]
if !gui.shouldRefresh(key) {
return nil
}
@ -64,10 +75,10 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
gui.clearMainView()
mainView := gui.getMainView()
mainView.Tabs = gui.getStatusContextTitles()
mainView.TabIndex = gui.State.Panels.Status.ContextIndex
mainView.Tabs = gui.getProjectContextTitles()
mainView.TabIndex = gui.State.Panels.Project.ContextIndex
switch gui.getStatusContexts()[gui.State.Panels.Status.ContextIndex] {
switch gui.getProjectContexts()[gui.State.Panels.Project.ContextIndex] {
case "credits":
if err := gui.renderCredits(); err != nil {
return err
@ -176,28 +187,28 @@ func lazydockerTitle() string {
`
}
func (gui *Gui) handleStatusNextContext(g *gocui.Gui, v *gocui.View) error {
contexts := gui.getStatusContexts()
if gui.State.Panels.Status.ContextIndex >= len(contexts)-1 {
gui.State.Panels.Status.ContextIndex = 0
func (gui *Gui) handleProjectNextContext(g *gocui.Gui, v *gocui.View) error {
contexts := gui.getProjectContexts()
if gui.State.Panels.Project.ContextIndex >= len(contexts)-1 {
gui.State.Panels.Project.ContextIndex = 0
} else {
gui.State.Panels.Status.ContextIndex++
gui.State.Panels.Project.ContextIndex++
}
gui.handleStatusSelect(gui.g, v)
gui.handleProjectSelect(gui.g, v)
return nil
}
func (gui *Gui) handleStatusPrevContext(g *gocui.Gui, v *gocui.View) error {
contexts := gui.getStatusContexts()
if gui.State.Panels.Status.ContextIndex <= 0 {
gui.State.Panels.Status.ContextIndex = len(contexts) - 1
func (gui *Gui) handleProjectPrevContext(g *gocui.Gui, v *gocui.View) error {
contexts := gui.getProjectContexts()
if gui.State.Panels.Project.ContextIndex <= 0 {
gui.State.Panels.Project.ContextIndex = len(contexts) - 1
} else {
gui.State.Panels.Status.ContextIndex--
gui.State.Panels.Project.ContextIndex--
}
gui.handleStatusSelect(gui.g, v)
gui.handleProjectSelect(gui.g, v)
return nil
}

View file

@ -15,9 +15,6 @@ func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
if err := gui.refreshImages(); err != nil {
return err
}
if err := gui.refreshStatus(); err != nil {
return err
}
return nil
}
@ -85,8 +82,8 @@ func (gui *Gui) newLineFocused(v *gocui.View) error {
switch v.Name() {
case "menu":
return gui.handleMenuSelect(gui.g, v)
case "status":
return gui.handleStatusSelect(gui.g, v)
case "project":
return gui.handleProjectSelect(gui.g, v)
case "services":
return gui.handleServiceSelect(gui.g, v)
case "containers":
@ -236,6 +233,11 @@ func (gui *Gui) renderOptionsMap(optionsMap map[string]string) error {
return gui.renderString(gui.g, "options", gui.optionsMapToString(optionsMap))
}
func (gui *Gui) getProjectView() *gocui.View {
v, _ := gui.g.View("project")
return v
}
func (gui *Gui) getServicesView() *gocui.View {
v, _ := gui.g.View("services")
return v
@ -261,11 +263,6 @@ func (gui *Gui) getMainView() *gocui.View {
return v
}
func (gui *Gui) getStatusView() *gocui.View {
v, _ := gui.g.View("status")
return v
}
func (gui *Gui) trimmedContent(v *gocui.View) string {
return strings.TrimSpace(v.Buffer())
}

View file

@ -56,7 +56,7 @@ func dutchSet() TranslationSet {
GlobalTitle: "Globaal",
MainTitle: "Hooft",
StatusTitle: "Staat",
ProjectTitle: "Project",
ServicesTitle: "Diensten",
ContainersTitle: "Containers",
StandaloneContainersTitle: "Alleenstaande Containers",

View file

@ -5,7 +5,7 @@ type TranslationSet struct {
AddFavourite string
ErrorMessage string
NotEnoughSpace string
StatusTitle string
ProjectTitle string
MainTitle string
GlobalTitle string
Navigate string
@ -140,7 +140,7 @@ func englishSet() TranslationSet {
GlobalTitle: "Global",
MainTitle: "Main",
StatusTitle: "Status",
ProjectTitle: "Project",
ServicesTitle: "Services",
ContainersTitle: "Containers",
StandaloneContainersTitle: "Standalone Containers",

View file

@ -56,7 +56,7 @@ func germanSet() TranslationSet {
GlobalTitle: "Global",
MainTitle: "Haupt",
StatusTitle: "Status",
ProjectTitle: "Projekt",
ServicesTitle: "Dienste",
ContainersTitle: "Container",
StandaloneContainersTitle: "Alleinstehende Container",

View file

@ -26,7 +26,7 @@ type bindingSection struct {
func main() {
langs := []string{"pl", "nl", "en"}
mConfig, err := config.NewAppConfig("lazydocker", "", "", "", "", true, nil)
mConfig, err := config.NewAppConfig("lazydocker", "", "", "", "", true, nil, "")
if err != nil {
panic(err)
}
@ -76,7 +76,7 @@ func getBindingSections(mApp *app.App) []*bindingSection {
titleMap := map[string]string{
"global": mApp.Tr.GlobalTitle,
"main": mApp.Tr.MainTitle,
"status": mApp.Tr.StatusTitle,
"project": mApp.Tr.ProjectTitle,
"services": mApp.Tr.ServicesTitle,
"containers": mApp.Tr.ContainersTitle,
"images": mApp.Tr.ImagesTitle,