truncate inefficiencies report (fixes #27)
This commit is contained in:
parent
e757503234
commit
5bc7337b04
@ -18,6 +18,6 @@ func analyze(cmd *cobra.Command, args []string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
color.New(color.Bold).Println("Analyzing Image")
|
||||
manifest, refTrees := image.InitializeData(userImage)
|
||||
ui.Run(manifest, refTrees)
|
||||
manifest, refTrees, efficiency, inefficiencies := image.InitializeData(userImage)
|
||||
ui.Run(manifest, refTrees, efficiency, inefficiencies)
|
||||
}
|
||||
|
@ -41,6 +41,6 @@ func doBuild(cmd *cobra.Command, args []string) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
manifest, refTrees := image.InitializeData(string(imageId))
|
||||
ui.Run(manifest, refTrees)
|
||||
manifest, refTrees, efficiency, inefficiencies := image.InitializeData(string(imageId))
|
||||
ui.Run(manifest, refTrees, efficiency, inefficiencies)
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func processLayerTar(line *jotframe.Line, layerMap map[string]*filetree.FileTree
|
||||
line.Close()
|
||||
}
|
||||
|
||||
func InitializeData(imageID string) ([]*Layer, []*filetree.FileTree) {
|
||||
func InitializeData(imageID string) ([]*Layer, []*filetree.FileTree, float64, filetree.EfficiencySlice) {
|
||||
var manifest ImageManifest
|
||||
var layerMap = make(map[string]*filetree.FileTree)
|
||||
var trees = make([]*filetree.FileTree, 0)
|
||||
@ -212,11 +212,11 @@ func InitializeData(imageID string) ([]*Layer, []*filetree.FileTree) {
|
||||
}
|
||||
|
||||
// save this image to disk temporarily to get the content info
|
||||
imageTarPath, tmpDir := saveImage(imageID)
|
||||
// imageTarPath, tmpDir := saveImage(imageID)
|
||||
// fmt.Println(imageTarPath)
|
||||
// fmt.Println(tmpDir)
|
||||
// imageTarPath := "/tmp/dive446223287/image.tar"
|
||||
defer os.RemoveAll(tmpDir)
|
||||
imageTarPath := "/home/wagoodman/Downloads/image/image.tar"
|
||||
// defer os.RemoveAll(tmpDir)
|
||||
|
||||
// read through the image contents and build a tree
|
||||
tarFile, err := os.Open(imageTarPath)
|
||||
@ -325,7 +325,10 @@ func InitializeData(imageID string) ([]*Layer, []*filetree.FileTree) {
|
||||
layerIdx--
|
||||
}
|
||||
|
||||
return layers, trees
|
||||
fmt.Println(" Analyzing layers...")
|
||||
efficiency, inefficiencies := filetree.Efficiency(trees)
|
||||
|
||||
return layers, trees, efficiency, inefficiencies
|
||||
}
|
||||
|
||||
func saveImage(imageID string) (string, string) {
|
||||
|
@ -22,12 +22,14 @@ type DetailsView struct {
|
||||
}
|
||||
|
||||
// NewDetailsView creates a new view object attached the the global [gocui] screen object.
|
||||
func NewDetailsView(name string, gui *gocui.Gui) (detailsView *DetailsView) {
|
||||
func NewDetailsView(name string, gui *gocui.Gui, efficiency float64, inefficiencies filetree.EfficiencySlice) (detailsView *DetailsView) {
|
||||
detailsView = new(DetailsView)
|
||||
|
||||
// populate main fields
|
||||
detailsView.Name = name
|
||||
detailsView.gui = gui
|
||||
detailsView.efficiency = efficiency
|
||||
detailsView.inefficiencies = inefficiencies
|
||||
|
||||
return detailsView
|
||||
}
|
||||
@ -76,10 +78,8 @@ func (view *DetailsView) CursorUp() error {
|
||||
return CursorUp(view.gui, view.view)
|
||||
}
|
||||
|
||||
// Update refreshes the state objects for future rendering. Note: we only need to update this view upon the initial tree load
|
||||
// Update refreshes the state objects for future rendering.
|
||||
func (view *DetailsView) Update() error {
|
||||
layerTrees := Views.Tree.RefTrees
|
||||
view.efficiency, view.inefficiencies = filetree.Efficiency(layerTrees)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -94,16 +94,21 @@ func (view *DetailsView) Render() error {
|
||||
var wastedSpace int64
|
||||
|
||||
template := "%5s %12s %-s\n"
|
||||
var trueInefficiencies int
|
||||
inefficiencyReport := fmt.Sprintf(Formatting.Header(template), "Count", "Total Space", "Path")
|
||||
for idx := len(view.inefficiencies) - 1; idx >= 0; idx-- {
|
||||
data := view.inefficiencies[idx]
|
||||
trueInefficiencies++
|
||||
wastedSpace += data.CumulativeSize
|
||||
inefficiencyReport += fmt.Sprintf(template, strconv.Itoa(len(data.Nodes)), humanize.Bytes(uint64(data.CumulativeSize)), data.Path)
|
||||
|
||||
height := 100
|
||||
if view.view != nil {
|
||||
_, height = view.view.Size()
|
||||
}
|
||||
if trueInefficiencies == 0 {
|
||||
inefficiencyReport = ""
|
||||
|
||||
for idx := 0; idx < len(view.inefficiencies); idx++ {
|
||||
data := view.inefficiencies[len(view.inefficiencies)-1-idx]
|
||||
wastedSpace += data.CumulativeSize
|
||||
|
||||
// todo: make this report scrollable and exportable
|
||||
if idx < height {
|
||||
inefficiencyReport += fmt.Sprintf(template, strconv.Itoa(len(data.Nodes)), humanize.Bytes(uint64(data.CumulativeSize)), data.Path)
|
||||
}
|
||||
}
|
||||
|
||||
effStr := fmt.Sprintf("\n%s %d %%", Formatting.Header("Image efficiency score:"), int(100.0*view.efficiency))
|
||||
|
30
ui/ui.go
30
ui/ui.go
@ -3,22 +3,16 @@ package ui
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/jroimartin/gocui"
|
||||
"github.com/wagoodman/dive/filetree"
|
||||
"github.com/wagoodman/dive/image"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"log"
|
||||
)
|
||||
|
||||
const debug = false
|
||||
const profile = false
|
||||
|
||||
var cpuProfilePath *os.File
|
||||
var memoryProfilePath *os.File
|
||||
// var profileObj = profile.Start(profile.CPUProfile, profile.ProfilePath("."), profile.NoShutdownHook)
|
||||
|
||||
// debugPrint writes the given string to the debug pane (if the debug pane is enabled)
|
||||
func debugPrint(s string) {
|
||||
@ -138,13 +132,9 @@ func CursorUp(g *gocui.Gui, v *gocui.View) error {
|
||||
|
||||
// quit is the gocui callback invoked when the user hits Ctrl+C
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
if profile {
|
||||
pprof.StopCPUProfile()
|
||||
runtime.GC() // get up-to-date statistics
|
||||
pprof.WriteHeapProfile(memoryProfilePath)
|
||||
memoryProfilePath.Close()
|
||||
cpuProfilePath.Close()
|
||||
}
|
||||
|
||||
// profileObj.Stop()
|
||||
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
||||
@ -288,7 +278,7 @@ func renderStatusOption(control, title string, selected bool) string {
|
||||
}
|
||||
|
||||
// Run is the UI entrypoint.
|
||||
func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
|
||||
func Run(layers []*image.Layer, refTrees []*filetree.FileTree, efficiency float64, inefficiencies filetree.EfficiencySlice) {
|
||||
|
||||
Formatting.Selected = color.New(color.ReverseVideo, color.Bold).SprintFunc()
|
||||
Formatting.Header = color.New(color.Bold).SprintFunc()
|
||||
@ -319,7 +309,7 @@ func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
|
||||
Views.Filter = NewFilterView("command", g)
|
||||
Views.lookup[Views.Filter.Name] = Views.Filter
|
||||
|
||||
Views.Details = NewDetailsView("details", g)
|
||||
Views.Details = NewDetailsView("details", g, efficiency, inefficiencies)
|
||||
Views.lookup[Views.Details.Name] = Views.Details
|
||||
|
||||
g.Cursor = false
|
||||
@ -337,12 +327,6 @@ func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
if profile {
|
||||
os.Create("cpu.pprof")
|
||||
os.Create("mem.pprof")
|
||||
pprof.StartCPUProfile(cpuProfilePath)
|
||||
}
|
||||
|
||||
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user