Skip to content

Commit

Permalink
feat: logger print command fit in term width (#11)
Browse files Browse the repository at this point in the history
The default logger will check the terminal width and if the command to
be printed is wider than the terminal width, it will be broken up into
multiple lines, similar to a shell command represented on multiple
lines.
  • Loading branch information
scottames authored Apr 23, 2023
1 parent af01dbf commit d242eee
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Additionally many of the tests can provide some example usage.

### Logging

Cmder logs all commands being run using the specified, using the `Logger` method, logger which implements the [`Logger`](https://github.com/scottames/cmder/blob/master/pkg/log/logger.go#L10-L27) interface.
Cmder logs all commands being run, using the `Logger` method, which implements the [`Logger`](https://github.com/scottames/cmder/blob/master/pkg/log/logger.go#L10-L27) interface:

```golang
type Logger interface {
Expand All @@ -43,12 +43,14 @@ type Logger interface {
}
```

By default (if none specified with the `Logger` method) the built-in logger will be used. See Additional `log.Logger*` variables for configuration
By default (if none specified with the `Cmder.Logger()` method) the built-in [logger](pkg/log/logger.go) will be used. See Additional `log.Logger*` variables for configuration
options.

Color is disabled by default, but can be enabled by setting either `MAGEFILE_ENABLE_COLOR` or
`CMDER_ENABLE_COLOR` environment variables to true.

The default logger will check the terminal width and if the command to be printed is wider than the terminal width, it will be broken up into multiple lines, similar to a shell command represented on multiple lines.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Contributors should follow the [Go Community Code of Conduct
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ require (
github.com/go-test/deep v1.1.0
github.com/magefile/mage v1.14.0
github.com/stretchr/testify v1.8.2
golang.org/x/term v0.7.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.7.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
58 changes: 57 additions & 1 deletion pkg/log/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"fmt"
"os"
"strconv"
"strings"
"time"

"golang.org/x/term"
)

// Logger is a generic logging interface
Expand Down Expand Up @@ -176,12 +179,65 @@ func (l logger) Logf(format string, v ...interface{}) {
fmt.Printf(s+format+timestamp+"\n", v...)
}

// splitArgsToNewLine returns a new string formatted as a shell command as if being executed
// on multiple lines - padding between the [] of the command (slice) to be printed
func splitArgsToNewLine(s string) string {
var result string

const (
bBracket = "["
eBracket = "]"
)

newArgs := []string{}
args := strings.Split(s, " ")

for _, w := range args {
if strings.HasPrefix(w, bBracket) {
w = strings.Replace(w, bBracket, bBracket+"\n\n ", 1)
}

if strings.HasSuffix(w, eBracket) {
i := strings.LastIndex(w, eBracket)
w = w[:i] + strings.Replace(w[i:], eBracket, "\n\n"+eBracket, 1)
}

if strings.Contains(w, eBracket+string(LoggerColor)) {
w = strings.Replace(w, eBracket+string(LoggerColor), "\n\n"+eBracket+string(LoggerColor), 1)
}

if strings.HasPrefix(w, "-") {
newArgs = append(newArgs, "\\\n "+w)
} else {
newArgs = append(newArgs, w)
}
}

result = strings.Join(newArgs, " ")

return result
}

// stringLen returns the length of a given string
func stringLen(s string) int {
return len([]rune(s))
}

// Log implements the Logger interface
func (l logger) Log(v ...interface{}) {
s := l.prependStr()
timestamp := l.timestamp(string(LoggerDarkGrey))
msg := fmt.Sprintf("%v", v...)

termWidth, _, err := term.GetSize(int(os.Stdin.Fd()))
if err == nil {
absLen := stringLen(msg) + stringLen(s) + stringLen(timestamp)
if absLen > termWidth {
msg = splitArgsToNewLine(msg)
}
}

fmt.Printf(s+"%v"+timestamp+"\n", v...)
fmt.Printf(s+"%s"+timestamp+"\n", msg)
}

func (l logger) prependStr() string {
Expand Down

0 comments on commit d242eee

Please sign in to comment.