From 6de4f633e7d4ff7edcd6b84230f8281a8329b10c Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 4 Jan 2019 22:01:45 +0100 Subject: [PATCH] Extract the api so that plugins and app can have independent lifecycles. API is found at https://github.com/metacosm/odo-event-api. This, however, doesn't work well with vendoring so right now, both the app and plugin can only be built against an api that's in the same spot in $GOPATH. See https://github.com/golang/go/issues/20481 for more details. --- cmd/odo/odo.go | 3 ++- pkg/odo/events/abort.go | 32 -------------------------- pkg/odo/events/bus.go | 33 ++++++++++++++------------- pkg/odo/events/event.go | 33 --------------------------- pkg/odo/events/listener.go | 7 ------ pkg/odo/genericclioptions/runnable.go | 11 +++++---- 6 files changed, 25 insertions(+), 94 deletions(-) delete mode 100644 pkg/odo/events/abort.go delete mode 100644 pkg/odo/events/event.go delete mode 100644 pkg/odo/events/listener.go diff --git a/cmd/odo/odo.go b/cmd/odo/odo.go index f9e86464e91..5e763feaef3 100644 --- a/cmd/odo/odo.go +++ b/cmd/odo/odo.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "github.com/golang/glog" + api "github.com/metacosm/odo-event-api/odo/api/events" "github.com/posener/complete" "github.com/redhat-developer/odo/pkg/config" "github.com/redhat-developer/odo/pkg/log" @@ -145,7 +146,7 @@ func loadPlugins() { } // Assert that Listener is indeed a Listener :) - listener, ok := candidate.(events.Listener) + listener, ok := candidate.(api.Listener) if !ok { log.Error("exported Listener variable is not implementing the Listener interface") os.Exit(1) diff --git a/pkg/odo/events/abort.go b/pkg/odo/events/abort.go deleted file mode 100644 index 9fd2ab9c709..00000000000 --- a/pkg/odo/events/abort.go +++ /dev/null @@ -1,32 +0,0 @@ -package events - -import ( - "fmt" - "reflect" -) - -type EventCausedAbortError struct { - Listener Listener - Source Event - cause error -} - -func (e *EventCausedAbortError) Error() string { - return fmt.Sprintf("listener %s aborted processing on event %v, cause: %v", e.Listener.Name(), e.Source, e.cause) -} - -func (e *EventCausedAbortError) Cause() error { - return e.cause -} - -func NewEventCausedAbortError(listener Listener, event Event, cause error) *EventCausedAbortError { - return &EventCausedAbortError{ - Listener: listener, - Source: event, - cause: cause, - } -} - -func IsEventCausedAbort(err error) bool { - return reflect.TypeOf(err) == reflect.TypeOf(EventCausedAbortError{}) -} diff --git a/pkg/odo/events/bus.go b/pkg/odo/events/bus.go index f5c8e04ffda..32c7c8223fb 100644 --- a/pkg/odo/events/bus.go +++ b/pkg/odo/events/bus.go @@ -2,18 +2,19 @@ package events import ( "fmt" + api "github.com/metacosm/odo-event-api/odo/api/events" "github.com/spf13/cobra" ) -type typesToListeners map[EventType][]Listener +type typesToListeners map[api.EventType][]api.Listener type EventBus struct { listeners map[string]typesToListeners - allListeners []Listener + allListeners []api.Listener } var bus = &EventBus{ - allListeners: make([]Listener, 0, 5), + allListeners: make([]api.Listener, 0, 5), } func GetEventBus() *EventBus { @@ -27,9 +28,9 @@ func EventNameFrom(cmd *cobra.Command) string { return cmd.Name() } -func DispatchEvent(cmd *cobra.Command, eventType EventType, payload interface{}) error { +func DispatchEvent(cmd *cobra.Command, eventType api.EventType, payload interface{}) error { eventBus := GetEventBus() - err := eventBus.DispatchEvent(Event{ + err := eventBus.DispatchEvent(api.Event{ Name: EventNameFrom(cmd), Type: eventType, Payload: payload, @@ -38,13 +39,13 @@ func DispatchEvent(cmd *cobra.Command, eventType EventType, payload interface{}) return err } -func (bus *EventBus) RegisterToAll(listener Listener) { +func (bus *EventBus) RegisterToAll(listener api.Listener) { bus.allListeners = append(bus.allListeners, listener) } type Subscription struct { - Listener Listener - SupportedEvents map[string]EventType + Listener api.Listener + SupportedEvents map[string]api.EventType } func (bus *EventBus) Register(subscription Subscription) { @@ -53,7 +54,7 @@ func (bus *EventBus) Register(subscription Subscription) { } } -func (bus *EventBus) RegisterSingle(event string, eventType EventType, listener Listener) { +func (bus *EventBus) RegisterSingle(event string, eventType api.EventType, listener api.Listener) { listenersForEvent, ok := bus.listeners[event] if !ok { listenersForEvent = make(typesToListeners, 10) @@ -62,16 +63,16 @@ func (bus *EventBus) RegisterSingle(event string, eventType EventType, listener listenersForType, ok := listenersForEvent[eventType] if !ok { - listenersForType = make([]Listener, 0, 10) + listenersForType = make([]api.Listener, 0, 10) } listenersForEvent[eventType] = append(listenersForType, listener) } -func (bus *EventBus) DispatchEvent(event Event) (err error) { +func (bus *EventBus) DispatchEvent(event api.Event) (err error) { errors := make([]error, 0, 10) listenersForEvent, ok := bus.listeners[event.Name] - processedListeners := make([]Listener, 0, 10) + processedListeners := make([]api.Listener, 0, 10) var abort bool if ok { listenersForType, ok := listenersForEvent[event.Type] @@ -80,7 +81,7 @@ func (bus *EventBus) DispatchEvent(event Event) (err error) { listener := listenersForType[i] err := listener.OnEvent(event) if err != nil { - if IsEventCausedAbort(err) { + if api.IsEventCausedAbort(err) { abort = true return err } @@ -96,7 +97,7 @@ func (bus *EventBus) DispatchEvent(event Event) (err error) { listener := bus.allListeners[i] err := listener.OnEvent(event) if err != nil { - if IsEventCausedAbort(err) { + if api.IsEventCausedAbort(err) { abort = true return err } @@ -118,11 +119,11 @@ func (bus *EventBus) DispatchEvent(event Event) (err error) { return } -func revertProcessedListenersOnAbort(abort bool, err error, listeners []Listener) { +func revertProcessedListenersOnAbort(abort bool, err error, listeners []api.Listener) { if abort { for i := range listeners { - listeners[i].OnAbort(err.(*EventCausedAbortError)) + listeners[i].OnAbort(err.(*api.EventCausedAbortError)) } } } diff --git a/pkg/odo/events/event.go b/pkg/odo/events/event.go deleted file mode 100644 index effd96c931d..00000000000 --- a/pkg/odo/events/event.go +++ /dev/null @@ -1,33 +0,0 @@ -package events - -type EventType int - -func (t EventType) String() string { - return eventTypes[t] -} - -var eventTypes = []string{ - "Unknown", - "PreRun", - "PostComplete", - "PostValidate", - "PostRun", -} - -const ( - Unknown EventType = iota - PreRun - PostComplete - PostValidate - PostRun -) - -type Event struct { - Name string - Type EventType - Payload interface{} -} - -func (e Event) String() string { - return e.Name + "->" + e.Type.String() -} diff --git a/pkg/odo/events/listener.go b/pkg/odo/events/listener.go deleted file mode 100644 index c5e913177b3..00000000000 --- a/pkg/odo/events/listener.go +++ /dev/null @@ -1,7 +0,0 @@ -package events - -type Listener interface { - OnEvent(event Event) error - OnAbort(abortError *EventCausedAbortError) - Name() string -} diff --git a/pkg/odo/genericclioptions/runnable.go b/pkg/odo/genericclioptions/runnable.go index 808e9cf377a..fddbb835754 100644 --- a/pkg/odo/genericclioptions/runnable.go +++ b/pkg/odo/genericclioptions/runnable.go @@ -1,6 +1,7 @@ package genericclioptions import ( + api "github.com/metacosm/odo-event-api/odo/api/events" "github.com/redhat-developer/odo/pkg/log" "github.com/redhat-developer/odo/pkg/odo/events" "github.com/redhat-developer/odo/pkg/odo/util" @@ -15,17 +16,17 @@ type Runnable interface { } func GenericRun(o Runnable, cmd *cobra.Command, args []string) { - exitIfAbort(events.DispatchEvent(cmd, events.PreRun, args), cmd) + exitIfAbort(events.DispatchEvent(cmd, api.PreRun, args), cmd) util.CheckError(o.Complete(cmd.Name(), cmd, args), "") - exitIfAbort(events.DispatchEvent(cmd, events.PostComplete, o), cmd) + exitIfAbort(events.DispatchEvent(cmd, api.PostComplete, o), cmd) util.CheckError(o.Validate(), "") - exitIfAbort(events.DispatchEvent(cmd, events.PostValidate, o), cmd) + exitIfAbort(events.DispatchEvent(cmd, api.PostValidate, o), cmd) util.CheckError(o.Run(), "") - exitIfAbort(events.DispatchEvent(cmd, events.PostRun, o), cmd) + exitIfAbort(events.DispatchEvent(cmd, api.PostRun, o), cmd) } func exitIfAbort(err error, cmd *cobra.Command) { - if events.IsEventCausedAbort(err) { + if api.IsEventCausedAbort(err) { log.Errorf("Processing of %s command was aborted: %v", cmd.Name(), err) os.Exit(1) }