From 4b62ae8b27524dcbb1f9a5dcca16b1b7161c3b4b Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Mon, 2 Oct 2023 23:49:49 +0300 Subject: [PATCH] Add -X/--extra option to print the last lines of command output if action failed --- action/auxi.go | 32 ++++++++++++++++++++++++++++++-- cli/cli.go | 6 ++++++ cli/executor/executor.go | 11 +++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/action/auxi.go b/action/auxi.go index 3b083c9c..6000d3e0 100644 --- a/action/auxi.go +++ b/action/auxi.go @@ -82,6 +82,32 @@ func (c *OutputContainer) String() string { return c.buf.String() } +// Tail return the last lines of output +func (c *OutputContainer) Tail(lines int) string { + if c.IsEmpty() { + return "" + } + + if c.buf.Len() < lines+2 { + return c.String() + } + + data := c.buf.Bytes() + line := 0 + + for i := len(data) - 2; i >= 0; i-- { + if data[i] == '\n' { + line++ + } + + if line == lines { + return strings.TrimRight(string(data[i+1:]), " \n\r") + } + } + + return strings.TrimRight(string(data), " \n\r") +} + // IsEmpty returns true if container is empty func (c *OutputContainer) IsEmpty() bool { return c == nil || c.buf == nil || c.buf.Len() == 0 @@ -89,9 +115,11 @@ func (c *OutputContainer) IsEmpty() bool { // Purge clears data func (c *OutputContainer) Purge() { - if c == nil || c.buf != nil { - c.buf.Reset() + if c == nil || c.buf == nil { + return } + + c.buf.Reset() } // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/cli/cli.go b/cli/cli.go index d18afd4e..a60a72f3 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -15,6 +15,7 @@ import ( "github.com/essentialkaos/ek/v12/fmtc" "github.com/essentialkaos/ek/v12/fmtutil" + "github.com/essentialkaos/ek/v12/fmtutil/panel" "github.com/essentialkaos/ek/v12/fmtutil/table" "github.com/essentialkaos/ek/v12/fsutil" "github.com/essentialkaos/ek/v12/options" @@ -52,6 +53,7 @@ const ( OPT_LIST_PACKAGES_FLAT = "L1:list-packages-flat" OPT_VARIABLES = "V:variables" OPT_BARCODE = "B:barcode" + OPT_EXTRA = "X:extra" OPT_TIME = "T:time" OPT_FORMAT = "f:format" OPT_DIR = "d:dir" @@ -78,6 +80,7 @@ var optMap = options.Map{ OPT_LIST_PACKAGES_FLAT: {Type: options.BOOL}, OPT_VARIABLES: {Type: options.BOOL}, OPT_BARCODE: {Type: options.BOOL}, + OPT_EXTRA: {Type: options.BOOL}, OPT_TIME: {Type: options.BOOL}, OPT_FORMAT: {}, OPT_DIR: {}, @@ -189,6 +192,7 @@ func configureUI() { } fmtutil.SeparatorSymbol = "–" + panel.Indent = 5 } // configureSubsystems configures bibop subsystems @@ -277,6 +281,7 @@ func process(file string) { } cfg := &executor.Config{ + Debug: options.GetB(OPT_EXTRA), Quiet: options.GetB(OPT_QUIET), DisableCleanup: options.GetB(OPT_NO_CLEANUP), ErrsDir: errDir, @@ -456,6 +461,7 @@ func genUsage() *usage.Info { info.AppNameColorTag = "{*}" + colorTagApp info.AddOption(OPT_DRY_RUN, "Parse and validate recipe") + info.AddOption(OPT_EXTRA, "Print the last lines from command output if action was failed") info.AddOption(OPT_LIST_PACKAGES, "List required packages") info.AddOption(OPT_LIST_PACKAGES_FLAT, "List required packages in one line {s-}(useful for scripts){!}") info.AddOption(OPT_VARIABLES, "List recipe variables") diff --git a/cli/executor/executor.go b/cli/executor/executor.go index c32f53c3..69d341a7 100644 --- a/cli/executor/executor.go +++ b/cli/executor/executor.go @@ -17,6 +17,8 @@ import ( "time" "github.com/essentialkaos/ek/v12/errutil" + "github.com/essentialkaos/ek/v12/fmtc" + "github.com/essentialkaos/ek/v12/fmtutil/panel" "github.com/essentialkaos/ek/v12/fsutil" "github.com/essentialkaos/ek/v12/log" "github.com/essentialkaos/ek/v12/req" @@ -54,6 +56,7 @@ type Executor struct { type Config struct { ErrsDir string Quiet bool + Debug bool DisableCleanup bool } @@ -287,6 +290,14 @@ func runCommand(e *Executor, rr render.Renderer, c *recipe.Command) bool { } if err != nil { + if !e.config.Quiet && e.config.Debug && !cmdEnv.output.IsEmpty() { + fmtc.NewLine() + panel.Panel( + "☴ OUTPUT", "{y}", "The last 10 lines from command output", + cmdEnv.output.Tail(10), panel.BOTTOM_LINE, + ) + } + logError(e, c, action, cmdEnv, err) return false }