mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Merge remote-tracking branch 'upstream/master' into master
This commit is contained in:
commit
f2fa715bb5
@ -17,12 +17,13 @@
|
|||||||
### 👍 Updated
|
### 👍 Updated
|
||||||
|
|
||||||
* Updated `github.com/gdamore/tcell` from 1.3.0 to 1.4.0
|
* Updated `github.com/gdamore/tcell` from 1.3.0 to 1.4.0
|
||||||
* Updated `github.com/shirou/gopsutil` from 2.20.7+incompatible to 2.20.8+incompatible
|
* Updated `github.com/shirou/gopsutil` from 2.20.7+incompatible to 2.20.9+incompatible
|
||||||
* Updated `github.com/mmcdole/gofeed` from 1.0.0 to 1.1.0
|
* Updated `github.com/mmcdole/gofeed` from 1.0.0 to 1.1.0
|
||||||
* Updated `github.com/digitalocean/godo` from 1.42.1 to 1.44.0
|
* Updated `github.com/digitalocean/godo` from 1.42.1 to 1.46.0
|
||||||
* Updated `github.com/xanzy/go-gitlab` from 0.33.0 to 0.38.1
|
* Updated `github.com/xanzy/go-gitlab` from 0.33.0 to 0.38.1
|
||||||
* Updated `github.com/adlio/trello` from 1.7.0 to 1.8.0
|
* Updated `github.com/adlio/trello` from 1.7.0 to 1.8.0
|
||||||
* Updated `github.com/alecthomas/chroma` from 0.8.0 to 0.8.1
|
* Updated `github.com/alecthomas/chroma` from 0.8.0 to 0.8.1
|
||||||
|
* Updated `github.com/nicklaw5/helix` from 0.5.9 to 0.7.0
|
||||||
|
|
||||||
* Now requires Go 1.15 for compilation in Dockerfiles and go.mod, by [@seanstoppable](https://github.com/Seanstoppable)
|
* Now requires Go 1.15 for compilation in Dockerfiles and go.mod, by [@seanstoppable](https://github.com/Seanstoppable)
|
||||||
|
|
||||||
|
@ -5,55 +5,75 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/logrusorgru/aurora"
|
"github.com/logrusorgru/aurora"
|
||||||
|
"github.com/wtfutil/wtf/cfg"
|
||||||
"github.com/wtfutil/wtf/wtf"
|
"github.com/wtfutil/wtf/wtf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ModuleValidator struct{}
|
type ModuleValidator struct{}
|
||||||
|
|
||||||
|
type widgetError struct {
|
||||||
|
name string
|
||||||
|
validationErrors []cfg.Validatable
|
||||||
|
}
|
||||||
|
|
||||||
func NewModuleValidator() *ModuleValidator {
|
func NewModuleValidator() *ModuleValidator {
|
||||||
val := &ModuleValidator{}
|
return &ModuleValidator{}
|
||||||
return val
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate rolls through all the enabled widgets and looks for configuration errors.
|
// Validate rolls through all the enabled widgets and looks for configuration errors.
|
||||||
// If it finds any it stringifies them, writes them to the console, and kills the app gracefully
|
// If it finds any it stringifies them, writes them to the console, and kills the app gracefully
|
||||||
func (val *ModuleValidator) Validate(widgets []wtf.Wtfable) {
|
func (val *ModuleValidator) Validate(widgets []wtf.Wtfable) {
|
||||||
var errStr string
|
validationErrors := validate(widgets)
|
||||||
hasErrors := false
|
|
||||||
|
|
||||||
for _, widget := range widgets {
|
if len(validationErrors) > 0 {
|
||||||
var widgetErrStr string
|
fmt.Println()
|
||||||
|
for _, error := range validationErrors {
|
||||||
for _, val := range widget.CommonSettings().Validations() {
|
for _, message := range error.errorMessages() {
|
||||||
if val.HasError() {
|
fmt.Println(message)
|
||||||
hasErrors = true
|
|
||||||
widgetErrStr += fmt.Sprintf(" - %s\t%s %v\n", val, aurora.Red("Error:"), val.Error())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if widgetErrStr != "" {
|
|
||||||
errStr += fmt.Sprintf(
|
|
||||||
"%s\n",
|
|
||||||
fmt.Sprintf(
|
|
||||||
"%s in %s configuration",
|
|
||||||
aurora.Red("Errors"),
|
|
||||||
aurora.Yellow(
|
|
||||||
fmt.Sprintf(
|
|
||||||
"%s.position",
|
|
||||||
widget.Name(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
errStr += widgetErrStr + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasErrors {
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(errStr)
|
|
||||||
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validate(widgets []wtf.Wtfable) (widgetErrors []widgetError) {
|
||||||
|
for _, widget := range widgets {
|
||||||
|
error := widgetError{name: widget.Name()}
|
||||||
|
|
||||||
|
for _, val := range widget.CommonSettings().Validations() {
|
||||||
|
if val.HasError() {
|
||||||
|
error.validationErrors = append(error.validationErrors, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(error.validationErrors) > 0 {
|
||||||
|
widgetErrors = append(widgetErrors, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return widgetErrors
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err widgetError) errorMessages() (messages []string) {
|
||||||
|
widgetMessage := fmt.Sprintf(
|
||||||
|
"%s in %s configuration",
|
||||||
|
aurora.Red("Errors"),
|
||||||
|
aurora.Yellow(
|
||||||
|
fmt.Sprintf(
|
||||||
|
"%s.position",
|
||||||
|
err.name,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
messages = append(messages, widgetMessage)
|
||||||
|
|
||||||
|
for _, e := range err.validationErrors {
|
||||||
|
configMessage := fmt.Sprintf(" - %s\t%s %v", e.String(), aurora.Red("Error:"), e.Error())
|
||||||
|
|
||||||
|
messages = append(messages, configMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages
|
||||||
|
}
|
||||||
|
102
app/module_validator_test.go
Normal file
102
app/module_validator_test.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/logrusorgru/aurora"
|
||||||
|
"github.com/olebedev/config"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/wtfutil/wtf/wtf"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
valid = `
|
||||||
|
wtf:
|
||||||
|
mods:
|
||||||
|
clocks:
|
||||||
|
enabled: true
|
||||||
|
position:
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
height: 1
|
||||||
|
width: 1
|
||||||
|
refreshInterval: 30`
|
||||||
|
|
||||||
|
invalid = `
|
||||||
|
wtf:
|
||||||
|
mods:
|
||||||
|
clocks:
|
||||||
|
enabled: true
|
||||||
|
position:
|
||||||
|
top: abc
|
||||||
|
left: 0
|
||||||
|
height: 1
|
||||||
|
width: 1
|
||||||
|
refreshInterval: 30`
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_NewModuleValidator(t *testing.T) {
|
||||||
|
assert.IsType(t, &ModuleValidator{}, NewModuleValidator())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_validate(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
moduleName string
|
||||||
|
config *config.Config
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid config",
|
||||||
|
moduleName: "clocks",
|
||||||
|
config: func() *config.Config {
|
||||||
|
cfg, _ := config.ParseYaml(valid)
|
||||||
|
return cfg
|
||||||
|
}(),
|
||||||
|
expected: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid config",
|
||||||
|
moduleName: "clocks",
|
||||||
|
config: func() *config.Config {
|
||||||
|
cfg, _ := config.ParseYaml(invalid)
|
||||||
|
return cfg
|
||||||
|
}(),
|
||||||
|
expected: []string{
|
||||||
|
fmt.Sprintf("%s in %s configuration", aurora.Red("Errors"), aurora.Yellow("clocks.position")),
|
||||||
|
fmt.Sprintf(
|
||||||
|
" - Invalid value for %s: 0 %s strconv.ParseInt: parsing \"abc\": invalid syntax",
|
||||||
|
aurora.Yellow("top"),
|
||||||
|
aurora.Red("Error:"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
widget := MakeWidget(nil, nil, tt.moduleName, tt.config)
|
||||||
|
|
||||||
|
if widget == nil {
|
||||||
|
t.Logf("Failed to create widget %s", tt.moduleName)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
errs := validate([]wtf.Wtfable{widget})
|
||||||
|
|
||||||
|
if len(tt.expected) == 0 {
|
||||||
|
assert.Empty(t, errs)
|
||||||
|
} else {
|
||||||
|
assert.NotEmpty(t, errs)
|
||||||
|
|
||||||
|
var actual []string
|
||||||
|
for _, err := range errs {
|
||||||
|
actual = append(actual, err.errorMessages()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, tt.expected, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ const (
|
|||||||
|
|
||||||
// CreateFile creates the named file in the config directory, if it does not already exist.
|
// CreateFile creates the named file in the config directory, if it does not already exist.
|
||||||
// If the file exists it does not recreate it.
|
// If the file exists it does not recreate it.
|
||||||
// If successful, eturns the absolute path to the file
|
// If successful, returns the absolute path to the file
|
||||||
// If unsuccessful, returns an error
|
// If unsuccessful, returns an error
|
||||||
func CreateFile(fileName string) (string, error) {
|
func CreateFile(fileName string) (string, error) {
|
||||||
configDir, err := WtfConfigDir()
|
configDir, err := WtfConfigDir()
|
||||||
|
7
go.mod
7
go.mod
@ -15,7 +15,8 @@ require (
|
|||||||
github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d
|
github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
|
||||||
github.com/digitalocean/godo v1.44.0
|
github.com/creack/pty v1.1.11
|
||||||
|
github.com/digitalocean/godo v1.46.0
|
||||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||||
github.com/docker/docker v1.13.1
|
github.com/docker/docker v1.13.1
|
||||||
github.com/docker/docker-credential-helpers v0.6.3
|
github.com/docker/docker-credential-helpers v0.6.3
|
||||||
@ -40,7 +41,7 @@ require (
|
|||||||
github.com/logrusorgru/aurora v0.0.0-20190803045625-94edacc10f9b
|
github.com/logrusorgru/aurora v0.0.0-20190803045625-94edacc10f9b
|
||||||
github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20191014190507-26902c1d4325
|
github.com/microsoft/azure-devops-go-api/azuredevops v0.0.0-20191014190507-26902c1d4325
|
||||||
github.com/mmcdole/gofeed v1.1.0
|
github.com/mmcdole/gofeed v1.1.0
|
||||||
github.com/nicklaw5/helix v0.5.9
|
github.com/nicklaw5/helix v0.7.0
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/olebedev/config v0.0.0-20190528211619-364964f3a8e4
|
github.com/olebedev/config v0.0.0-20190528211619-364964f3a8e4
|
||||||
github.com/olekukonko/tablewriter v0.0.4
|
github.com/olekukonko/tablewriter v0.0.4
|
||||||
@ -52,7 +53,7 @@ require (
|
|||||||
github.com/pkg/profile v1.5.0
|
github.com/pkg/profile v1.5.0
|
||||||
github.com/radovskyb/watcher v1.0.7
|
github.com/radovskyb/watcher v1.0.7
|
||||||
github.com/rivo/tview v0.0.0-20200108161608-1316ea7a4b35
|
github.com/rivo/tview v0.0.0-20200108161608-1316ea7a4b35
|
||||||
github.com/shirou/gopsutil v2.20.8+incompatible
|
github.com/shirou/gopsutil v2.20.9+incompatible
|
||||||
github.com/spf13/cobra v0.0.5 // indirect
|
github.com/spf13/cobra v0.0.5 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/spf13/viper v1.6.1 // indirect
|
github.com/spf13/viper v1.6.1 // indirect
|
||||||
|
14
go.sum
14
go.sum
@ -162,6 +162,8 @@ github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
|
|||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||||
|
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/dancannon/gorethink v4.0.0+incompatible h1:KFV7Gha3AuqT+gr0B/eKvGhbjmUv0qGF43aKCIKVE9A=
|
github.com/dancannon/gorethink v4.0.0+incompatible h1:KFV7Gha3AuqT+gr0B/eKvGhbjmUv0qGF43aKCIKVE9A=
|
||||||
github.com/dancannon/gorethink v4.0.0+incompatible/go.mod h1:BLvkat9KmZc1efyYwhz3WnybhRZtgF1K929FD8z1avU=
|
github.com/dancannon/gorethink v4.0.0+incompatible/go.mod h1:BLvkat9KmZc1efyYwhz3WnybhRZtgF1K929FD8z1avU=
|
||||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||||
@ -172,8 +174,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/digitalocean/godo v1.44.0 h1:IMElzMUpO1dVR8qjSg53+5vDkOLzMbhJt4yTAq7NGCQ=
|
github.com/digitalocean/godo v1.46.0 h1:WRbwjATilgz2NE4NGMeSDpeicy9h4xSKNGuRJ/Nq/fA=
|
||||||
github.com/digitalocean/godo v1.44.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
|
github.com/digitalocean/godo v1.46.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
|
||||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 h1:Dzuw9GtbmllUqEcoHfScT9YpKFUssSiZ5PgZkIGf/YQ=
|
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 h1:Dzuw9GtbmllUqEcoHfScT9YpKFUssSiZ5PgZkIGf/YQ=
|
||||||
@ -551,8 +553,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1
|
|||||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||||
github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a h1:SAjW6pL/9NssyKM1Qvyy5/V4kR3z76qlTbaqJLixhP4=
|
github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a h1:SAjW6pL/9NssyKM1Qvyy5/V4kR3z76qlTbaqJLixhP4=
|
||||||
github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
github.com/ncw/swift v0.0.0-20171019114456-c95c6e5c2d1a/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||||
github.com/nicklaw5/helix v0.5.9 h1:THNJ3o+OM+Dh1gPD9qh2jQlVRTPhjB0rYVBus+9GoB4=
|
github.com/nicklaw5/helix v0.7.0 h1:+E8YUqNewLFX0jSxlzKvDpyOs/v299ZZtp1aEqlonWk=
|
||||||
github.com/nicklaw5/helix v0.5.9/go.mod h1:nRcok4VLg8ONQYW/iXBZ24wcfiJjTlDbhgk0ZatOrUY=
|
github.com/nicklaw5/helix v0.7.0/go.mod h1:nRcok4VLg8ONQYW/iXBZ24wcfiJjTlDbhgk0ZatOrUY=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||||
@ -672,8 +674,8 @@ github.com/sethgrid/pester v0.0.0-20171127025028-760f8913c048/go.mod h1:Ad7IjTpv
|
|||||||
github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 h1:qu90yDtRE5WEfRT5mn9v0Xz9RaopLguhbPwZKx4dHq8=
|
github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197 h1:qu90yDtRE5WEfRT5mn9v0Xz9RaopLguhbPwZKx4dHq8=
|
||||||
github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197/go.mod h1:0hhKrsUsoT7yvxwNGKa+TSYNA26DNWMqReeZEQq/9FI=
|
github.com/sguiheux/go-coverage v0.0.0-20190710153556-287b082a7197/go.mod h1:0hhKrsUsoT7yvxwNGKa+TSYNA26DNWMqReeZEQq/9FI=
|
||||||
github.com/shirou/gopsutil v0.0.0-20170406131756-e49a95f3d5f8/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
github.com/shirou/gopsutil v0.0.0-20170406131756-e49a95f3d5f8/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
|
github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ=
|
||||||
github.com/shirou/gopsutil v2.20.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
@ -18,6 +18,7 @@ type Settings struct {
|
|||||||
args []string `help:"The arguments to the command, with each item as an element in an array. Example: for curl -I cisco.com, the arguments array would be ['-I', 'cisco.com']."`
|
args []string `help:"The arguments to the command, with each item as an element in an array. Example: for curl -I cisco.com, the arguments array would be ['-I', 'cisco.com']."`
|
||||||
cmd string `help:"The terminal command to be run, withouth the arguments. Ie: ping, whoami, curl."`
|
cmd string `help:"The terminal command to be run, withouth the arguments. Ie: ping, whoami, curl."`
|
||||||
tail bool `help:"Automatically scroll to the end of the command output."`
|
tail bool `help:"Automatically scroll to the end of the command output."`
|
||||||
|
pty bool `help:"Run the command in a pseudo-terminal. Some apps will behave differently if they feel in a terminal. For example, some apps will produce colorized output in a terminal, and non-colorized output otherwise. Default false" optional:"true"`
|
||||||
maxLines int `help:"Maximum number of lines kept in the buffer."`
|
maxLines int `help:"Maximum number of lines kept in the buffer."`
|
||||||
|
|
||||||
// The dimensions of the module
|
// The dimensions of the module
|
||||||
@ -32,6 +33,7 @@ func NewSettingsFromYAML(name string, moduleConfig *config.Config, globalConfig
|
|||||||
|
|
||||||
args: utils.ToStrs(moduleConfig.UList("args")),
|
args: utils.ToStrs(moduleConfig.UList("args")),
|
||||||
cmd: moduleConfig.UString("cmd"),
|
cmd: moduleConfig.UString("cmd"),
|
||||||
|
pty: moduleConfig.UBool("pty", false),
|
||||||
tail: moduleConfig.UBool("tail", false),
|
tail: moduleConfig.UBool("tail", false),
|
||||||
maxLines: moduleConfig.UInt("maxLines", 256),
|
maxLines: moduleConfig.UInt("maxLines", 256),
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,13 @@ package cmdrunner
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/creack/pty"
|
||||||
"github.com/rivo/tview"
|
"github.com/rivo/tview"
|
||||||
"github.com/wtfutil/wtf/view"
|
"github.com/wtfutil/wtf/view"
|
||||||
)
|
)
|
||||||
@ -121,23 +123,45 @@ func runCommandLoop(widget *Widget) {
|
|||||||
<-widget.runChan
|
<-widget.runChan
|
||||||
widget.resetBuffer()
|
widget.resetBuffer()
|
||||||
cmd := exec.Command(widget.settings.cmd, widget.settings.args...)
|
cmd := exec.Command(widget.settings.cmd, widget.settings.args...)
|
||||||
cmd.Stdout = widget
|
|
||||||
cmd.Env = widget.environment()
|
cmd.Env = widget.environment()
|
||||||
err := cmd.Run()
|
var err error
|
||||||
|
if widget.settings.pty {
|
||||||
// The command has exited, print any error messages
|
err = runCommandPty(widget, cmd)
|
||||||
|
} else {
|
||||||
|
err = runCommand(widget, cmd)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
widget.m.Lock()
|
widget.handleError(err)
|
||||||
_, writeErr := widget.buffer.WriteString(err.Error())
|
|
||||||
if writeErr != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
widget.m.Unlock()
|
|
||||||
}
|
}
|
||||||
widget.redrawChan <- true
|
widget.redrawChan <- true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runCommand(widget *Widget, cmd *exec.Cmd) error {
|
||||||
|
cmd.Stdout = widget
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCommandPty(widget *Widget, cmd *exec.Cmd) error {
|
||||||
|
f, err := pty.Start(cmd)
|
||||||
|
// The command has exited, print any error messages
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(widget.buffer, f)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (widget *Widget) handleError(err error) {
|
||||||
|
widget.m.Lock()
|
||||||
|
defer widget.m.Unlock()
|
||||||
|
_, writeErr := widget.buffer.WriteString(err.Error())
|
||||||
|
if writeErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func redrawLoop(widget *Widget) {
|
func redrawLoop(widget *Widget) {
|
||||||
for {
|
for {
|
||||||
widget.Redraw(widget.content)
|
widget.Redraw(widget.content)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user