Skip to content

Commit

Permalink
fix ANSI in cmd; respect NO_COLOR; print version on run
Browse files Browse the repository at this point in the history
  • Loading branch information
danbrakeley committed Jun 20, 2024
1 parent 309bb8e commit 46aa0f2
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 99 deletions.
30 changes: 19 additions & 11 deletions cmd/upmyip/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
"os"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
Expand All @@ -11,25 +12,32 @@ import (
)

func main() {
_, noColor := os.LookupEnv("NO_COLOR")
prn := Printer{
NoColor: noColor,
}

prn.Header("UpMyIP v0.1.2")

cfg, err := LoadConfig("upmyip.toml")
if err != nil {
fmt.Println(err)
prn.Error("upmyip.toml", err)
return
}

ctx := context.Background()

s := NewSpinner()
fmt.Print("Finding public IP address... ")
s := NewSpinner(noColor)
prn.Print("Finding public IP address... ")
s.Start()
info, err := RequestPublicInfo(ctx)
if err != nil {
s.Stop()
fmt.Printf("%sError: %s%v%s\n", SGR(FgRed), SGR(FgYellow), err, SGR(FgReset))
prn.Error("Error", err)
return
}
s.Stop()
fmt.Printf("%s%s %s(%s)%s\n", SGR(FgWhite), info.IP, SGR(FgCyan), info.ISP, SGR(FgReset))
prn.BrightIPln(info)

credProvider := aws.NewCredentialsCache(
credentials.NewStaticCredentialsProvider(cfg.AccessKey, cfg.SecretKey, ""),
Expand All @@ -40,22 +48,22 @@ func main() {
config.WithRegion("us-east-1"),
)
if err != nil {
fmt.Printf("%sError loading AWS config: %s%v%s\n", SGR(FgRed), SGR(FgYellow), err, SGR(FgReset))
prn.Error("Error loading AWS config", err)
return
}

fmt.Print("Updating IP... ")
prn.Print("Updating IP... ")
s.Start()
err = InvokeLambda(ctx, awscfg, cfg.LambdaName, info.IP)
if err != nil {
s.Stop()
fmt.Printf("%sError invoking lambda: %s%v%s\n", SGR(FgRed), SGR(FgYellow), err, SGR(FgReset))
prn.Error("AWS Error", err)
return
}
s.Stop()
fmt.Printf("%sDone%s\n", SGR(FgWhite), SGR(FgReset))
prn.BrightPrintln("Done")

fmt.Printf("Success!\n\n")
prn.Print("Success!\n\n")
}

func InvokeLambda(ctx context.Context, awscfg aws.Config, lambdaName, ip string) error {
Expand All @@ -70,7 +78,7 @@ func InvokeLambda(ctx context.Context, awscfg aws.Config, lambdaName, ip string)
return err
}
if result.FunctionError != nil {
return fmt.Errorf("lambda function error: %s", *result.FunctionError)
return fmt.Errorf("remote function error: %s", *result.FunctionError)
}

return nil
Expand Down
82 changes: 82 additions & 0 deletions cmd/upmyip/print.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"fmt"
"strings"

"github.com/danbrakeley/frog/ansi"
)

type Printer struct {
NoColor bool
}

func (p Printer) Header(a ...string) {
var s strings.Builder
s.Grow(256)
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgBlue))
}
for _, v := range a {
s.WriteString(v)
}
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgReset))
}
fmt.Println(s.String())
}

func (p Printer) Print(a ...any) {
fmt.Print(a...)
}

func (p Printer) BrightPrintln(msg string) {
var s strings.Builder
s.Grow(256)
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgWhite))
}
s.WriteString(msg)
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgReset))
}
fmt.Println(s.String())
}

func (p Printer) Error(prefix string, err error) {
var s strings.Builder
s.Grow(256)
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgRed))
}
s.WriteString(prefix)
s.WriteString(": ")
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgYellow))
}
s.WriteString(err.Error())
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgReset))
}
fmt.Println(s.String())
}

func (p Printer) BrightIPln(info *PublicInfo) {
var s strings.Builder
s.Grow(256)
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgWhite))
}
s.WriteString(info.IP)
s.WriteRune(' ')
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgCyan))
}
s.WriteRune('(')
s.WriteString(info.ISP)
s.WriteRune(')')
if !p.NoColor {
s.WriteString(ansi.SGR(ansi.FgReset))
}
fmt.Println(s.String())
}
113 changes: 25 additions & 88 deletions cmd/upmyip/spinner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@ package main

import (
"fmt"
"strings"
"sync"
"time"

"github.com/danbrakeley/frog/ansi"
)

type Spinner struct {
frame int
mspf int
frames []rune

done chan struct{}
wg *sync.WaitGroup
frame int
mspf int
frames []rune
noColor bool
done chan struct{}
wg *sync.WaitGroup
}

func NewSpinner() *Spinner {
func NewSpinner(noColor bool) *Spinner {
return &Spinner{
frame: 0,
mspf: 200,
frames: []rune{'.', 'o', 'O', '@', '*'},
frame: 0,
mspf: 120,
frames: []rune{'.', 'o', 'O', '@', '*'},
noColor: noColor,
}
}

Expand All @@ -46,91 +48,26 @@ func (s *Spinner) Stop() {

func (s *Spinner) Run() {
defer s.wg.Done()
fmt.Print(HideCursor)
defer fmt.Print(EraseEOL + ShowCursor + SGR(Reset))
fmt.Print(ansi.HideCursor)
defer fmt.Print(ansi.EraseEOL + ansi.ShowCursor + ansi.SGR(ansi.Reset))

green := ""
if !s.noColor {
green = ansi.SGR(ansi.FgGreen)
}
reset := ""
if !s.noColor {
reset = ansi.SGR(ansi.FgReset)
}

for {
select {
case <-s.done:
return
default:
fmt.Printf("%s%c%s", SGR(FgGreen), s.frames[s.frame], Left(1)+SGR(FgReset))
fmt.Printf("%s%c%s", green, s.frames[s.frame], ansi.Left(1)+reset)
s.frame = (s.frame + 1) % len(s.frames)
<-time.After(time.Duration(s.mspf) * time.Millisecond)
}
}
}

const (
EscRune = '\u001b'
Esc = string(EscRune)
CSI = Esc + "[" // Control Sequence Introducer

EraseEOL = CSI + "K" // erase to end of current line

// DECTCEM commands

ShowCursor = CSI + "?25h"
HideCursor = CSI + "?25l"
)

func Right(n int) string {
return fmt.Sprintf(CSI+"%dC", n)
}

func Left(n int) string {
return fmt.Sprintf(CSI+"%dD", n)
}

const (
Reset = "0"
FgBlack = "30"
FgDarkRed = "31"
FgDarkGreen = "32"
FgDarkYellow = "33"
FgDarkBlue = "34"
FgDarkMagenta = "35"
FgDarkCyan = "36"
FgLightGray = "37"
FgReset = "39" // sets foreground color to default
BgBlack = "40"
BgDarkRed = "41"
BgDarkGreen = "42"
BgDarkYellow = "43"
BgDarkBlue = "44"
BgDarkMagenta = "45"
BgDarkCyan = "46"
BgLightGray = "47"
BgReset = "49" // sets background color to default
FgDarkGray = "90"
FgRed = "91"
FgGreen = "92"
FgYellow = "93"
FgBlue = "94"
FgMagenta = "95"
FgCyan = "96"
FgWhite = "97"
BgDarkGray = "100"
BgRed = "101"
BgGreen = "102"
BgYellow = "103"
BgBlue = "104"
BgMagenta = "105"
BgCyan = "106"
BgWhite = "107"
)

// SGR applies the above sgr params in the order specified (later commands may override earlier commands)
func SGR(params ...string) string {
var sb strings.Builder
sb.Grow(len(params)*4 + 2) // worst case: n 3-char params, n-1 semicolons, <esc>, '[', and 'm'
sb.WriteString(CSI)
for i, v := range params {
if i != 0 {
sb.WriteRune(';')
}
sb.WriteString(string(v))
}
sb.WriteRune('m')
return sb.String()
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/ec2 v1.164.1
github.com/aws/aws-sdk-go-v2/service/lambda v1.54.6
github.com/danbrakeley/bsh v0.2.0
github.com/danbrakeley/frog v0.10.0
github.com/magefile/mage v1.15.0
)

Expand All @@ -28,4 +29,6 @@ require (
github.com/aws/smithy-go v1.20.2 // indirect
github.com/danbrakeley/commandline v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
golang.org/x/sys v0.5.0 // indirect
)
15 changes: 15 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ github.com/danbrakeley/bsh v0.2.0 h1:ymKekjFekftmn2eEQvQk0MDjuhdaiTVLeI6mEfy52us
github.com/danbrakeley/bsh v0.2.0/go.mod h1:s6MsY0JONwbMmO6PucUyqTSULGTPTTdRMohD0iccFtA=
github.com/danbrakeley/commandline v1.0.0 h1:9qOX7wnJxECT0ZEZav6P5/GVdX/xSsPnIwQ9ptpMUuc=
github.com/danbrakeley/commandline v1.0.0/go.mod h1:TebcfPCZN3Dpc0DZMp68KTbVzCr07KCfAVkrYlLi2is=
github.com/danbrakeley/frog v0.10.0 h1:YtORqrv+3J0w/1t7GKl/I3+cDfI2xhEFKDRC5ARCYJM=
github.com/danbrakeley/frog v0.10.0/go.mod h1:p2AWOH3knZHylnQLcDqoR633mOi6UMpFVPzV9iTNPUg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -48,11 +50,24 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC
github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down

0 comments on commit 46aa0f2

Please sign in to comment.