truncate inefficiencies report (fixes #27)

This commit is contained in:
Alex Goodman 2018-10-22 17:48:43 -04:00
parent e757503234
commit 5bc7337b04
No known key found for this signature in database
GPG Key ID: 05328C611D8A520E
5 changed files with 36 additions and 44 deletions

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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) {

View File

@ -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))

View File

@ -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)
}