Move state to event for whether they support inplace progress logging (#339)

## Changes
Adds a IsInplaceSupported() function to the event interface. Any event
that now uses the progress logger has to declare whether they support in
place logging

## Tests
Manually
This commit is contained in:
shreyas-goenka 2023-04-18 14:20:35 +02:00 committed by GitHub
parent 93d57dd00f
commit 85889dffb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 27 deletions

View File

@ -41,6 +41,10 @@ func (c *PlanResourceChange) String() string {
return result.String() return result.String()
} }
func (c *PlanResourceChange) IsInplaceSupported() bool {
return false
}
func logDestroyPlan(l *cmdio.Logger, changes []*tfjson.ResourceChange) error { func logDestroyPlan(l *cmdio.Logger, changes []*tfjson.ResourceChange) error {
// TODO: remove once we have mutator logging in place // TODO: remove once we have mutator logging in place
fmt.Fprintln(os.Stderr, "The following resources will be removed: ") fmt.Fprintln(os.Stderr, "The following resources will be removed: ")

View File

@ -11,7 +11,6 @@ import (
"github.com/databricks/bricks/bundle/run/output" "github.com/databricks/bricks/bundle/run/output"
"github.com/databricks/bricks/bundle/run/progress" "github.com/databricks/bricks/bundle/run/progress"
"github.com/databricks/bricks/libs/cmdio" "github.com/databricks/bricks/libs/cmdio"
"github.com/databricks/bricks/libs/flags"
"github.com/databricks/bricks/libs/log" "github.com/databricks/bricks/libs/log"
"github.com/databricks/databricks-sdk-go/service/pipelines" "github.com/databricks/databricks-sdk-go/service/pipelines"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
@ -167,10 +166,6 @@ func (r *pipelineRunner) Run(ctx context.Context, opts *Options) (output.RunOutp
if !ok { if !ok {
return nil, fmt.Errorf("no progress logger found") return nil, fmt.Errorf("no progress logger found")
} }
// Inplace logger mode is not supported for pipelines right now
if progressLogger.Mode == flags.ModeInplace {
progressLogger.Mode = flags.ModeAppend
}
// Log the pipeline update URL as soon as it is available. // Log the pipeline update URL as soon as it is available.
progressLogger.Log(progress.NewUpdateUrlEvent(w.Config.Host, updateID, pipelineID)) progressLogger.Log(progress.NewUpdateUrlEvent(w.Config.Host, updateID, pipelineID))

View File

@ -33,3 +33,7 @@ func (event *JobProgressEvent) String() string {
result.WriteString(event.RunPageURL) result.WriteString(event.RunPageURL)
return result.String() return result.String()
} }
func (event *JobProgressEvent) IsInplaceSupported() bool {
return true
}

View File

@ -25,6 +25,10 @@ func (event *ProgressEvent) String() string {
return result.String() return result.String()
} }
func (event *ProgressEvent) IsInplaceSupported() bool {
return false
}
// TODO: Add inplace logging to pipelines. https://github.com/databricks/bricks/issues/280 // TODO: Add inplace logging to pipelines. https://github.com/databricks/bricks/issues/280
type UpdateTracker struct { type UpdateTracker struct {
UpdateId string UpdateId string

View File

@ -21,3 +21,7 @@ func NewUpdateUrlEvent(host, updateId, pipelineId string) *UpdateUrlEvent {
func (event *UpdateUrlEvent) String() string { func (event *UpdateUrlEvent) String() string {
return fmt.Sprintf("The update can be found at %s\n", event.Url) return fmt.Sprintf("The update can be found at %s\n", event.Url)
} }
func (event *UpdateUrlEvent) IsInplaceSupported() bool {
return false
}

View File

@ -1,5 +1,9 @@
package cmdio package cmdio
type Event interface { type Event interface {
// convert event into human readable string
String() string String() string
// true if event supports inplace logging, return false otherwise
IsInplaceSupported() bool
} }

View File

@ -42,40 +42,57 @@ func (l *Logger) Ask(question string) (bool, error) {
} }
} }
func (l *Logger) writeJson(event Event) {
b, err := json.MarshalIndent(event, "", " ")
if err != nil {
// we panic because there we cannot catch this in jobs.RunNowAndWait
panic(err)
}
l.Writer.Write([]byte(b))
l.Writer.Write([]byte("\n"))
}
func (l *Logger) writeAppend(event Event) {
l.Writer.Write([]byte(event.String()))
l.Writer.Write([]byte("\n"))
}
func (l *Logger) writeInplace(event Event) {
if l.isFirstEvent {
// save cursor location
l.Writer.Write([]byte("\033[s"))
}
// move cursor to saved location
l.Writer.Write([]byte("\033[u"))
// clear from cursor to end of screen
l.Writer.Write([]byte("\033[0J"))
l.Writer.Write([]byte(event.String()))
l.Writer.Write([]byte("\n"))
l.isFirstEvent = false
}
func (l *Logger) Log(event Event) { func (l *Logger) Log(event Event) {
switch l.Mode { switch l.Mode {
case flags.ModeInplace: case flags.ModeInplace:
if l.isFirstEvent { if event.IsInplaceSupported() {
// save cursor location l.writeInplace(event)
l.Writer.Write([]byte("\033[s")) } else {
l.writeAppend(event)
} }
// move cursor to saved location
l.Writer.Write([]byte("\033[u"))
// clear from cursor to end of screen
l.Writer.Write([]byte("\033[0J"))
l.Writer.Write([]byte(event.String()))
l.Writer.Write([]byte("\n"))
case flags.ModeJson: case flags.ModeJson:
b, err := json.MarshalIndent(event, "", " ") l.writeJson(event)
if err != nil {
// we panic because there we cannot catch this in jobs.RunNowAndWait
panic(err)
}
l.Writer.Write([]byte(b))
l.Writer.Write([]byte("\n"))
case flags.ModeAppend: case flags.ModeAppend:
l.Writer.Write([]byte(event.String())) l.writeAppend(event)
l.Writer.Write([]byte("\n"))
default: default:
// we panic because errors are not captured in some log sides like // we panic because errors are not captured in some log sides like
// jobs.RunNowAndWait // jobs.RunNowAndWait
panic("unknown progress logger mode: " + l.Mode.String()) panic("unknown progress logger mode: " + l.Mode.String())
} }
l.isFirstEvent = false
} }