mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
Export UI handlers for reuse in other tools (#113)
* export UI handlers for reuse in other tools * bump jotframe to fix cursor issues at frame close
This commit is contained in:
parent
857f41b04b
commit
271ba35c85
10 changed files with 108 additions and 59 deletions
|
@ -90,7 +90,7 @@ func initAppConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initLogging() {
|
func initLogging() {
|
||||||
config := logger.LogConfig{
|
cfg := logger.LogConfig{
|
||||||
EnableConsole: (appConfig.Log.FileLocation == "" || appConfig.CliOptions.Verbosity > 0) && !appConfig.Quiet,
|
EnableConsole: (appConfig.Log.FileLocation == "" || appConfig.CliOptions.Verbosity > 0) && !appConfig.Quiet,
|
||||||
EnableFile: appConfig.Log.FileLocation != "",
|
EnableFile: appConfig.Log.FileLocation != "",
|
||||||
Level: appConfig.Log.LevelOpt,
|
Level: appConfig.Log.LevelOpt,
|
||||||
|
@ -98,7 +98,7 @@ func initLogging() {
|
||||||
FileLocation: appConfig.Log.FileLocation,
|
FileLocation: appConfig.Log.FileLocation,
|
||||||
}
|
}
|
||||||
|
|
||||||
logWrapper := logger.NewZapLogger(config)
|
logWrapper := logger.NewZapLogger(cfg)
|
||||||
syft.SetLogger(logWrapper)
|
syft.SetLogger(logWrapper)
|
||||||
stereoscope.SetLogger(logWrapper)
|
stereoscope.SetLogger(logWrapper)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ func startWorker(userInput string) <-chan error {
|
||||||
Type: event.AppUpdateAvailable,
|
Type: event.AppUpdateAvailable,
|
||||||
Value: newVersion,
|
Value: newVersion,
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
log.Debugf("No new %s update available", internal.ApplicationName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -24,7 +24,7 @@ require (
|
||||||
github.com/wagoodman/go-partybus v0.0.0-20200526224238-eb215533f07d
|
github.com/wagoodman/go-partybus v0.0.0-20200526224238-eb215533f07d
|
||||||
github.com/wagoodman/go-progress v0.0.0-20200621153512-2778c704bf22
|
github.com/wagoodman/go-progress v0.0.0-20200621153512-2778c704bf22
|
||||||
github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b
|
github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b
|
||||||
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525
|
github.com/wagoodman/jotframe v0.0.0-20200730190914-3517092dd163
|
||||||
go.uber.org/zap v1.15.0
|
go.uber.org/zap v1.15.0
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da // indirect
|
golang.org/x/sys v0.0.0-20200610111108-226ff32320da // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -829,6 +829,8 @@ github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b h1:elYGLFZPymeT
|
||||||
github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b/go.mod h1:MjoIZzKmbYfcpbC6ARWMcHijAjtLBViDaHcayXKWQWI=
|
github.com/wagoodman/go-rpmdb v0.0.0-20200719223757-ce54a4b0607b/go.mod h1:MjoIZzKmbYfcpbC6ARWMcHijAjtLBViDaHcayXKWQWI=
|
||||||
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525 h1:fGlwSBQrl9/axciK2+gJ9q86SeQYJpbPx4vOrExvZXY=
|
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525 h1:fGlwSBQrl9/axciK2+gJ9q86SeQYJpbPx4vOrExvZXY=
|
||||||
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525/go.mod h1:DzXZ1wfRedNhC3KQTick8Gf3CEPMFHsP5k4R/ldjKtw=
|
github.com/wagoodman/jotframe v0.0.0-20200622123948-2995cbd43525/go.mod h1:DzXZ1wfRedNhC3KQTick8Gf3CEPMFHsP5k4R/ldjKtw=
|
||||||
|
github.com/wagoodman/jotframe v0.0.0-20200730190914-3517092dd163 h1:qoZwR+bHbFFNirY4Yt7lqbOXnFAMnlFfR89w0TXwjrc=
|
||||||
|
github.com/wagoodman/jotframe v0.0.0-20200730190914-3517092dd163/go.mod h1:DzXZ1wfRedNhC3KQTick8Gf3CEPMFHsP5k4R/ldjKtw=
|
||||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||||
github.com/xanzy/go-gitlab v0.32.0 h1:tBm+OXv1t+KBsqlXkSDFz+YUjRM0GFsjpOWYOod3Ebs=
|
github.com/xanzy/go-gitlab v0.32.0 h1:tBm+OXv1t+KBsqlXkSDFz+YUjRM0GFsjpOWYOod3Ebs=
|
||||||
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package etui
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
|
@ -6,9 +6,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
stereoscopeEvent "github.com/anchore/stereoscope/pkg/event"
|
|
||||||
"github.com/anchore/syft/internal/log"
|
|
||||||
"github.com/anchore/syft/internal/ui/common"
|
"github.com/anchore/syft/internal/ui/common"
|
||||||
|
"github.com/anchore/syft/ui"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
syftEvent "github.com/anchore/syft/syft/event"
|
syftEvent "github.com/anchore/syft/syft/event"
|
||||||
"github.com/wagoodman/go-partybus"
|
"github.com/wagoodman/go-partybus"
|
||||||
"github.com/wagoodman/jotframe/pkg/frame"
|
"github.com/wagoodman/jotframe/pkg/frame"
|
||||||
|
@ -47,6 +48,7 @@ func OutputToEphemeralTUI(workerErrs <-chan error, subscription *partybus.Subscr
|
||||||
var isClosed bool
|
var isClosed bool
|
||||||
defer func() {
|
defer func() {
|
||||||
if !isClosed {
|
if !isClosed {
|
||||||
|
fr.Close()
|
||||||
frame.Close()
|
frame.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -55,6 +57,7 @@ func OutputToEphemeralTUI(workerErrs <-chan error, subscription *partybus.Subscr
|
||||||
var wg = &sync.WaitGroup{}
|
var wg = &sync.WaitGroup{}
|
||||||
events := subscription.Events()
|
events := subscription.Events()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
syftUIHandler := ui.NewHandler()
|
||||||
|
|
||||||
eventLoop:
|
eventLoop:
|
||||||
for {
|
for {
|
||||||
|
@ -67,41 +70,27 @@ eventLoop:
|
||||||
if !ok {
|
if !ok {
|
||||||
break eventLoop
|
break eventLoop
|
||||||
}
|
}
|
||||||
switch e.Type {
|
switch {
|
||||||
case syftEvent.AppUpdateAvailable:
|
case syftUIHandler.RespondsTo(e):
|
||||||
err = appUpdateAvailableHandler(ctx, fr, e, wg)
|
if err = syftUIHandler.Handle(ctx, fr, e, wg); err != nil {
|
||||||
if err != nil {
|
log.Errorf("unable to show %s event: %+v", e.Type, err)
|
||||||
log.Errorf("unable to show AppUpdateAvailable event: %+v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case stereoscopeEvent.ReadImage:
|
case e.Type == syftEvent.AppUpdateAvailable:
|
||||||
err = imageReadHandler(ctx, fr, e, wg)
|
if err = appUpdateAvailableHandler(ctx, fr, e, wg); err != nil {
|
||||||
if err != nil {
|
log.Errorf("unable to show %s event: %+v", e.Type, err)
|
||||||
log.Errorf("unable to show ReadImage event: %+v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case stereoscopeEvent.FetchImage:
|
case e.Type == syftEvent.CatalogerFinished:
|
||||||
err = imageFetchHandler(ctx, fr, e, wg)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("unable to show FetchImage event: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case syftEvent.CatalogerStarted:
|
|
||||||
err = catalogerStartedHandler(ctx, fr, e, wg)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("unable to show CatalogerStarted event: %+v", err)
|
|
||||||
}
|
|
||||||
case syftEvent.CatalogerFinished:
|
|
||||||
// we may have other background processes still displaying progress, wait for them to
|
// we may have other background processes still displaying progress, wait for them to
|
||||||
// finish before discontinuing dynamic content and showing the final report
|
// finish before discontinuing dynamic content and showing the final report
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
fr.Close()
|
||||||
frame.Close()
|
frame.Close()
|
||||||
isClosed = true
|
isClosed = true
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
err := common.CatalogerFinishedHandler(e)
|
if err := common.CatalogerFinishedHandler(e); err != nil {
|
||||||
if err != nil {
|
log.Errorf("unable to show %s event: %+v", e.Type, err)
|
||||||
log.Errorf("unable to show CatalogerFinished event: %+v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the last expected event
|
// this is the last expected event
|
||||||
|
|
31
internal/ui/etui/internal_event_handlers.go
Normal file
31
internal/ui/etui/internal_event_handlers.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package etui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal"
|
||||||
|
syftEventParsers "github.com/anchore/syft/syft/event/parsers"
|
||||||
|
"github.com/gookit/color"
|
||||||
|
"github.com/wagoodman/go-partybus"
|
||||||
|
"github.com/wagoodman/jotframe/pkg/frame"
|
||||||
|
)
|
||||||
|
|
||||||
|
func appUpdateAvailableHandler(_ context.Context, fr *frame.Frame, event partybus.Event, _ *sync.WaitGroup) error {
|
||||||
|
newVersion, err := syftEventParsers.ParseAppUpdateAvailable(event)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("bad AppUpdateAvailable event: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
line, err := fr.Prepend()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
message := color.Magenta.Sprintf("New version of %s is available: %s", internal.ApplicationName, newVersion)
|
||||||
|
_, _ = io.WriteString(line, message)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package event
|
||||||
import "github.com/wagoodman/go-partybus"
|
import "github.com/wagoodman/go-partybus"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AppUpdateAvailable partybus.EventType = "app-update-available"
|
AppUpdateAvailable partybus.EventType = "syft-app-update-available"
|
||||||
CatalogerStarted partybus.EventType = "cataloger-started-event"
|
CatalogerStarted partybus.EventType = "syft-cataloger-started-event"
|
||||||
CatalogerFinished partybus.EventType = "cataloger-finished-event"
|
CatalogerFinished partybus.EventType = "syft-cataloger-finished-event"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package etui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -8,6 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
stereoEventParsers "github.com/anchore/stereoscope/pkg/event/parsers"
|
stereoEventParsers "github.com/anchore/stereoscope/pkg/event/parsers"
|
||||||
|
"github.com/anchore/syft/internal/ui/common"
|
||||||
syftEventParsers "github.com/anchore/syft/syft/event/parsers"
|
syftEventParsers "github.com/anchore/syft/syft/event/parsers"
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
"github.com/wagoodman/go-partybus"
|
"github.com/wagoodman/go-partybus"
|
||||||
|
@ -17,26 +18,26 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxBarWidth = 50
|
const maxBarWidth = 50
|
||||||
const statusSet = SpinnerDotSet // SpinnerCircleOutlineSet
|
const statusSet = common.SpinnerDotSet // SpinnerCircleOutlineSet
|
||||||
const completedStatus = "✔" //"●"
|
const completedStatus = "✔" // "●"
|
||||||
const tileFormat = color.Bold
|
const tileFormat = color.Bold
|
||||||
const statusTitleTemplate = " %s %-28s "
|
const statusTitleTemplate = " %s %-28s "
|
||||||
|
|
||||||
var auxInfoFormat = color.HEX("#777777")
|
var auxInfoFormat = color.HEX("#777777")
|
||||||
|
|
||||||
func startProcess() (format.Simple, *Spinner) {
|
func startProcess() (format.Simple, *common.Spinner) {
|
||||||
width, _ := frame.GetTerminalSize()
|
width, _ := frame.GetTerminalSize()
|
||||||
barWidth := int(0.25 * float64(width))
|
barWidth := int(0.25 * float64(width))
|
||||||
if barWidth > maxBarWidth {
|
if barWidth > maxBarWidth {
|
||||||
barWidth = maxBarWidth
|
barWidth = maxBarWidth
|
||||||
}
|
}
|
||||||
formatter := format.NewSimpleWithTheme(barWidth, format.HeavyNoBarTheme, format.ColorCompleted, format.ColorTodo)
|
formatter := format.NewSimpleWithTheme(barWidth, format.HeavyNoBarTheme, format.ColorCompleted, format.ColorTodo)
|
||||||
spinner := NewSpinner(statusSet)
|
spinner := common.NewSpinner(statusSet)
|
||||||
|
|
||||||
return formatter, &spinner
|
return formatter, &spinner
|
||||||
}
|
}
|
||||||
|
|
||||||
func imageFetchHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
func FetchImageHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
||||||
_, prog, err := stereoEventParsers.ParseFetchImage(event)
|
_, prog, err := stereoEventParsers.ParseFetchImage(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("bad FetchImage event: %w", err)
|
return fmt.Errorf("bad FetchImage event: %w", err)
|
||||||
|
@ -73,7 +74,7 @@ func imageFetchHandler(ctx context.Context, fr *frame.Frame, event partybus.Even
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func imageReadHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
func ReadImageHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
||||||
_, prog, err := stereoEventParsers.ParseReadImage(event)
|
_, prog, err := stereoEventParsers.ParseReadImage(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("bad ReadImage event: %w", err)
|
return fmt.Errorf("bad ReadImage event: %w", err)
|
||||||
|
@ -110,7 +111,7 @@ func imageReadHandler(ctx context.Context, fr *frame.Frame, event partybus.Event
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func catalogerStartedHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
func CatalogerStartedHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
||||||
monitor, err := syftEventParsers.ParseCatalogerStarted(event)
|
monitor, err := syftEventParsers.ParseCatalogerStarted(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("bad CatalogerStarted event: %w", err)
|
return fmt.Errorf("bad CatalogerStarted event: %w", err)
|
||||||
|
@ -143,20 +144,3 @@ func catalogerStartedHandler(ctx context.Context, fr *frame.Frame, event partybu
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func appUpdateAvailableHandler(_ context.Context, fr *frame.Frame, event partybus.Event, _ *sync.WaitGroup) error {
|
|
||||||
newVersion, err := syftEventParsers.ParseAppUpdateAvailable(event)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("bad AppUpdateAvailable event: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
line, err := fr.Prepend()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
message := color.Magenta.Sprintf("New Update Available: %s", newVersion)
|
|
||||||
_, _ = io.WriteString(line, message)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
41
ui/handler.go
Normal file
41
ui/handler.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
stereoscopeEvent "github.com/anchore/stereoscope/pkg/event"
|
||||||
|
syftEvent "github.com/anchore/syft/syft/event"
|
||||||
|
"github.com/wagoodman/go-partybus"
|
||||||
|
"github.com/wagoodman/jotframe/pkg/frame"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHandler() *Handler {
|
||||||
|
return &Handler{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Handler) RespondsTo(event partybus.Event) bool {
|
||||||
|
switch event.Type {
|
||||||
|
case stereoscopeEvent.ReadImage, stereoscopeEvent.FetchImage, syftEvent.CatalogerStarted:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Handler) Handle(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error {
|
||||||
|
switch event.Type {
|
||||||
|
case stereoscopeEvent.ReadImage:
|
||||||
|
return ReadImageHandler(ctx, fr, event, wg)
|
||||||
|
|
||||||
|
case stereoscopeEvent.FetchImage:
|
||||||
|
return FetchImageHandler(ctx, fr, event, wg)
|
||||||
|
|
||||||
|
case syftEvent.CatalogerStarted:
|
||||||
|
return CatalogerStartedHandler(ctx, fr, event, wg)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in a new issue