summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filetree/node.go3
-rw-r--r--filetree/tree.go4
-rw-r--r--filetree/tree_test.go2
-rw-r--r--image/image.go9
-rw-r--r--ui/filetreeview.go62
-rw-r--r--ui/layerview.go26
-rw-r--r--ui/statusview.go7
-rw-r--r--ui/ui.go6
8 files changed, 76 insertions, 43 deletions
diff --git a/filetree/node.go b/filetree/node.go
index 979ecf1..8ba41f0 100644
--- a/filetree/node.go
+++ b/filetree/node.go
@@ -1,14 +1,13 @@
package filetree
import (
+ "archive/tar"
"sort"
"strings"
-
"github.com/fatih/color"
"fmt"
"github.com/phayes/permbits"
"github.com/dustin/go-humanize"
- "github.com/wagoodman/docker-image-explorer/_vendor-20180604210951/github.com/Microsoft/go-winio/archive/tar"
)
const (
diff --git a/filetree/tree.go b/filetree/tree.go
index 01e405f..5fdbcbe 100644
--- a/filetree/tree.go
+++ b/filetree/tree.go
@@ -217,9 +217,9 @@ func (tree *FileTree) MarkRemoved(path string) error {
return node.AssignDiffType(Removed)
}
-func StackRange(trees []*FileTree, index int) *FileTree {
+func StackRange(trees []*FileTree, start, stop int) *FileTree {
tree := trees[0].Copy()
- for idx := 0; idx <= index; idx++ {
+ for idx := start; idx <= stop; idx++ {
tree.Stack(trees[idx])
}
return tree
diff --git a/filetree/tree_test.go b/filetree/tree_test.go
index 44b8e60..429d0de 100644
--- a/filetree/tree_test.go
+++ b/filetree/tree_test.go
@@ -423,7 +423,7 @@ func TestStackRange(t *testing.T) {
upperTree.AddPath(value, fakeData)
}
trees := []*FileTree{lowerTree, upperTree, tree}
- StackRange(trees, 2)
+ StackRange(trees, 0, 2)
}
diff --git a/image/image.go b/image/image.go
index 4934fee..6faf921 100644
--- a/image/image.go
+++ b/image/image.go
@@ -55,12 +55,17 @@ type Layer struct {
History types.ImageHistory
}
-func (layer *Layer) String() string {
+func (layer *Layer) Id() string {
id := layer.History.ID[0:25]
if len(layer.History.Tags) > 0 {
id = "[" + strings.Join(layer.History.Tags, ",") + "]"
}
- return fmt.Sprintf(LayerFormat, id, humanize.Bytes(uint64(layer.History.Size)), layer.History.CreatedBy)
+ return id
+}
+
+func (layer *Layer) String() string {
+
+ return fmt.Sprintf(LayerFormat, layer.Id(), humanize.Bytes(uint64(layer.History.Size)), strings.TrimPrefix(layer.History.CreatedBy, "/bin/sh -c "))
}
func InitializeData(imageID string) ([]*Layer, []*filetree.FileTree) {
diff --git a/ui/filetreeview.go b/ui/filetreeview.go
index 8b49f8e..5f95592 100644
--- a/ui/filetreeview.go
+++ b/ui/filetreeview.go
@@ -6,21 +6,30 @@ import (
"github.com/jroimartin/gocui"
"github.com/wagoodman/docker-image-explorer/filetree"
- "github.com/fatih/color"
"strings"
"github.com/lunixbochs/vtclean"
)
+const (
+ CompareLayer CompareType = iota
+ CompareAll
+)
+
+type CompareType int
+
+
type FileTreeView struct {
- Name string
- gui *gocui.Gui
- view *gocui.View
- header *gocui.View
- TreeIndex int
- ModelTree *filetree.FileTree
- ViewTree *filetree.FileTree
- RefTrees []*filetree.FileTree
- HiddenDiffTypes []bool
+ Name string
+ gui *gocui.Gui
+ view *gocui.View
+ header *gocui.View
+ ModelTree *filetree.FileTree
+ ViewTree *filetree.FileTree
+ RefTrees []*filetree.FileTree
+ HiddenDiffTypes []bool
+ CompareMode CompareType
+ CompareStartIndex int
+ CompareStopIndex int
}
func NewFileTreeView(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree) (treeview *FileTreeView) {
@@ -32,6 +41,7 @@ func NewFileTreeView(name string, gui *gocui.Gui, tree *filetree.FileTree, refTr
treeview.ModelTree = tree
treeview.RefTrees = refTrees
treeview.HiddenDiffTypes = make([]bool, 4)
+ treeview.CompareMode = CompareLayer
return treeview
}
@@ -88,8 +98,9 @@ func (view *FileTreeView) setLayer(layerIndex int) error {
if layerIndex > len(view.RefTrees)-1 {
return errors.New(fmt.Sprintf("Invalid layer index given: %d of %d", layerIndex, len(view.RefTrees)-1))
}
- newTree := filetree.StackRange(view.RefTrees, layerIndex-1)
- newTree.Compare(view.RefTrees[layerIndex])
+ view.CompareStopIndex = layerIndex
+ newTree := filetree.StackRange(view.RefTrees, view.CompareStartIndex, view.CompareStopIndex-1)
+ newTree.Compare(view.RefTrees[view.CompareStopIndex])
// preserve view state on copy
visitor := func(node *filetree.FileNode) error {
@@ -104,11 +115,11 @@ func (view *FileTreeView) setLayer(layerIndex int) error {
if debug {
v, _ := view.gui.View("debug")
v.Clear()
- _, _ = fmt.Fprintln(v, view.RefTrees[layerIndex])
+ _, _ = fmt.Fprintln(v, view.RefTrees[view.CompareStopIndex])
}
view.view.SetCursor(0, 0)
- view.TreeIndex = 0
+ view.CompareStopIndex = 0
view.ModelTree = newTree
view.updateViewTree()
return view.Render()
@@ -119,16 +130,16 @@ func (view *FileTreeView) CursorDown() error {
// to let us know what is a valid bounds (i.e. when it hits an empty line)
err := CursorDown(view.gui, view.view)
if err == nil {
- view.TreeIndex++
+ view.CompareStopIndex++
}
return view.Render()
}
func (view *FileTreeView) CursorUp() error {
- if view.TreeIndex > 0 {
+ if view.CompareStopIndex > 0 {
err := CursorUp(view.gui, view.view)
if err == nil {
- view.TreeIndex--
+ view.CompareStopIndex--
}
}
return view.Render()
@@ -140,7 +151,7 @@ func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
var dfsCounter int
visiter = func(curNode *filetree.FileNode) error {
- if dfsCounter == view.TreeIndex {
+ if dfsCounter == view.CompareStopIndex {
node = curNode
}
dfsCounter++
@@ -170,7 +181,7 @@ func (view *FileTreeView) toggleShowDiffType(diffType filetree.DiffType) error {
view.HiddenDiffTypes[diffType] = !view.HiddenDiffTypes[diffType]
view.view.SetCursor(0, 0)
- view.TreeIndex = 0
+ view.CompareStopIndex = 0
view.updateViewTree()
return view.Render()
}
@@ -193,12 +204,11 @@ func (view *FileTreeView) updateViewTree() {
}
func (view *FileTreeView) KeyHelp() string {
- control := color.New(color.Bold).SprintFunc()
- return control("[Space]") + ": Collapse dir " +
- control("[^A]") + ": Added files " +
- control("[^R]") + ": Removed files " +
- control("[^M]") + ": Modified files " +
- control("[^U]") + ": Unmodified files"
+ return Formatting.Control("[Space]") + ": Collapse dir " +
+ Formatting.Control("[^A]") + ": Added files " +
+ Formatting.Control("[^R]") + ": Removed files " +
+ Formatting.Control("[^M]") + ": Modified files " +
+ Formatting.Control("[^U]") + ": Unmodified files"
}
func (view *FileTreeView) Render() error {
@@ -207,7 +217,7 @@ func (view *FileTreeView) Render() error {
view.gui.Update(func(g *gocui.Gui) error {
view.view.Clear()
for idx, line := range lines {
- if idx == view.TreeIndex {
+ if idx == view.CompareStopIndex {
fmt.Fprintln(view.view, Formatting.StatusBar(vtclean.Clean(line, false)))
} else {
fmt.Fprintln(view.view, line)
diff --git a/ui/layerview.go b/ui/layerview.go
index d100194..f4eefa9 100644
--- a/ui/layerview.go
+++ b/ui/layerview.go
@@ -51,6 +51,13 @@ func (view *LayerView) Setup(v *gocui.View, header *gocui.View) error {
if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowUp, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorUp() }); err != nil {
return err
}
+ if err := view.gui.SetKeybinding(view.Name, gocui.KeyCtrlL, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.setCompareMode(CompareLayer) }); err != nil {
+ return err
+ }
+ if err := view.gui.SetKeybinding(view.Name, gocui.KeyCtrlA, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.setCompareMode(CompareAll) }); err != nil {
+ return err
+ }
+
headerStr := fmt.Sprintf(image.LayerFormat, "Image ID", "Size", "Command")
fmt.Fprintln(view.header, Formatting.Header(vtclean.Clean(headerStr, false)))
@@ -58,6 +65,12 @@ func (view *LayerView) Setup(v *gocui.View, header *gocui.View) error {
return view.Render()
}
+func (view *LayerView) setCompareMode(compareMode CompareType) error {
+ Views.Tree.CompareMode = compareMode
+ view.Render()
+ return Views.Tree.setLayer(Views.Tree.CompareStopIndex)
+}
+
func (view *LayerView) Render() error {
view.gui.Update(func(g *gocui.Gui) error {
view.view.Clear()
@@ -65,10 +78,16 @@ func (view *LayerView) Render() error {
layer := view.Layers[revIdx]
idx := (len(view.Layers)-1) - revIdx
+ layerStr := layer.String()
+ if idx == 0 {
+ // TODO: add size
+ layerStr = fmt.Sprintf(image.LayerFormat, layer.History.ID[0:25], "", "FROM "+layer.Id())
+ }
+
if idx == view.LayerIndex {
- fmt.Fprintln(view.view, Formatting.StatusBar(layer.String()))
+ fmt.Fprintln(view.view, Formatting.StatusBar(layerStr))
} else {
- fmt.Fprintln(view.view, layer.String())
+ fmt.Fprintln(view.view, layerStr)
}
}
@@ -103,5 +122,6 @@ func (view *LayerView) CursorUp() error {
}
func (view *LayerView) KeyHelp() string {
- return "blerg"
+ return Formatting.Control("[^L]") + ": Layer Changes " +
+ Formatting.Control("[^A]") + ": All Changes "
}
diff --git a/ui/statusview.go b/ui/statusview.go
index 99cc579..a6329bc 100644
--- a/ui/statusview.go
+++ b/ui/statusview.go
@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/jroimartin/gocui"
- "github.com/fatih/color"
)
type StatusView struct {
@@ -53,10 +52,8 @@ func (view *StatusView) CursorUp() error {
}
func (view *StatusView) KeyHelp() string {
- control := color.New(color.Bold).SprintFunc()
- return control("[^C]") + ": Quit " +
- control("[^Space]") + ": Switch View "
-
+ return Formatting.Control("[^C]") + ": Quit " +
+ Formatting.Control("[^Space]") + ": Switch View "
}
func (view *StatusView) Render() error {
diff --git a/ui/ui.go b/ui/ui.go
index 434adfd..8b58eb3 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -7,7 +7,7 @@ import (
"github.com/wagoodman/docker-image-explorer/filetree"
"github.com/wagoodman/docker-image-explorer/image"
"github.com/fatih/color"
- "github.com/wagoodman/docker-image-explorer/_vendor-20180604210951/github.com/pkg/errors"
+ "errors"
)
const debug = false
@@ -15,6 +15,7 @@ const debug = false
var Formatting struct {
Header func(...interface{})(string)
StatusBar func(...interface{})(string)
+ Control func(...interface{})(string)
}
var Views struct {
@@ -168,6 +169,7 @@ func Render() {
func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
Formatting.StatusBar = color.New(color.ReverseVideo, color.Bold).SprintFunc()
Formatting.Header = color.New(color.Bold).SprintFunc()
+ Formatting.Control = color.New(color.Bold).SprintFunc()
g, err := gocui.NewGui(gocui.OutputNormal)
if err != nil {
@@ -180,7 +182,7 @@ func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
Views.Layer = NewLayerView("side", g, layers)
Views.lookup[Views.Layer.Name] = Views.Layer
- Views.Tree = NewFileTreeView("main", g, filetree.StackRange(refTrees, 0), refTrees)
+ Views.Tree = NewFileTreeView("main", g, filetree.StackRange(refTrees, 0,0), refTrees)
Views.lookup[Views.Tree.Name] = Views.Tree
Views.Status = NewStatusView("status", g)