mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-21 23:01:03 +00:00
more progress
This commit is contained in:
parent
cf5ec17197
commit
09eaab23f4
9 changed files with 174 additions and 34 deletions
4
main.go
4
main.go
|
|
@ -34,6 +34,10 @@ func main() {
|
|||
fmt.Printf("%s\n", config.GetDefaultConfig())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// for now we're always in debug mode so we're not passing *debuggingFlag
|
||||
*debuggingFlag = true
|
||||
|
||||
appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, *debuggingFlag)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
|
|
|
|||
|
|
@ -9,32 +9,34 @@ import (
|
|||
// Container : A git Container
|
||||
type Container struct {
|
||||
Name string
|
||||
ServiceName string
|
||||
ID string
|
||||
State string
|
||||
Container types.Container
|
||||
DisplayString string
|
||||
}
|
||||
|
||||
// GetDisplayStrings returns the dispaly string of Container
|
||||
func (b *Container) GetDisplayStrings(isFocused bool) []string {
|
||||
displayName := utils.ColoredString(b.Name, b.GetColor())
|
||||
func (c *Container) GetDisplayStrings(isFocused bool) []string {
|
||||
displayName := utils.ColoredString(c.Name, c.GetColor())
|
||||
|
||||
return []string{displayName}
|
||||
return []string{c.ServiceName, displayName}
|
||||
}
|
||||
|
||||
// GetColor Container color
|
||||
func (b *Container) GetColor() color.Attribute {
|
||||
return color.FgWhite
|
||||
|
||||
// todo: change color based on state.
|
||||
|
||||
switch b.State {
|
||||
case "feature":
|
||||
return color.FgGreen
|
||||
case "bugfix":
|
||||
return color.FgYellow
|
||||
case "hotfix":
|
||||
func (c *Container) GetColor() color.Attribute {
|
||||
switch c.Container.State {
|
||||
case "exited":
|
||||
return color.FgRed
|
||||
case "created":
|
||||
return color.FgCyan
|
||||
case "running":
|
||||
return color.FgGreen
|
||||
case "paused":
|
||||
return color.FgYellow
|
||||
case "dead":
|
||||
return color.FgRed
|
||||
case "restarting":
|
||||
return color.FgBlue
|
||||
default:
|
||||
return color.FgWhite
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package commands
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||
|
|
@ -38,16 +40,22 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localize
|
|||
|
||||
// GetContainers returns a slice of docker containers
|
||||
func (c *DockerCommand) GetContainers() ([]*Container, error) {
|
||||
containers, err := c.Client.ContainerList(context.Background(), types.ContainerListOptions{})
|
||||
containers, err := c.Client.ContainerList(context.Background(), types.ContainerListOptions{All: true})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ownContainers := make([]*Container, len(containers))
|
||||
|
||||
for i, container := range containers {
|
||||
fmt.Printf("%s %s\n", container.ID[:10], container.Image)
|
||||
ownContainers[i] = &Container{ID: container.ID, Name: "test", Container: container}
|
||||
c.Log.Warn(spew.Sdump(container))
|
||||
c.Log.Warn(fmt.Sprintf("%s %s\n", container.ID[:10], container.Image))
|
||||
serviceName, ok := container.Labels["com.docker.compose.service"]
|
||||
if !ok {
|
||||
serviceName = ""
|
||||
c.Log.Warn("Could not get service name from docker container")
|
||||
}
|
||||
ownContainers[i] = &Container{ID: container.ID, Name: strings.TrimLeft(container.Names[0], "/"), ServiceName: serviceName, Container: container}
|
||||
}
|
||||
|
||||
return ownContainers, nil
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ func GetDefaultConfig() []byte {
|
|||
`gui:
|
||||
## stuff relating to the UI
|
||||
scrollHeight: 2
|
||||
scrollPastBottom: true
|
||||
scrollPastBottom: false
|
||||
mouseEvents: false # will default to true when the feature is complete
|
||||
theme:
|
||||
activeBorderColor:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
package gui
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazydocker/pkg/commands"
|
||||
"github.com/jesseduffield/lazydocker/pkg/utils"
|
||||
|
|
@ -48,21 +54,71 @@ func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View, alreadySelect
|
|||
return err
|
||||
}
|
||||
|
||||
// container, err := gui.getSelectedContainer(g)
|
||||
// if err != nil {
|
||||
// if err != gui.Errors.ErrNoContainers {
|
||||
// return err
|
||||
// }
|
||||
// return gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedContainers"))
|
||||
// }
|
||||
container, err := gui.getSelectedContainer(g)
|
||||
if err != nil {
|
||||
if err != gui.Errors.ErrNoContainers {
|
||||
return err
|
||||
}
|
||||
return gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedContainers"))
|
||||
}
|
||||
|
||||
if err := gui.focusPoint(0, gui.State.Panels.Containers.SelectedLine, len(gui.State.Containers), v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: render logs
|
||||
// data, err := json.MarshalIndent(&container.Container, "", " ")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
return gui.renderString(g, "main", "haha")
|
||||
logsReader, err := gui.DockerCommand.Client.ContainerLogs(context.Background(), container.Container.ID, types.ContainerLogsOptions{
|
||||
ShowStdout: true,
|
||||
ShowStderr: true,
|
||||
Follow: true,
|
||||
Tail: "20",
|
||||
Timestamps: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mainView := gui.getMainView()
|
||||
|
||||
gui.State.MainWriterID++
|
||||
writerID := gui.State.MainWriterID
|
||||
mainView.Clear()
|
||||
gui.Log.Warn(writerID)
|
||||
|
||||
go func() {
|
||||
defer logsReader.Close()
|
||||
|
||||
time.Sleep(time.Second / 10)
|
||||
|
||||
rd := bufio.NewReader(logsReader)
|
||||
for {
|
||||
if gui.State.MainWriterID != writerID {
|
||||
return
|
||||
}
|
||||
|
||||
line, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
|
||||
gui.Log.Errorf("read file line error: %v", err)
|
||||
return
|
||||
}
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
mainView.Write([]byte(line))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
|
||||
// return gui.renderString(g, "main", string(data))
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshContainers() error {
|
||||
|
|
@ -77,6 +133,10 @@ func (gui *Gui) refreshContainers() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if len(gui.State.Containers) > 0 && gui.State.Panels.Containers.SelectedLine == -1 {
|
||||
gui.State.Panels.Containers.SelectedLine = 0
|
||||
}
|
||||
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
|
||||
containersView.Clear()
|
||||
|
|
@ -114,9 +174,17 @@ func (gui *Gui) handleContainersNextLine(g *gocui.Gui, v *gocui.View) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
gui.Log.Warn("nexting")
|
||||
gui.Log.Warn(spew.Sdump(gui.State.Panels.Containers))
|
||||
gui.Log.Warn(len(gui.State.Containers))
|
||||
|
||||
panelState := gui.State.Panels.Containers
|
||||
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Containers), false)
|
||||
|
||||
gui.Log.Warn("nexting2")
|
||||
gui.Log.Warn(spew.Sdump(gui.State.Panels.Containers))
|
||||
gui.Log.Warn(len(gui.State.Containers))
|
||||
|
||||
return gui.handleContainerSelect(gui.g, v, false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ type guiState struct {
|
|||
Updating bool
|
||||
Panels *panelStates
|
||||
SubProcessOutput string
|
||||
MainWriterID int
|
||||
}
|
||||
|
||||
// NewGui builds a new gui handler
|
||||
|
|
@ -107,6 +108,7 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
|
|||
Containers: &containerPanelState{SelectedLine: -1},
|
||||
Menu: &menuPanelState{SelectedLine: 0},
|
||||
},
|
||||
MainWriterID: 0,
|
||||
}
|
||||
|
||||
gui := &Gui{
|
||||
|
|
@ -127,6 +129,7 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
|
|||
|
||||
func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error {
|
||||
mainView, _ := g.View("main")
|
||||
mainView.Autoscroll = false
|
||||
ox, oy := mainView.Origin()
|
||||
newOy := int(math.Max(0, float64(oy-gui.Config.GetUserConfig().GetInt("gui.scrollHeight"))))
|
||||
return mainView.SetOrigin(ox, newOy)
|
||||
|
|
@ -143,6 +146,8 @@ func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error {
|
|||
if y < len(mainView.BufferLines()) {
|
||||
return mainView.SetOrigin(ox, oy+gui.Config.GetUserConfig().GetInt("gui.scrollHeight"))
|
||||
}
|
||||
|
||||
mainView.Autoscroll = true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +196,9 @@ func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error {
|
|||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
if v.Name() == "containers" {
|
||||
gui.State.MainWriterID++
|
||||
}
|
||||
gui.Log.Info(v.Name() + " focus lost")
|
||||
return nil
|
||||
}
|
||||
|
|
@ -242,12 +250,12 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
}
|
||||
}
|
||||
|
||||
usableSpace := height - 7
|
||||
usableSpace := height - 4
|
||||
extraSpace := usableSpace - (usableSpace/3)*3
|
||||
|
||||
vHeights := map[string]int{
|
||||
"status": 3,
|
||||
"containers": (usableSpace / 3) + extraSpace,
|
||||
"containers": (usableSpace) + extraSpace,
|
||||
"options": 1,
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +346,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
}
|
||||
|
||||
// doing this here because it'll only happen once
|
||||
if err := gui.loadNewRepo(); err != nil {
|
||||
if err := gui.loadNewDirectory(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -390,7 +398,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
return gui.resizeCurrentPopupPanel(g)
|
||||
}
|
||||
|
||||
func (gui *Gui) loadNewRepo() error {
|
||||
func (gui *Gui) loadNewDirectory() error {
|
||||
gui.Updater.CheckForNewUpdate(gui.onBackgroundUpdateCheckFinish, false)
|
||||
|
||||
gui.waitForIntro.Done()
|
||||
|
|
@ -469,7 +477,7 @@ func (gui *Gui) Run() error {
|
|||
go func() {
|
||||
gui.waitForIntro.Wait()
|
||||
// TODO: see if this is right
|
||||
gui.goEvery(time.Second*10, gui.refreshContainers)
|
||||
// gui.goEvery(time.Second*10, gui.refreshContainers)
|
||||
gui.goEvery(time.Millisecond*50, gui.renderAppStatus)
|
||||
}()
|
||||
|
||||
|
|
|
|||
24
test/printrandom/Dockerfile
Normal file
24
test/printrandom/Dockerfile
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# building the binary
|
||||
FROM golang:1.11 as builder
|
||||
|
||||
# Add Maintainer Info
|
||||
LABEL maintainer="Jesse Duffield <jessedduffield@gmail.com>"
|
||||
|
||||
# Set the Current Working Directory inside the container
|
||||
WORKDIR /src/github.com/jesseduffield/lazydocker/test/printrandom
|
||||
|
||||
# Copy everything from the current directory to the PWD(Present Working Directory) inside the container
|
||||
COPY . .
|
||||
|
||||
# Build the package
|
||||
RUN go build
|
||||
|
||||
# putting binary into a minimal image
|
||||
FROM scratch
|
||||
|
||||
WORKDIR /root/
|
||||
|
||||
COPY --from=builder /src/github.com/jesseduffield/lazydocker/test/printrandom/printrandom .
|
||||
|
||||
# Run the executable
|
||||
CMD ["./printrandom"]
|
||||
26
test/printrandom/main.go
Normal file
26
test/printrandom/main.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
exitOnInterrupt()
|
||||
|
||||
for range time.Tick(time.Second / 3) {
|
||||
fmt.Println(rand.Intn(1000))
|
||||
}
|
||||
}
|
||||
|
||||
func exitOnInterrupt() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
<-c
|
||||
os.Exit(0)
|
||||
}()
|
||||
}
|
||||
BIN
test/printrandom/printrandom
Executable file
BIN
test/printrandom/printrandom
Executable file
Binary file not shown.
Loading…
Add table
Reference in a new issue