stop swallowing errors & cleanup exit logic
This commit is contained in:
parent
26d37baabd
commit
d53d8926bc
@ -3,16 +3,15 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wagoodman/dive/dive"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wagoodman/dive/runtime"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
)
|
||||
|
||||
// doAnalyzeCmd takes a docker image tag, digest, or id and displays the
|
||||
// image analysis to the screen
|
||||
func doAnalyzeCmd(cmd *cobra.Command, args []string) {
|
||||
defer utils.Cleanup()
|
||||
|
||||
if len(args) == 0 {
|
||||
printVersionFlag, err := cmd.PersistentFlags().GetBool("version")
|
||||
@ -22,13 +21,13 @@ func doAnalyzeCmd(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
fmt.Println("No image argument given")
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
userImage := args[0]
|
||||
if userImage == "" {
|
||||
fmt.Println("No image argument given")
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
initLogging()
|
||||
@ -37,13 +36,13 @@ func doAnalyzeCmd(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("ci configuration error: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
engine, err := cmd.PersistentFlags().GetString("engine")
|
||||
if err != nil {
|
||||
fmt.Printf("unable to determine engine: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
runtime.Run(runtime.Options{
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wagoodman/dive/dive"
|
||||
"github.com/wagoodman/dive/runtime"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
)
|
||||
|
||||
// buildCmd represents the build command
|
||||
@ -22,8 +21,6 @@ func init() {
|
||||
|
||||
// doBuildCmd implements the steps taken for the build command
|
||||
func doBuildCmd(cmd *cobra.Command, args []string) {
|
||||
defer utils.Cleanup()
|
||||
|
||||
initLogging()
|
||||
|
||||
// there is no cli options allowed, only config can be supplied
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
@ -36,9 +35,8 @@ the amount of wasted space and identifies the offending files from the image.`,
|
||||
func Execute() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
utils.Cleanup()
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -160,7 +158,7 @@ func getCfgFile(fromFlag string) string {
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
utils.Exit(0)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
xdgHome := os.Getenv("XDG_CONFIG_HOME")
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"fmt"
|
||||
"github.com/wagoodman/dive/dive/filetree"
|
||||
"github.com/wagoodman/dive/dive/image"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -37,7 +37,7 @@ func NewImageArchive(tarFile io.ReadCloser) (*ImageArchive, error) {
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
name := header.Name
|
||||
@ -116,8 +116,7 @@ func getFileList(tarReader *tar.Reader) ([]filetree.FileInfo, error) {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
fmt.Println(err)
|
||||
utils.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := header.Name
|
||||
|
@ -58,7 +58,7 @@ func NewImageDirectoryRef(img *podmanImage.Image) (*ImageDirectoryRef, error) {
|
||||
// record the tree and layer info
|
||||
imgDirRef.treeMap[curImg.ID()] = tree
|
||||
imgDirRef.layerMap[curImg.ID()] = curImg
|
||||
imgDirRef.layerOrder = append(imgDirRef.layerOrder, curImg.ID())
|
||||
imgDirRef.layerOrder = append([]string{curImg.ID()}, imgDirRef.layerOrder...)
|
||||
|
||||
// continue to the next image
|
||||
curImg, err = curImg.GetParent(ctx)
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/wagoodman/dive/dive"
|
||||
"github.com/wagoodman/dive/runtime/ci"
|
||||
"github.com/wagoodman/dive/runtime/export"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
@ -26,9 +27,9 @@ func runCi(analysis *image.AnalysisResult, options Options) {
|
||||
evaluator.Report()
|
||||
|
||||
if pass {
|
||||
utils.Exit(0)
|
||||
os.Exit(0)
|
||||
}
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func Run(options Options) {
|
||||
@ -44,7 +45,7 @@ func Run(options Options) {
|
||||
imageResolver, err := dive.GetImageHandler(options.Engine)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot determine image provider: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var img *image.Image
|
||||
@ -54,13 +55,13 @@ func Run(options Options) {
|
||||
img, err = imageResolver.Build(options.BuildArgs)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot build image: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
img, err = imageResolver.Fetch(options.ImageId)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot fetch image: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,14 +77,14 @@ func Run(options Options) {
|
||||
result, err := img.Analyze()
|
||||
if err != nil {
|
||||
fmt.Printf("cannot analyze image: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if doExport {
|
||||
err = export.NewExport(result).ToFile(options.ExportFile)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot write export file: %v\n", err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ func Run(options Options) {
|
||||
runCi(result, options)
|
||||
} else {
|
||||
if doExport {
|
||||
utils.Exit(0)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
fmt.Println(utils.TitleFormat("Building cache..."))
|
||||
@ -99,7 +100,7 @@ func Run(options Options) {
|
||||
err := cache.Build()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// it appears there is a race condition where termbox.Init() will
|
||||
@ -110,11 +111,10 @@ func Run(options Options) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
err = ui.Run(result, cache)
|
||||
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
utils.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
utils.Exit(0)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/wagoodman/dive/dive/filetree"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -121,22 +122,29 @@ func (controller *DetailsController) Render() error {
|
||||
layerHeaderStr := fmt.Sprintf("[Layer Details]%s", strings.Repeat("─", width-15))
|
||||
imageHeaderStr := fmt.Sprintf("[Image Details]%s", strings.Repeat("─", width-15))
|
||||
|
||||
_, _ = fmt.Fprintln(controller.header, Formatting.Header(vtclean.Clean(layerHeaderStr, false)))
|
||||
_, err := fmt.Fprintln(controller.header, Formatting.Header(vtclean.Clean(layerHeaderStr, false)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update contents
|
||||
controller.view.Clear()
|
||||
_, _ = fmt.Fprintln(controller.view, Formatting.Header("Digest: ")+currentLayer.Id())
|
||||
_, _ = fmt.Fprintln(controller.view, Formatting.Header("Command:"))
|
||||
_, _ = fmt.Fprintln(controller.view, currentLayer.Command())
|
||||
|
||||
_, _ = fmt.Fprintln(controller.view, "\n"+Formatting.Header(vtclean.Clean(imageHeaderStr, false)))
|
||||
var lines = make([]string, 0)
|
||||
lines = append(lines, Formatting.Header("Digest: ")+currentLayer.Id())
|
||||
lines = append(lines, Formatting.Header("Command:"))
|
||||
lines = append(lines, currentLayer.Command())
|
||||
lines = append(lines, "\n"+Formatting.Header(vtclean.Clean(imageHeaderStr, false)))
|
||||
lines = append(lines, imageSizeStr)
|
||||
lines = append(lines, wastedSpaceStr)
|
||||
lines = append(lines, effStr+"\n")
|
||||
lines = append(lines, inefficiencyReport)
|
||||
|
||||
_, _ = fmt.Fprintln(controller.view, imageSizeStr)
|
||||
_, _ = fmt.Fprintln(controller.view, wastedSpaceStr)
|
||||
_, _ = fmt.Fprintln(controller.view, effStr+"\n")
|
||||
|
||||
_, _ = fmt.Fprintln(controller.view, inefficiencyReport)
|
||||
return nil
|
||||
_, err = fmt.Fprintln(controller.view, strings.Join(lines, "\n"))
|
||||
if err != nil {
|
||||
logrus.Debug("unable to write to buffer: ", err)
|
||||
}
|
||||
return err
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
@ -42,15 +42,17 @@ type FileTreeController struct {
|
||||
}
|
||||
|
||||
// NewFileTreeController creates a new view object attached the the global [gocui] screen object.
|
||||
func NewFileTreeController(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (controller *FileTreeController) {
|
||||
func NewFileTreeController(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (controller *FileTreeController, err error) {
|
||||
controller = new(FileTreeController)
|
||||
|
||||
// populate main fields
|
||||
controller.Name = name
|
||||
controller.gui = gui
|
||||
controller.vm = NewFileTreeViewModel(tree, refTrees, cache)
|
||||
controller.vm, err = NewFileTreeViewModel(tree, refTrees, cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var err error
|
||||
controller.keybindingToggleCollapse, err = keybinding.ParseAll(viper.GetString("keybinding.toggle-collapse-dir"))
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
@ -100,7 +102,7 @@ func NewFileTreeController(name string, gui *gocui.Gui, tree *filetree.FileTree,
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
return controller
|
||||
return controller, err
|
||||
}
|
||||
|
||||
// Setup initializes the UI concerns within the context of a global [gocui] view object.
|
||||
@ -302,19 +304,15 @@ func (controller *FileTreeController) toggleAttributes() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// we need to render the changes to the status pane as well
|
||||
Update()
|
||||
Render()
|
||||
return nil
|
||||
// we need to render the changes to the status pane as well (not just this contoller/view)
|
||||
return UpdateAndRender()
|
||||
}
|
||||
|
||||
// toggleShowDiffType will show/hide the selected DiffType in the filetree pane.
|
||||
func (controller *FileTreeController) toggleShowDiffType(diffType filetree.DiffType) error {
|
||||
controller.vm.toggleShowDiffType(diffType)
|
||||
// we need to render the changes to the status pane as well
|
||||
Update()
|
||||
Render()
|
||||
return nil
|
||||
// we need to render the changes to the status pane as well (not just this contoller/view)
|
||||
return UpdateAndRender()
|
||||
}
|
||||
|
||||
// filterRegex will return a regular expression object to match the user's filter input.
|
||||
@ -383,10 +381,13 @@ func (controller *FileTreeController) Render() error {
|
||||
|
||||
// update the contents
|
||||
controller.view.Clear()
|
||||
_ = controller.vm.Render()
|
||||
_, _ = fmt.Fprint(controller.view, controller.vm.mainBuf.String())
|
||||
err := controller.vm.Render()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprint(controller.view, controller.vm.mainBuf.String())
|
||||
|
||||
return nil
|
||||
return err
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
@ -6,11 +6,9 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/lunixbochs/vtclean"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
|
||||
"github.com/lunixbochs/vtclean"
|
||||
"github.com/wagoodman/dive/dive/filetree"
|
||||
)
|
||||
|
||||
@ -36,7 +34,7 @@ type FileTreeViewModel struct {
|
||||
}
|
||||
|
||||
// NewFileTreeController creates a new view object attached the the global [gocui] screen object.
|
||||
func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (treeViewModel *FileTreeViewModel) {
|
||||
func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (treeViewModel *FileTreeViewModel, err error) {
|
||||
treeViewModel = new(FileTreeViewModel)
|
||||
|
||||
// populate main fields
|
||||
@ -59,11 +57,11 @@ func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree
|
||||
case "unmodified":
|
||||
treeViewModel.HiddenDiffTypes[filetree.Unmodified] = true
|
||||
default:
|
||||
utils.PrintAndExit(fmt.Sprintf("unknown diff.hide value: %s", t))
|
||||
return nil, fmt.Errorf("unknown diff.hide value: %s", t)
|
||||
}
|
||||
}
|
||||
|
||||
return treeViewModel
|
||||
return treeViewModel, nil
|
||||
}
|
||||
|
||||
// Setup initializes the UI concerns within the context of a global [gocui] view object.
|
||||
@ -420,9 +418,17 @@ func (vm *FileTreeViewModel) Render() error {
|
||||
vm.mainBuf.Reset()
|
||||
for idx, line := range lines {
|
||||
if idx == vm.bufferIndex {
|
||||
fmt.Fprintln(&vm.mainBuf, Formatting.Selected(vtclean.Clean(line, false)))
|
||||
_, err := fmt.Fprintln(&vm.mainBuf, Formatting.Selected(vtclean.Clean(line, false)))
|
||||
if err != nil {
|
||||
logrus.Debug("unable to write to buffer: ", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(&vm.mainBuf, line)
|
||||
_, err := fmt.Fprintln(&vm.mainBuf, line)
|
||||
if err != nil {
|
||||
logrus.Debug("unable to write to buffer: ", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -3,6 +3,7 @@ package ui
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jroimartin/gocui"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// FilterController holds the UI objects and data models for populating the bottom row. Specifically the pane that
|
||||
@ -99,9 +100,10 @@ func (controller *FilterController) Update() error {
|
||||
// Render flushes the state objects to the screen. Currently this is the users path filter input.
|
||||
func (controller *FilterController) Render() error {
|
||||
controller.gui.Update(func(g *gocui.Gui) error {
|
||||
// render the header
|
||||
_, err := fmt.Fprintln(controller.header, Formatting.Header(controller.headerStr))
|
||||
|
||||
if err != nil {
|
||||
logrus.Error("unable to write to buffer: ", err)
|
||||
}
|
||||
return err
|
||||
})
|
||||
return nil
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/lunixbochs/vtclean"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
"github.com/wagoodman/keybinding"
|
||||
)
|
||||
|
||||
@ -33,7 +32,7 @@ type LayerController struct {
|
||||
}
|
||||
|
||||
// NewLayerController creates a new view object attached the the global [gocui] screen object.
|
||||
func NewLayerController(name string, gui *gocui.Gui, layers []image.Layer) (controller *LayerController) {
|
||||
func NewLayerController(name string, gui *gocui.Gui, layers []image.Layer) (controller *LayerController, err error) {
|
||||
controller = new(LayerController)
|
||||
|
||||
// populate main fields
|
||||
@ -47,10 +46,9 @@ func NewLayerController(name string, gui *gocui.Gui, layers []image.Layer) (cont
|
||||
case false:
|
||||
controller.CompareMode = CompareLayer
|
||||
default:
|
||||
utils.PrintAndExit(fmt.Sprintf("unknown layer.show-aggregated-changes value: %v", mode))
|
||||
return nil, fmt.Errorf("unknown layer.show-aggregated-changes value: %v", mode)
|
||||
}
|
||||
|
||||
var err error
|
||||
controller.keybindingCompareAll, err = keybinding.ParseAll(viper.GetString("keybinding.compare-all"))
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
@ -71,7 +69,7 @@ func NewLayerController(name string, gui *gocui.Gui, layers []image.Layer) (cont
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
return controller
|
||||
return controller, err
|
||||
}
|
||||
|
||||
// Setup initializes the UI concerns within the context of a global [gocui] view object.
|
||||
@ -218,8 +216,11 @@ func (controller *LayerController) currentLayer() image.Layer {
|
||||
// setCompareMode switches the layer comparison between a single-layer comparison to an aggregated comparison.
|
||||
func (controller *LayerController) setCompareMode(compareMode CompareType) error {
|
||||
controller.CompareMode = compareMode
|
||||
Update()
|
||||
Render()
|
||||
err := UpdateAndRender()
|
||||
if err != nil {
|
||||
logrus.Errorf("unable to set compare mode: %+v", err)
|
||||
return err
|
||||
}
|
||||
return Controllers.Tree.setTreeByLayer(controller.getCompareIndexes())
|
||||
}
|
||||
|
||||
@ -283,7 +284,10 @@ func (controller *LayerController) Render() error {
|
||||
width, _ := g.Size()
|
||||
headerStr := fmt.Sprintf("[%s]%s\n", title, strings.Repeat("─", width*2))
|
||||
headerStr += fmt.Sprintf("Cmp"+image.LayerFormat, "Size", "Command")
|
||||
_, _ = fmt.Fprintln(controller.header, Formatting.Header(vtclean.Clean(headerStr, false)))
|
||||
_, err := fmt.Fprintln(controller.header, Formatting.Header(vtclean.Clean(headerStr, false)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update contents
|
||||
controller.view.Clear()
|
||||
@ -295,9 +299,14 @@ func (controller *LayerController) Render() error {
|
||||
compareBar := controller.renderCompareBar(idx)
|
||||
|
||||
if idx == controller.LayerIndex {
|
||||
_, _ = fmt.Fprintln(controller.view, compareBar+" "+Formatting.Selected(layerStr))
|
||||
_, err = fmt.Fprintln(controller.view, compareBar+" "+Formatting.Selected(layerStr))
|
||||
} else {
|
||||
_, _ = fmt.Fprintln(controller.view, compareBar+" "+layerStr)
|
||||
_, err = fmt.Fprintln(controller.view, compareBar+" "+layerStr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logrus.Debug("unable to write to buffer: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"strings"
|
||||
|
||||
@ -61,11 +62,13 @@ func (controller *StatusController) Update() error {
|
||||
func (controller *StatusController) Render() error {
|
||||
controller.gui.Update(func(g *gocui.Gui) error {
|
||||
controller.view.Clear()
|
||||
_, _ = fmt.Fprintln(controller.view, controller.KeyHelp()+Controllers.lookup[controller.gui.CurrentView().Name()].KeyHelp()+Formatting.StatusNormal("▏"+strings.Repeat(" ", 1000)))
|
||||
_, err := fmt.Fprintln(controller.view, controller.KeyHelp()+Controllers.lookup[controller.gui.CurrentView().Name()].KeyHelp()+Formatting.StatusNormal("▏"+strings.Repeat(" ", 1000)))
|
||||
if err != nil {
|
||||
logrus.Debug("unable to write to buffer: ", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
})
|
||||
// todo: blerg
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/wagoodman/dive/dive/filetree"
|
||||
"github.com/wagoodman/dive/utils"
|
||||
"github.com/wagoodman/keybinding"
|
||||
)
|
||||
|
||||
@ -72,6 +71,22 @@ type View interface {
|
||||
IsVisible() bool
|
||||
}
|
||||
|
||||
func UpdateAndRender() error {
|
||||
err := Update()
|
||||
if err != nil {
|
||||
logrus.Debug("failed update: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = Render()
|
||||
if err != nil {
|
||||
logrus.Debug("failed render: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// toggleView switches between the file view and the layer view and re-renders the screen.
|
||||
func toggleView(g *gocui.Gui, v *gocui.View) (err error) {
|
||||
if v == nil || v.Name() == Controllers.Layer.Name {
|
||||
@ -79,9 +94,13 @@ func toggleView(g *gocui.Gui, v *gocui.View) (err error) {
|
||||
} else {
|
||||
_, err = g.SetCurrentView(Controllers.Layer.Name)
|
||||
}
|
||||
Update()
|
||||
Render()
|
||||
return err
|
||||
|
||||
if err != nil {
|
||||
logrus.Error("unable to toggle view: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return UpdateAndRender()
|
||||
}
|
||||
|
||||
// toggleFilterView shows/hides the file tree filter pane.
|
||||
@ -95,22 +114,24 @@ func toggleFilterView(g *gocui.Gui, v *gocui.View) error {
|
||||
if !Controllers.Filter.hidden {
|
||||
_, err := g.SetCurrentView(Controllers.Filter.Name)
|
||||
if err != nil {
|
||||
logrus.Error("unable to toggle filter view: ", err)
|
||||
return err
|
||||
}
|
||||
Update()
|
||||
Render()
|
||||
} else {
|
||||
err := toggleView(g, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = Controllers.Filter.view.SetCursor(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return UpdateAndRender()
|
||||
}
|
||||
|
||||
err := toggleView(g, v)
|
||||
if err != nil {
|
||||
logrus.Error("unable to toggle filter view (back): ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = Controllers.Filter.view.SetCursor(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -325,9 +346,10 @@ func layout(g *gocui.Gui) error {
|
||||
|
||||
// Update refreshes the state objects for future rendering.
|
||||
func Update() error {
|
||||
for _, view := range Controllers.lookup {
|
||||
err := view.Update()
|
||||
for _, controller := range Controllers.lookup {
|
||||
err := controller.Update()
|
||||
if err != nil {
|
||||
logrus.Debug("unable to update controller: ")
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -336,9 +358,9 @@ func Update() error {
|
||||
|
||||
// Render flushes the state objects to the screen.
|
||||
func Render() error {
|
||||
for _, view := range Controllers.lookup {
|
||||
if view.IsVisible() {
|
||||
err := view.Render()
|
||||
for _, controller := range Controllers.lookup {
|
||||
if controller.IsVisible() {
|
||||
err := controller.Render()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -386,19 +408,24 @@ func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
utils.SetUi(g)
|
||||
defer g.Close()
|
||||
|
||||
Controllers.lookup = make(map[string]View)
|
||||
|
||||
Controllers.Layer = NewLayerController("side", g, analysis.Layers)
|
||||
Controllers.Layer, err = NewLayerController("side", g, analysis.Layers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Controllers.lookup[Controllers.Layer.Name] = Controllers.Layer
|
||||
|
||||
treeStack, err := filetree.StackTreeRange(analysis.RefTrees, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Controllers.Tree = NewFileTreeController("main", g, treeStack, analysis.RefTrees, cache)
|
||||
Controllers.Tree, err = NewFileTreeController("main", g, treeStack, analysis.RefTrees, cache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Controllers.lookup[Controllers.Tree.Name] = Controllers.Tree
|
||||
|
||||
Controllers.Status = NewStatusController("status", g)
|
||||
@ -421,12 +448,7 @@ func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) error {
|
||||
// }
|
||||
|
||||
// perform the first update and render now that all resources have been loaded
|
||||
err = Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = Render()
|
||||
err = UpdateAndRender()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/jroimartin/gocui"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var ui *gocui.Gui
|
||||
|
||||
func SetUi(g *gocui.Gui) {
|
||||
ui = g
|
||||
}
|
||||
|
||||
func PrintAndExit(args ...interface{}) {
|
||||
logrus.Println(args...)
|
||||
Cleanup()
|
||||
fmt.Println(args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Note: this should only be used when exiting from non-gocui code
|
||||
func Exit(rc int) {
|
||||
Cleanup()
|
||||
os.Exit(rc)
|
||||
}
|
||||
|
||||
func Cleanup() {
|
||||
if ui != nil {
|
||||
ui.Close()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user