@@ -15,6 +15,7 @@ import (
15
15
"sort"
16
16
"strings"
17
17
18
+ "github.com/atotto/clipboard"
18
19
"github.com/dustin/go-humanize"
19
20
"github.com/gdamore/tcell/v2"
20
21
"github.com/pkg/profile"
@@ -326,6 +327,7 @@ func runInteractive(img *Image) error {
326
327
tree := tview .NewTreeView ().
327
328
SetRoot (root ).
328
329
SetCurrentNode (root )
330
+ navi := tview .NewTextView ()
329
331
330
332
for _ , layer := range img .Layers {
331
333
text := strings .TrimPrefix (layer .CreatedBy , "/bin/sh -c " )
@@ -340,7 +342,8 @@ func runInteractive(img *Image) error {
340
342
text = "RUN " + text
341
343
}
342
344
tn := tview .NewTreeNode (text )
343
- addFiles (tn , layer .Files , true )
345
+ tn .SetReference (layer )
346
+ addFiles (tn , layer .Files , nil )
344
347
root .AddChild (tn )
345
348
}
346
349
@@ -358,23 +361,61 @@ func runInteractive(img *Image) error {
358
361
})
359
362
360
363
tree .SetInputCapture (func (e * tcell.EventKey ) * tcell.EventKey {
361
- if e .Rune () == 'q' {
364
+ switch e .Rune () {
365
+ case 'q' :
362
366
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 )
369
372
}
373
+ case 'y' :
374
+ _ = clipboard .WriteAll (navi .GetText (true ))
370
375
}
371
376
return e
372
377
})
373
378
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
+ }
375
416
}
376
417
377
- func addFiles (node * tview.TreeNode , files []* FileInfo , root bool ) int64 {
418
+ func addFiles (node * tview.TreeNode , files []* FileInfo , parent * TreeNode ) int64 {
378
419
tree := make (map [string ][]* FileInfo )
379
420
size := int64 (0 )
380
421
for _ , f := range files {
@@ -392,28 +433,39 @@ func addFiles(node *tview.TreeNode, files []*FileInfo, root bool) int64 {
392
433
}
393
434
394
435
type entry struct {
395
- node * tview. TreeNode
436
+ node * TreeNode
396
437
size int64
397
438
}
398
439
entries := make ([]* entry , 0 , len (tree ))
399
440
for key := range tree {
400
441
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 )
402
453
entries = append (entries , & entry {
403
- node : t ,
454
+ node : child ,
404
455
size : s ,
405
456
})
406
457
}
407
458
sort .Slice (entries , func (i , j int ) bool {
408
459
return entries [i ].size > entries [j ].size
409
460
})
410
461
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 )
413
464
}
414
465
text := humanizeBytes (size ) + ": " + node .GetText ()
415
- if ! root && len (entries ) > 0 {
466
+ if parent != nil && len (entries ) > 0 {
416
467
text += "/"
468
+ parent .dir = true
417
469
}
418
470
node .SetText (text )
419
471
node .SetExpanded (false )
0 commit comments