better error propagation on startup
This commit is contained in:
parent
56e8530dea
commit
26d37baabd
@ -13,29 +13,36 @@ type TreeCache struct {
|
|||||||
cache map[TreeCacheKey]*FileTree
|
cache map[TreeCacheKey]*FileTree
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cache *TreeCache) Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) *FileTree {
|
func (cache *TreeCache) Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) (*FileTree, error) {
|
||||||
key := TreeCacheKey{bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop}
|
key := TreeCacheKey{bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop}
|
||||||
if value, exists := cache.cache[key]; exists {
|
if value, exists := cache.cache[key]; exists {
|
||||||
return value
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
value := cache.buildTree(key)
|
value, err := cache.buildTree(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
cache.cache[key] = value
|
cache.cache[key] = value
|
||||||
return value
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cache *TreeCache) buildTree(key TreeCacheKey) *FileTree {
|
func (cache *TreeCache) buildTree(key TreeCacheKey) (*FileTree, error) {
|
||||||
newTree := StackTreeRange(cache.refTrees, key.bottomTreeStart, key.bottomTreeStop)
|
newTree, err := StackTreeRange(cache.refTrees, key.bottomTreeStart, key.bottomTreeStop)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for idx := key.topTreeStart; idx <= key.topTreeStop; idx++ {
|
for idx := key.topTreeStart; idx <= key.topTreeStop; idx++ {
|
||||||
err := newTree.CompareAndMark(cache.refTrees[idx])
|
err := newTree.CompareAndMark(cache.refTrees[idx])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("unable to build tree: %+v", err)
|
logrus.Errorf("unable to build tree: %+v", err)
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newTree
|
return newTree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cache *TreeCache) Build() {
|
func (cache *TreeCache) Build() error {
|
||||||
var bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int
|
var bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int
|
||||||
|
|
||||||
// case 1: layer compare (top tree SIZE is fixed (BUT floats forward), Bottom tree SIZE changes)
|
// case 1: layer compare (top tree SIZE is fixed (BUT floats forward), Bottom tree SIZE changes)
|
||||||
@ -51,7 +58,10 @@ func (cache *TreeCache) Build() {
|
|||||||
topTreeStart = selectIdx
|
topTreeStart = selectIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
|
_, err := cache.Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// case 2: aggregated compare (bottom tree is ENTIRELY fixed, top tree SIZE changes)
|
// case 2: aggregated compare (bottom tree is ENTIRELY fixed, top tree SIZE changes)
|
||||||
@ -66,8 +76,12 @@ func (cache *TreeCache) Build() {
|
|||||||
topTreeStart = 1
|
topTreeStart = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
|
_, err := cache.Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileTreeCache(refTrees []*FileTree) TreeCache {
|
func NewFileTreeCache(refTrees []*FileTree) TreeCache {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package filetree
|
package filetree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -63,14 +62,22 @@ func Efficiency(trees []*FileTree) (float64, EfficiencySlice) {
|
|||||||
sizeBytes += curNode.Data.FileInfo.Size
|
sizeBytes += curNode.Data.FileInfo.Size
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
stackedTree := StackTreeRange(trees, 0, currentTree-1)
|
stackedTree, err := StackTreeRange(trees, 0, currentTree-1)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("unable to stack tree range: %+v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
previousTreeNode, err := stackedTree.GetNode(node.Path())
|
previousTreeNode, err := stackedTree.GetNode(node.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Debug(fmt.Sprintf("CurrentTree: %d : %s", currentTree, err))
|
return err
|
||||||
} else if previousTreeNode.Data.FileInfo.IsDir {
|
}
|
||||||
|
|
||||||
|
if previousTreeNode.Data.FileInfo.IsDir {
|
||||||
err = previousTreeNode.VisitDepthChildFirst(sizer, nil)
|
err = previousTreeNode.VisitDepthChildFirst(sizer, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("unable to propagate whiteout dir: %+v", err)
|
logrus.Errorf("unable to propagate whiteout dir: %+v", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,14 +367,15 @@ func (tree *FileTree) markRemoved(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StackTreeRange combines an array of trees into a single tree
|
// StackTreeRange combines an array of trees into a single tree
|
||||||
func StackTreeRange(trees []*FileTree, start, stop int) *FileTree {
|
func StackTreeRange(trees []*FileTree, start, stop int) (*FileTree, error) {
|
||||||
|
|
||||||
tree := trees[0].Copy()
|
tree := trees[0].Copy()
|
||||||
for idx := start; idx <= stop; idx++ {
|
for idx := start; idx <= stop; idx++ {
|
||||||
err := tree.Stack(trees[idx])
|
err := tree.Stack(trees[idx])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("could not stack tree range: %v", err)
|
logrus.Errorf("could not stack tree range: %v", err)
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tree
|
return tree, nil
|
||||||
}
|
}
|
||||||
|
@ -745,7 +745,10 @@ func TestStackRange(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
trees := []*FileTree{lowerTree, upperTree, tree}
|
trees := []*FileTree{lowerTree, upperTree, tree}
|
||||||
StackTreeRange(trees, 0, 2)
|
_, err = StackTreeRange(trees, 0, 2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveOnIterate(t *testing.T) {
|
func TestRemoveOnIterate(t *testing.T) {
|
||||||
|
@ -2,6 +2,7 @@ package runtime
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/wagoodman/dive/dive"
|
"github.com/wagoodman/dive/dive"
|
||||||
"github.com/wagoodman/dive/runtime/ci"
|
"github.com/wagoodman/dive/runtime/ci"
|
||||||
"github.com/wagoodman/dive/runtime/export"
|
"github.com/wagoodman/dive/runtime/export"
|
||||||
@ -95,7 +96,11 @@ func Run(options Options) {
|
|||||||
|
|
||||||
fmt.Println(utils.TitleFormat("Building cache..."))
|
fmt.Println(utils.TitleFormat("Building cache..."))
|
||||||
cache := filetree.NewFileTreeCache(result.RefTrees)
|
cache := filetree.NewFileTreeCache(result.RefTrees)
|
||||||
cache.Build()
|
err := cache.Build()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
utils.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
// it appears there is a race condition where termbox.Init() will
|
// it appears there is a race condition where termbox.Init() will
|
||||||
// block nearly indefinitely when running as the first process in
|
// block nearly indefinitely when running as the first process in
|
||||||
@ -104,6 +109,12 @@ func Run(options Options) {
|
|||||||
// enough sleep will prevent this behavior (todo: remove this hack)
|
// enough sleep will prevent this behavior (todo: remove this hack)
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
ui.Run(result, cache)
|
err = ui.Run(result, cache)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
utils.Exit(1)
|
||||||
|
}
|
||||||
|
utils.Exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,11 @@ func (vm *FileTreeViewModel) setTreeByLayer(bottomTreeStart, bottomTreeStop, top
|
|||||||
if topTreeStop > len(vm.RefTrees)-1 {
|
if topTreeStop > len(vm.RefTrees)-1 {
|
||||||
return fmt.Errorf("invalid layer index given: %d of %d", topTreeStop, len(vm.RefTrees)-1)
|
return fmt.Errorf("invalid layer index given: %d of %d", topTreeStop, len(vm.RefTrees)-1)
|
||||||
}
|
}
|
||||||
newTree := vm.cache.Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
|
newTree, err := vm.cache.Get(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("unable to fetch layer tree from cache: %+v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// preserve vm state on copy
|
// preserve vm state on copy
|
||||||
visitor := func(node *filetree.FileNode) error {
|
visitor := func(node *filetree.FileNode) error {
|
||||||
@ -112,7 +116,7 @@ func (vm *FileTreeViewModel) setTreeByLayer(bottomTreeStart, bottomTreeStop, top
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := vm.ModelTree.VisitDepthChildFirst(visitor, nil)
|
err = vm.ModelTree.VisitDepthChildFirst(visitor, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("unable to propagate layer tree: %+v", err)
|
logrus.Errorf("unable to propagate layer tree: %+v", err)
|
||||||
return err
|
return err
|
||||||
|
@ -78,11 +78,18 @@ func initializeTestViewModel(t *testing.T) *FileTreeViewModel {
|
|||||||
t.Fatalf("%s: unable to fetch analysis: %v", t.Name(), err)
|
t.Fatalf("%s: unable to fetch analysis: %v", t.Name(), err)
|
||||||
}
|
}
|
||||||
cache := filetree.NewFileTreeCache(result.RefTrees)
|
cache := filetree.NewFileTreeCache(result.RefTrees)
|
||||||
cache.Build()
|
err = cache.Build()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: unable to build cache: %+v", t.Name(), err)
|
||||||
|
}
|
||||||
|
|
||||||
Formatting.Selected = color.New(color.ReverseVideo, color.Bold).SprintFunc()
|
Formatting.Selected = color.New(color.ReverseVideo, color.Bold).SprintFunc()
|
||||||
|
|
||||||
return NewFileTreeViewModel(filetree.StackTreeRange(result.RefTrees, 0, 0), result.RefTrees, cache)
|
treeStack, err := filetree.StackTreeRange(result.RefTrees, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: unable to create tree ViewModel: %v", t.Name(), err)
|
||||||
|
}
|
||||||
|
return NewFileTreeViewModel(treeStack, result.RefTrees, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTestCase(t *testing.T, vm *FileTreeViewModel, width, height int, filterRegex *regexp.Regexp) {
|
func runTestCase(t *testing.T, vm *FileTreeViewModel, width, height int, filterRegex *regexp.Regexp) {
|
||||||
|
@ -251,20 +251,32 @@ func layout(g *gocui.Gui) error {
|
|||||||
view, viewErr = g.SetView(Controllers.Layer.Name, -1, -1+headerRows, splitCols, layersHeight)
|
view, viewErr = g.SetView(Controllers.Layer.Name, -1, -1+headerRows, splitCols, layersHeight)
|
||||||
header, headerErr = g.SetView(Controllers.Layer.Name+"header", -1, -1, splitCols, headerRows)
|
header, headerErr = g.SetView(Controllers.Layer.Name+"header", -1, -1, splitCols, headerRows)
|
||||||
if isNewView(viewErr, headerErr) {
|
if isNewView(viewErr, headerErr) {
|
||||||
_ = Controllers.Layer.Setup(view, header)
|
err = Controllers.Layer.Setup(view, header)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("unable to setup layer controller", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if _, err = g.SetCurrentView(Controllers.Layer.Name); err != nil {
|
if _, err = g.SetCurrentView(Controllers.Layer.Name); err != nil {
|
||||||
|
logrus.Error("unable to set view to layer", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// since we are selecting the view, we should rerender to indicate it is selected
|
// since we are selecting the view, we should rerender to indicate it is selected
|
||||||
_ = Controllers.Layer.Render()
|
err = Controllers.Layer.Render()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("unable to render layer view", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Details
|
// Details
|
||||||
view, viewErr = g.SetView(Controllers.Details.Name, -1, -1+layersHeight+headerRows, splitCols, maxY-bottomRows)
|
view, viewErr = g.SetView(Controllers.Details.Name, -1, -1+layersHeight+headerRows, splitCols, maxY-bottomRows)
|
||||||
header, headerErr = g.SetView(Controllers.Details.Name+"header", -1, -1+layersHeight, splitCols, layersHeight+headerRows)
|
header, headerErr = g.SetView(Controllers.Details.Name+"header", -1, -1+layersHeight, splitCols, layersHeight+headerRows)
|
||||||
if isNewView(viewErr, headerErr) {
|
if isNewView(viewErr, headerErr) {
|
||||||
_ = Controllers.Details.Setup(view, header)
|
err = Controllers.Details.Setup(view, header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filetree
|
// Filetree
|
||||||
@ -275,40 +287,64 @@ func layout(g *gocui.Gui) error {
|
|||||||
view, viewErr = g.SetView(Controllers.Tree.Name, splitCols, -1+headerRows-offset, debugCols, maxY-bottomRows)
|
view, viewErr = g.SetView(Controllers.Tree.Name, splitCols, -1+headerRows-offset, debugCols, maxY-bottomRows)
|
||||||
header, headerErr = g.SetView(Controllers.Tree.Name+"header", splitCols, -1, debugCols, headerRows-offset)
|
header, headerErr = g.SetView(Controllers.Tree.Name+"header", splitCols, -1, debugCols, headerRows-offset)
|
||||||
if isNewView(viewErr, headerErr) {
|
if isNewView(viewErr, headerErr) {
|
||||||
_ = Controllers.Tree.Setup(view, header)
|
err = Controllers.Tree.Setup(view, header)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("unable to setup tree controller", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = Controllers.Tree.onLayoutChange(resized)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("unable to setup layer controller onLayoutChange", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
_ = Controllers.Tree.onLayoutChange(resized)
|
|
||||||
|
|
||||||
// Status Bar
|
// Status Bar
|
||||||
view, viewErr = g.SetView(Controllers.Status.Name, -1, maxY-statusBarHeight-statusBarIndex, maxX, maxY-(statusBarIndex-1))
|
view, viewErr = g.SetView(Controllers.Status.Name, -1, maxY-statusBarHeight-statusBarIndex, maxX, maxY-(statusBarIndex-1))
|
||||||
if isNewView(viewErr, headerErr) {
|
if isNewView(viewErr, headerErr) {
|
||||||
_ = Controllers.Status.Setup(view, nil)
|
err = Controllers.Status.Setup(view, nil)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("unable to setup status controller", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter Bar
|
// Filter Bar
|
||||||
view, viewErr = g.SetView(Controllers.Filter.Name, len(Controllers.Filter.headerStr)-1, maxY-filterBarHeight-filterBarIndex, maxX, maxY-(filterBarIndex-1))
|
view, viewErr = g.SetView(Controllers.Filter.Name, len(Controllers.Filter.headerStr)-1, maxY-filterBarHeight-filterBarIndex, maxX, maxY-(filterBarIndex-1))
|
||||||
header, headerErr = g.SetView(Controllers.Filter.Name+"header", -1, maxY-filterBarHeight-filterBarIndex, len(Controllers.Filter.headerStr), maxY-(filterBarIndex-1))
|
header, headerErr = g.SetView(Controllers.Filter.Name+"header", -1, maxY-filterBarHeight-filterBarIndex, len(Controllers.Filter.headerStr), maxY-(filterBarIndex-1))
|
||||||
if isNewView(viewErr, headerErr) {
|
if isNewView(viewErr, headerErr) {
|
||||||
_ = Controllers.Filter.Setup(view, header)
|
err = Controllers.Filter.Setup(view, header)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error("unable to setup filter controller", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update refreshes the state objects for future rendering.
|
// Update refreshes the state objects for future rendering.
|
||||||
func Update() {
|
func Update() error {
|
||||||
for _, view := range Controllers.lookup {
|
for _, view := range Controllers.lookup {
|
||||||
_ = view.Update()
|
err := view.Update()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render flushes the state objects to the screen.
|
// Render flushes the state objects to the screen.
|
||||||
func Render() {
|
func Render() error {
|
||||||
for _, view := range Controllers.lookup {
|
for _, view := range Controllers.lookup {
|
||||||
if view.IsVisible() {
|
if view.IsVisible() {
|
||||||
_ = view.Render()
|
err := view.Render()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// renderStatusOption formats key help bindings-to-title pairs.
|
// renderStatusOption formats key help bindings-to-title pairs.
|
||||||
@ -321,7 +357,7 @@ func renderStatusOption(control, title string, selected bool) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run is the UI entrypoint.
|
// Run is the UI entrypoint.
|
||||||
func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) {
|
func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) error {
|
||||||
|
|
||||||
Formatting.Selected = color.New(color.ReverseVideo, color.Bold).SprintFunc()
|
Formatting.Selected = color.New(color.ReverseVideo, color.Bold).SprintFunc()
|
||||||
Formatting.Header = color.New(color.Bold).SprintFunc()
|
Formatting.Header = color.New(color.Bold).SprintFunc()
|
||||||
@ -335,20 +371,20 @@ func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) {
|
|||||||
var err error
|
var err error
|
||||||
GlobalKeybindings.quit, err = keybinding.ParseAll(viper.GetString("keybinding.quit"))
|
GlobalKeybindings.quit, err = keybinding.ParseAll(viper.GetString("keybinding.quit"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error(err)
|
return err
|
||||||
}
|
}
|
||||||
GlobalKeybindings.toggleView, err = keybinding.ParseAll(viper.GetString("keybinding.toggle-view"))
|
GlobalKeybindings.toggleView, err = keybinding.ParseAll(viper.GetString("keybinding.toggle-view"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error(err)
|
return err
|
||||||
}
|
}
|
||||||
GlobalKeybindings.filterView, err = keybinding.ParseAll(viper.GetString("keybinding.filter-files"))
|
GlobalKeybindings.filterView, err = keybinding.ParseAll(viper.GetString("keybinding.filter-files"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
g, err := gocui.NewGui(gocui.OutputNormal)
|
g, err := gocui.NewGui(gocui.OutputNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error(err)
|
return err
|
||||||
}
|
}
|
||||||
utils.SetUi(g)
|
utils.SetUi(g)
|
||||||
defer g.Close()
|
defer g.Close()
|
||||||
@ -358,7 +394,11 @@ func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) {
|
|||||||
Controllers.Layer = NewLayerController("side", g, analysis.Layers)
|
Controllers.Layer = NewLayerController("side", g, analysis.Layers)
|
||||||
Controllers.lookup[Controllers.Layer.Name] = Controllers.Layer
|
Controllers.lookup[Controllers.Layer.Name] = Controllers.Layer
|
||||||
|
|
||||||
Controllers.Tree = NewFileTreeController("main", g, filetree.StackTreeRange(analysis.RefTrees, 0, 0), analysis.RefTrees, cache)
|
treeStack, err := filetree.StackTreeRange(analysis.RefTrees, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
Controllers.Tree = NewFileTreeController("main", g, treeStack, analysis.RefTrees, cache)
|
||||||
Controllers.lookup[Controllers.Tree.Name] = Controllers.Tree
|
Controllers.lookup[Controllers.Tree.Name] = Controllers.Tree
|
||||||
|
|
||||||
Controllers.Status = NewStatusController("status", g)
|
Controllers.Status = NewStatusController("status", g)
|
||||||
@ -381,15 +421,23 @@ func Run(analysis *image.AnalysisResult, cache filetree.TreeCache) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// perform the first update and render now that all resources have been loaded
|
// perform the first update and render now that all resources have been loaded
|
||||||
Update()
|
err = Update()
|
||||||
Render()
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = Render()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := keyBindings(g); err != nil {
|
if err := keyBindings(g); err != nil {
|
||||||
logrus.Error("keybinding error: ", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
|
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
|
||||||
logrus.Error("main loop error: ", err)
|
logrus.Error("main loop error: ", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
utils.Exit(0)
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user