Add documentation around catalogers, UI elements, and the event bus (#143)

* add basic documentation for catalogers (with refactoring for simplification)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add docs for catalog parsers, UI, and event bus

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* update bus phrasing

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman
2020-08-12 11:04:39 -04:00
committed by GitHub
parent 5042d371cf
commit 51b9c73c31
33 changed files with 250 additions and 86 deletions
+2
View File
@@ -8,6 +8,8 @@ import (
"github.com/wagoodman/go-partybus"
)
// CatalogerFinishedHandler is a UI function for processing the CatalogerFinished bus event, displaying the catalog
// via the given presenter to stdout.
func CatalogerFinishedHandler(event partybus.Event) error {
// show the report to stdout
pres, err := syftEventParsers.ParseCatalogerFinished(event)
+24 -1
View File
@@ -1,3 +1,21 @@
/*
Package etui provides an "ephemeral" terminal user interface to display the application state dynamically.
The terminal is placed into raw mode and the cursor is manipulated to allow for a dynamic, multi-line
UI (provided by the jotframe lib), for this reason all other application mechanisms that write to the screen
must be suppressed before starting (such as logs); since bytes in the device and in application memory combine to make
a shared state, bytes coming from elsewhere to the screen will disrupt this state.
This UI is primarily driven off of events from the event bus, creating single-line terminal widgets to represent a
published element on the event bus, typically polling the element for the latest state. This allows for the UI to
control update frequency to the screen, provide "liveness" indications that are interpolated between bus events,
and overall loosely couple the bus events from screen interactions.
By convention, all elements published on the bus should be treated as read-only, and publishers on the bus should
attempt to enforce this when possible by wrapping complex objects with interfaces to prescribe interactions. Also by
convention, each new event that the UI should respond to should be added either in this package as a handler function,
or in the shared ui package as a function on the main handler object. All handler functions should be completed
processing an event before the ETUI exits (coordinated with a sync.WaitGroup)
*/
package etui
import (
@@ -18,8 +36,10 @@ import (
"github.com/wagoodman/jotframe/pkg/frame"
)
// TODO: specify per-platform implementations with build tags
// TODO: specify per-platform implementations with build tags (needed when windows is supported by syft)
// setupScreen creates a new jotframe object to manage specific screen lines dynamically, preparing the screen device
// as needed (i.e. setting the terminal to raw mode).
func setupScreen(output *os.File) *frame.Frame {
config := frame.Config{
PositionPolicy: frame.PolicyFloatForward,
@@ -36,6 +56,8 @@ func setupScreen(output *os.File) *frame.Frame {
}
// nolint:funlen,gocognit
// OutputToEphemeralTUI is a UI function that provides a terminal UI experience without a separate, in-application
// screen buffer. All logging is suppressed, buffered to a string, and output after the ETUI has been torn down.
func OutputToEphemeralTUI(workerErrs <-chan error, subscription *partybus.Subscription) error {
output := os.Stderr
@@ -84,6 +106,7 @@ eventLoop:
for {
select {
case err := <-workerErrs:
// TODO: we should show errors more explicitly in the ETUI
if err != nil {
return err
}
@@ -13,6 +13,7 @@ import (
"github.com/wagoodman/jotframe/pkg/frame"
)
// appUpdateAvailableHandler is a UI handler function to display a new application version to the top of the screen.
func appUpdateAvailableHandler(_ context.Context, fr *frame.Frame, event partybus.Event, _ *sync.WaitGroup) error {
newVersion, err := syftEventParsers.ParseAppUpdateAvailable(event)
if err != nil {
+1
View File
@@ -7,6 +7,7 @@ import (
"github.com/wagoodman/go-partybus"
)
// LoggerUI is a UI function that leverages the displays all application logs to the screen.
func LoggerUI(workerErrs <-chan error, subscription *partybus.Subscription) error {
events := subscription.Events()
eventLoop:
+2
View File
@@ -10,6 +10,8 @@ import (
// TODO: build tags to exclude options from windows
// Select is responsible for determining the specific UI function given select user option, the current platform
// config values, and environment status (such as a TTY being present).
func Select(verbose, quiet bool) UI {
var ui UI
+2
View File
@@ -4,4 +4,6 @@ import (
"github.com/wagoodman/go-partybus"
)
// UI is a function that takes a channel of errors from the main() worker and a event bus subscription and is
// responsible for displaying pertinent events to the user, on the screen or otherwise.
type UI func(<-chan error, *partybus.Subscription) error