mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 15:06:36 +01:00
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:
@@ -1,3 +1,16 @@
|
||||
/*
|
||||
Package bus provides access to a singleton instance of an event bus (provided by the calling application). The event bus
|
||||
is intended to allow for the syft library to publish events which library consumers can subscribe to. These events
|
||||
can provide static information, but also have an object as a payload for which the consumer can poll for updates.
|
||||
This is akin to a logger, except instead of only allowing strings to be logged, rich objects that can be interacted with.
|
||||
|
||||
Note that the singleton instance is only allowed to publish events and not subscribe to them --this is intentional.
|
||||
Internal library interactions should continue to use traditional in-execution-path approaches for data sharing
|
||||
(e.g. function returns and channels) and not depend on bus subscriptions for critical interactions (e.g. one part of the
|
||||
lib publishes an event and another part of the lib subscribes and reacts to that event). The bus is provided only as a
|
||||
means for consumers to observe events emitted from the library (such as to provide a rich UI) and not to allow
|
||||
consumers to augment or otherwise change execution.
|
||||
*/
|
||||
package bus
|
||||
|
||||
import "github.com/wagoodman/go-partybus"
|
||||
@@ -5,6 +18,8 @@ import "github.com/wagoodman/go-partybus"
|
||||
var publisher partybus.Publisher
|
||||
var active bool
|
||||
|
||||
// SetPublisher sets the singleton event bus publisher. This is optional; if no bus is provided, the library will
|
||||
// behave no differently than if a bus had been provided.
|
||||
func SetPublisher(p partybus.Publisher) {
|
||||
publisher = p
|
||||
if p != nil {
|
||||
@@ -12,6 +27,7 @@ func SetPublisher(p partybus.Publisher) {
|
||||
}
|
||||
}
|
||||
|
||||
// Publish an event onto the bus. If there is no bus set by the calling application, this does nothing.
|
||||
func Publish(event partybus.Event) {
|
||||
if active {
|
||||
publisher.Publish(event)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,22 +7,25 @@ import (
|
||||
|
||||
const valueNotProvided = "[not provided]"
|
||||
|
||||
// all variables here are provided as build-time arguments, with clear default values
|
||||
var version = valueNotProvided
|
||||
var gitCommit = valueNotProvided
|
||||
var gitTreeState = valueNotProvided
|
||||
var buildDate = valueNotProvided
|
||||
var platform = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
|
||||
// Version defines the application version details (generally from build information)
|
||||
type Version struct {
|
||||
Version string
|
||||
GitCommit string
|
||||
GitTreeState string
|
||||
BuildDate string
|
||||
GoVersion string
|
||||
Compiler string
|
||||
Platform string
|
||||
Version string // application semantic version
|
||||
GitCommit string // git SHA at build-time
|
||||
GitTreeState string // indication of git tree (either "clean" or "dirty") at build-time
|
||||
BuildDate string // date of the build
|
||||
GoVersion string // go runtime version at build-time
|
||||
Compiler string // compiler used at build-time
|
||||
Platform string // GOOS and GOARCH at build-time
|
||||
}
|
||||
|
||||
// FromBuild provides all version details
|
||||
func FromBuild() Version {
|
||||
return Version{
|
||||
Version: version,
|
||||
|
||||
Reference in New Issue
Block a user