Skip to content

Commit 754bb42

Browse files
committed
feat: add command navigator
1 parent edea11a commit 754bb42

File tree

3 files changed

+71
-16
lines changed

3 files changed

+71
-16
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/orisano/dlayer
33
go 1.14
44

55
require (
6+
github.com/atotto/clipboard v0.1.4
67
github.com/dustin/go-humanize v1.0.0
78
github.com/gdamore/tcell/v2 v2.3.1
89
github.com/mattn/go-runewidth v0.0.12 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
2+
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
13
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
24
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
35
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=

main.go

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"sort"
1616
"strings"
1717

18+
"github.com/atotto/clipboard"
1819
"github.com/dustin/go-humanize"
1920
"github.com/gdamore/tcell/v2"
2021
"github.com/pkg/profile"
@@ -326,6 +327,7 @@ func runInteractive(img *Image) error {
326327
tree := tview.NewTreeView().
327328
SetRoot(root).
328329
SetCurrentNode(root)
330+
navi := tview.NewTextView()
329331

330332
for _, layer := range img.Layers {
331333
text := strings.TrimPrefix(layer.CreatedBy, "/bin/sh -c ")
@@ -340,7 +342,8 @@ func runInteractive(img *Image) error {
340342
text = "RUN " + text
341343
}
342344
tn := tview.NewTreeNode(text)
343-
addFiles(tn, layer.Files, true)
345+
tn.SetReference(layer)
346+
addFiles(tn, layer.Files, nil)
344347
root.AddChild(tn)
345348
}
346349

@@ -358,23 +361,61 @@ func runInteractive(img *Image) error {
358361
})
359362

360363
tree.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
361-
if e.Rune() == 'q' {
364+
switch e.Rune() {
365+
case 'q':
362366
app.Stop()
363-
}
364-
if e.Rune() == 'u' {
365-
parent, ok := tree.GetCurrentNode().GetReference().(*tview.TreeNode)
366-
if ok && parent != nil {
367-
parent.SetExpanded(false)
368-
tree.SetCurrentNode(parent)
367+
case 'u':
368+
node, ok := tree.GetCurrentNode().GetReference().(*TreeNode)
369+
if ok && node.parent != nil {
370+
node.parent.value.SetExpanded(false)
371+
tree.SetCurrentNode(node.parent.value)
369372
}
373+
case 'y':
374+
_ = clipboard.WriteAll(navi.GetText(true))
370375
}
371376
return e
372377
})
373378

374-
return app.SetRoot(tree, true).Run()
379+
tree.SetChangedFunc(func(target *tview.TreeNode) {
380+
node, ok := target.GetReference().(*TreeNode)
381+
if ok {
382+
navi.SetText(node.ExtractCommand())
383+
} else {
384+
navi.SetText("")
385+
}
386+
})
387+
flex := tview.NewFlex().
388+
SetDirection(tview.FlexRow).
389+
AddItem(tree, 0, 1, true).
390+
AddItem(navi, 1, 0, false)
391+
return app.SetRoot(flex, true).SetFocus(flex).Run()
392+
}
393+
394+
type TreeNode struct {
395+
layerID string
396+
parent *TreeNode
397+
value *tview.TreeNode
398+
key string
399+
dir bool
400+
}
401+
402+
func (n *TreeNode) Path() string {
403+
if n.parent == nil {
404+
return n.key
405+
}
406+
return n.parent.Path() + "/" + n.key
407+
}
408+
409+
func (n *TreeNode) ExtractCommand() string {
410+
layerCmd := "tar xO " + n.layerID + "/layer.tar"
411+
if n.dir {
412+
return layerCmd + " | tar x " + n.Path()
413+
} else {
414+
return layerCmd + " | tar xO " + n.Path()
415+
}
375416
}
376417

377-
func addFiles(node *tview.TreeNode, files []*FileInfo, root bool) int64 {
418+
func addFiles(node *tview.TreeNode, files []*FileInfo, parent *TreeNode) int64 {
378419
tree := make(map[string][]*FileInfo)
379420
size := int64(0)
380421
for _, f := range files {
@@ -392,28 +433,39 @@ func addFiles(node *tview.TreeNode, files []*FileInfo, root bool) int64 {
392433
}
393434

394435
type entry struct {
395-
node *tview.TreeNode
436+
node *TreeNode
396437
size int64
397438
}
398439
entries := make([]*entry, 0, len(tree))
399440
for key := range tree {
400441
t := tview.NewTreeNode(key)
401-
s := addFiles(t, tree[key], false)
442+
child := &TreeNode{
443+
parent: parent,
444+
value: t,
445+
key: key,
446+
}
447+
if parent != nil {
448+
child.layerID = parent.layerID
449+
} else {
450+
child.layerID = node.GetReference().(*Layer).ID
451+
}
452+
s := addFiles(t, tree[key], child)
402453
entries = append(entries, &entry{
403-
node: t,
454+
node: child,
404455
size: s,
405456
})
406457
}
407458
sort.Slice(entries, func(i, j int) bool {
408459
return entries[i].size > entries[j].size
409460
})
410461
for _, e := range entries {
411-
node.AddChild(e.node)
412-
e.node.SetReference(node)
462+
node.AddChild(e.node.value)
463+
e.node.value.SetReference(e.node)
413464
}
414465
text := humanizeBytes(size) + ": " + node.GetText()
415-
if !root && len(entries) > 0 {
466+
if parent != nil && len(entries) > 0 {
416467
text += "/"
468+
parent.dir = true
417469
}
418470
node.SetText(text)
419471
node.SetExpanded(false)

0 commit comments

Comments
 (0)