pterm based refactoring
This commit is contained in:
parent
c634777934
commit
3c56eee5bf
@ -1,4 +0,0 @@
|
||||
[bumpversion]
|
||||
current_version = 0.1.0
|
||||
commit = True
|
||||
tag = True
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,4 +15,4 @@
|
||||
# vendor/
|
||||
|
||||
# Own stuff
|
||||
fortlit-go_*
|
||||
dist/*
|
||||
|
27
Makefile
27
Makefile
@ -1,24 +1,3 @@
|
||||
.PHONY: build clean test lint dep-update
|
||||
|
||||
VERSION ?= $(shell git describe --tags --always --dirty --match=v* 2> /dev/null || \
|
||||
echo v0)
|
||||
|
||||
build:
|
||||
export GOFLAGS=-mod=vendor
|
||||
CGO_ENABLED=0 gox -mod vendor -ldflags '-extldflags "-static" -X "main.version=${VERSION}"' .
|
||||
|
||||
clean:
|
||||
rm fortlit-go_*
|
||||
|
||||
test:
|
||||
export GOFLAGS=-mod=vendor
|
||||
go test ./...
|
||||
|
||||
lint:
|
||||
golangci-lint run --enable-all
|
||||
|
||||
dep-update:
|
||||
go get -u ./...
|
||||
go test ./...
|
||||
go mod tidy
|
||||
go mod vendor
|
||||
.PHONY: generate
|
||||
generate:
|
||||
go generate -v
|
||||
|
244
data/bindata.go
244
data/bindata.go
File diff suppressed because one or more lines are too long
12
go.mod
12
go.mod
@ -1,5 +1,13 @@
|
||||
module github.com/xsteadfastx/fortlit-go
|
||||
module go.xsfx.dev/fortlit
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/stretchr/testify v1.4.0
|
||||
require (
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 // indirect
|
||||
github.com/dave/jennifer v1.4.1
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/pterm/pterm v0.12.9
|
||||
github.com/sergi/go-diff v1.0.0 // indirect
|
||||
)
|
||||
|
40
go.sum
40
go.sum
@ -1,11 +1,41 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||
github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw=
|
||||
github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA=
|
||||
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=
|
||||
github.com/gookit/color v1.3.7 h1:wtJz526qll4+TxVcUUaMJOzrXDCiPr6jlyB5VSOBd2U=
|
||||
github.com/gookit/color v1.3.7/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
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/pterm/pterm v0.12.9 h1:i25Prnm6ZFnBgXxNT7pmOiRi4pYnnLFGA1UxQEB5dU0=
|
||||
github.com/pterm/pterm v0.12.9/go.mod h1:KBjax57xK2AcylgCzaoZjOu0K0dy0JgaZbQzxhNpPUc=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210223212115-eede4237b368 h1:fDE3p0qf2V1co1vfj3/o87Ps8Hq6QTGNxJ5Xe7xSp80=
|
||||
golang.org/x/sys v0.0.0-20210223212115-eede4237b368/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
98
main.go
98
main.go
@ -1,89 +1,77 @@
|
||||
// nolint: exhaustivestruct, gochecknoglobals, gomnd
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xsteadfastx/fortlit-go/data"
|
||||
"github.com/pterm/pterm"
|
||||
"go.xsfx.dev/fortlit/quotes"
|
||||
)
|
||||
|
||||
//go:generate go-bindata -pkg data -o ./data/bindata.go litdata.json
|
||||
//go:generate go fmt ./data/bindata.go
|
||||
//go:generate go run tools/gen/gen.go
|
||||
//go:generate gofumpt -w quotes/quotes.go
|
||||
|
||||
var version = "development"
|
||||
const lineWords = 8
|
||||
|
||||
const (
|
||||
Purple = "\033[1;34m%s\033[0m"
|
||||
Teal = "\033[1;36m%s\033[0m"
|
||||
var (
|
||||
ColorAuthor = pterm.NewRGB(189, 147, 249)
|
||||
ColorTime = pterm.NewRGB(80, 250, 123)
|
||||
ColorBook = pterm.NewRGB(255, 121, 198)
|
||||
)
|
||||
|
||||
type Quote struct {
|
||||
Author string `json:"author"`
|
||||
Book string `json:"book"`
|
||||
Text string `json:"text"`
|
||||
Time string `json:"time"`
|
||||
}
|
||||
func getQuote(qs map[string][]quotes.Quote, t string) quotes.Quote {
|
||||
var q quotes.Quote
|
||||
|
||||
func get(qs map[string][]Quote, t string) Quote {
|
||||
quote := Quote{}
|
||||
|
||||
if _, exists := qs[t]; exists {
|
||||
//nolint: gomnd
|
||||
if _, ok := qs[t]; ok {
|
||||
if len(qs[t]) != 1 {
|
||||
rand.Seed(time.Now().Unix())
|
||||
quote = qs[t][rand.Intn(len(qs[t]))]
|
||||
q = qs[t][rand.Intn(len(qs[t]))] // nolint: gosec
|
||||
} else {
|
||||
quote = qs[t][0]
|
||||
q = qs[t][0]
|
||||
}
|
||||
}
|
||||
|
||||
return quote
|
||||
return q
|
||||
}
|
||||
|
||||
func open(as string) []byte {
|
||||
data, err := data.Asset(as)
|
||||
func stringWrap(text string, limit int) string {
|
||||
ts := strings.Fields(text)
|
||||
rs := ""
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
wc := 0
|
||||
for _, i := range ts {
|
||||
if wc < limit {
|
||||
rs = rs + " " + i
|
||||
wc++
|
||||
} else {
|
||||
rs = rs + " " + i + "\n"
|
||||
wc = 0
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func (q *Quote) decorate() string {
|
||||
m := regexp.MustCompile(fmt.Sprintf("(?i)(%s)", q.Time))
|
||||
text := m.ReplaceAllString(q.Text, fmt.Sprintf(Purple, "$1"))
|
||||
|
||||
return fmt.Sprintf("\n%s\n\n - %s, %s\n", text, q.Book, fmt.Sprintf(Teal, q.Author))
|
||||
return rs
|
||||
}
|
||||
|
||||
func main() {
|
||||
fversion := flag.Bool("version", false, "Shows version.")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *fversion {
|
||||
fmt.Printf("Version: %s", version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
data := open("litdata.json")
|
||||
qs := make(map[string][]Quote)
|
||||
|
||||
if err := json.Unmarshal(data, &qs); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
t := fmt.Sprintf("%02d:%02d", now.Hour(), now.Minute())
|
||||
quote := get(qs, t)
|
||||
q := getQuote(quotes.FortData, t)
|
||||
|
||||
if quote != (Quote{}) {
|
||||
fmt.Println(quote.decorate())
|
||||
if q == (quotes.Quote{}) {
|
||||
return
|
||||
}
|
||||
|
||||
m := regexp.MustCompile(fmt.Sprintf("(?i)(%s)", q.Time))
|
||||
text := m.ReplaceAllString(q.Text, ColorTime.Sprint("$1"))
|
||||
|
||||
pterm.DefaultCenter.Println(
|
||||
pterm.DefaultBox.Sprint(
|
||||
stringWrap(text, lineWords),
|
||||
),
|
||||
)
|
||||
pterm.DefaultCenter.Println(fmt.Sprintf("✍️ %s - 📖 %s", ColorAuthor.Sprint(q.Author), ColorBook.Sprint(q.Book)))
|
||||
}
|
||||
|
70
main_test.go
70
main_test.go
@ -3,57 +3,45 @@ package main
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/alecthomas/assert"
|
||||
)
|
||||
|
||||
func TestDecorate(t *testing.T) {
|
||||
func TestGenWordSlice(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tables := []struct {
|
||||
q Quote
|
||||
n string
|
||||
input []string
|
||||
index int
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
Quote{
|
||||
"Max Mustermann",
|
||||
"Testbook",
|
||||
"This is a time!",
|
||||
"time",
|
||||
},
|
||||
"\nThis is a \033[1;34mtime\033[0m!\n\n - Testbook, \033[1;36mMax Mustermann\033[0m\n",
|
||||
},
|
||||
{
|
||||
Quote{
|
||||
"Iain Banks",
|
||||
"Espedair Street",
|
||||
"Three twenty-three! Is that all?",
|
||||
"three twenty-three",
|
||||
},
|
||||
"\n\033[1;34mThree twenty-three\033[0m! Is that all?\n\n - Espedair Street, \033[1;36mIain Banks\033[0m\n",
|
||||
[]string{"foo", "bar", "zonk"},
|
||||
2,
|
||||
[][]string{{"foo", "bar"}, {"zonk"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
r := table.q.decorate()
|
||||
assert.Equal(table.n, r)
|
||||
assert.Equal(genWordSlice(table.input, table.index), table.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tables := []struct {
|
||||
m map[string][]Quote
|
||||
q Quote
|
||||
}{
|
||||
{
|
||||
map[string][]Quote{"00:00": {
|
||||
Quote{"Max Mustermann", "Testbook", "This is a time!", "time"},
|
||||
}},
|
||||
Quote{"Max Mustermann", "Testbook", "This is a time!", "time"},
|
||||
},
|
||||
}
|
||||
for _, table := range tables {
|
||||
q := get(table.m, "00:00")
|
||||
if q != table.q {
|
||||
t.Errorf("quote \"%+v\" is not like \"%+v\"", q, table.q)
|
||||
}
|
||||
}
|
||||
}
|
||||
// func TestGet(t *testing.T) {
|
||||
// tables := []struct {
|
||||
// m map[string][]Quote
|
||||
// q Quote
|
||||
// }{
|
||||
// {
|
||||
// map[string][]Quote{"00:00": {
|
||||
// Quote{"Max Mustermann", "Testbook", "This is a time!", "time"},
|
||||
// }},
|
||||
// Quote{"Max Mustermann", "Testbook", "This is a time!", "time"},
|
||||
// },
|
||||
// }
|
||||
// for _, table := range tables {
|
||||
// q := get(table.m, "00:00")
|
||||
// if q != table.q {
|
||||
// t.Errorf("quote \"%+v\" is not like \"%+v\"", q, table.q)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
0
quotes/.keep
Normal file
0
quotes/.keep
Normal file
8137
quotes/quotes.go
Normal file
8137
quotes/quotes.go
Normal file
File diff suppressed because it is too large
Load Diff
75
tools/gen/gen.go
Normal file
75
tools/gen/gen.go
Normal file
@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/dave/jennifer/jen"
|
||||
)
|
||||
|
||||
type Quote struct {
|
||||
Author string `json:"author"`
|
||||
Book string `json:"book"`
|
||||
Text string `json:"text"`
|
||||
Time string `json:"time"`
|
||||
}
|
||||
|
||||
func read(p string) (map[string][]Quote, error) {
|
||||
m := map[string][]Quote{}
|
||||
|
||||
f, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
return m, fmt.Errorf("could not read json file: %w", err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(f, &m); err != nil {
|
||||
return m, fmt.Errorf("could not unmarshal file: %w", err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
m, err := read("assets/litdata.json")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
f := jen.NewFile("quotes")
|
||||
f.Comment("Code generated by go generate.")
|
||||
f.Comment("nolint: lll")
|
||||
|
||||
f.Var().Id("FortData").Op("=").Map(jen.String()).Index().Id("Quote").Values(jen.DictFunc(func(d jen.Dict) {
|
||||
for k, v := range m {
|
||||
qs := []jen.Code{}
|
||||
for _, i := range v {
|
||||
qs = append(qs, jen.Id("Quote").Values(
|
||||
jen.Dict{
|
||||
jen.Id("Author"): jen.Lit(i.Author),
|
||||
jen.Id("Book"): jen.Lit(i.Book),
|
||||
jen.Id("Text"): jen.Lit(i.Text),
|
||||
jen.Id("Time"): jen.Lit(i.Time),
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
d[jen.Lit(k)] = jen.Index().Id("Quote").Values(
|
||||
qs...,
|
||||
)
|
||||
}
|
||||
}))
|
||||
|
||||
f.Type().Id("Quote").Struct(
|
||||
jen.Id("Author").String(),
|
||||
jen.Id("Book").String(),
|
||||
jen.Id("Text").String(),
|
||||
jen.Id("Time").String(),
|
||||
)
|
||||
|
||||
if err := f.Save("quotes/quotes.go"); err != nil {
|
||||
log.Fatalf("could not save file: %s", err.Error())
|
||||
}
|
||||
}
|
@ -1,16 +1,6 @@
|
||||
The following files were ported to Go from C files of libyaml, and thus
|
||||
are still covered by their original copyright and license:
|
||||
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
|
||||
|
||||
apic.go
|
||||
emitterc.go
|
||||
parserc.go
|
||||
readerc.go
|
||||
scannerc.go
|
||||
writerc.go
|
||||
yamlh.go
|
||||
yamlprivateh.go
|
||||
|
||||
Copyright (c) 2006 Kirill Simonov
|
||||
Please consider promoting this project if you find it useful.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
39
vendor/github.com/alecthomas/assert/README.md
generated
vendored
Normal file
39
vendor/github.com/alecthomas/assert/README.md
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Go assertion library (fork of [stretchr/testify/require](https://github.com/stretchr/testify/tree/master/require))
|
||||
|
||||
This is a fork of stretchr's assertion library that does two things:
|
||||
|
||||
1. It makes spotting differences in equality much easier. It uses [repr](https://github.com/alecthomas/repr) and
|
||||
[diffmatchpatch](https://github.com/sergi/go-diff/diffmatchpatch) to display structural differences
|
||||
in colour.
|
||||
2. Aborts tests on first assertion failure (the same behaviour as `stretchr/testify/require`).
|
||||
|
||||
## Example
|
||||
|
||||
Given the following test:
|
||||
|
||||
```go
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// Use github.com/alecthomas/assert
|
||||
func TestDiff(t *testing.T) {
|
||||
expected := []*Person{{"Alec", 20}, {"Bob", 21}, {"Sally", 22}}
|
||||
actual := []*Person{{"Alex", 20}, {"Bob", 22}, {"Sally", 22}}
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
// Use github.com/stretchr/testify/require
|
||||
func TestTestifyDiff(t *testing.T) {
|
||||
expected := []*Person{{"Alec", 20}, {"Bob", 21}, {"Sally", 22}}
|
||||
actual := []*Person{{"Alex", 20}, {"Bob", 22}, {"Sally", 22}}
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
```
|
||||
|
||||
The following output illustrates the problems this solves. Firstly, it shows
|
||||
nested structures correctly, and secondly it highlights the differences between
|
||||
actual and expected text.
|
||||
|
||||
<img style="overflow-x: auto;" src="./_example/diff.png">
|
826
vendor/github.com/alecthomas/assert/assertions.go
generated
vendored
Normal file
826
vendor/github.com/alecthomas/assert/assertions.go
generated
vendored
Normal file
@ -0,0 +1,826 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/alecthomas/repr"
|
||||
)
|
||||
|
||||
// TestingT is an interface wrapper around *testing.T
|
||||
type TestingT interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
FailNow()
|
||||
}
|
||||
|
||||
// Comparison a custom function that returns true on success and false on failure
|
||||
type Comparison func() (success bool)
|
||||
|
||||
/*
|
||||
Helper functions
|
||||
*/
|
||||
|
||||
// ObjectsAreEqual determines if two objects are considered equal.
|
||||
//
|
||||
// This function does no assertion of any kind.
|
||||
func ObjectsAreEqual(expected, actual interface{}) bool {
|
||||
|
||||
if expected == nil || actual == nil {
|
||||
return expected == actual
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(expected, actual) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
// ObjectsAreEqualValues gets whether two objects are equal, or if their
|
||||
// values are equal.
|
||||
func ObjectsAreEqualValues(expected, actual interface{}) bool {
|
||||
if ObjectsAreEqual(expected, actual) {
|
||||
return true
|
||||
}
|
||||
|
||||
actualType := reflect.TypeOf(actual)
|
||||
expectedValue := reflect.ValueOf(expected)
|
||||
if expectedValue.Type().ConvertibleTo(actualType) {
|
||||
// Attempt comparison after type conversion
|
||||
if reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/* CallerInfo is necessary because the assert functions use the testing object
|
||||
internally, causing it to print the file:line of the assert method, rather than where
|
||||
the problem actually occured in calling code.*/
|
||||
|
||||
// CallerInfo returns an array of strings containing the file and line number
|
||||
// of each stack frame leading from the current test to the assert call that
|
||||
// failed.
|
||||
func CallerInfo() []string {
|
||||
|
||||
pc := uintptr(0)
|
||||
file := ""
|
||||
line := 0
|
||||
ok := false
|
||||
name := ""
|
||||
|
||||
callers := []string{}
|
||||
for i := 0; ; i++ {
|
||||
pc, file, line, ok = runtime.Caller(i)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is a huge edge case, but it will panic if this is the case, see #180
|
||||
if file == "<autogenerated>" {
|
||||
break
|
||||
}
|
||||
|
||||
parts := strings.Split(file, "/")
|
||||
dir := parts[len(parts)-2]
|
||||
file = parts[len(parts)-1]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
}
|
||||
|
||||
f := runtime.FuncForPC(pc)
|
||||
if f == nil {
|
||||
break
|
||||
}
|
||||
name = f.Name()
|
||||
// Drop the package
|
||||
segments := strings.Split(name, ".")
|
||||
name = segments[len(segments)-1]
|
||||
if isTest(name, "Test") ||
|
||||
isTest(name, "Benchmark") ||
|
||||
isTest(name, "Example") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return callers
|
||||
}
|
||||
|
||||
// Stolen from the `go test` tool.
|
||||
// isTest tells whether name looks like a test (or benchmark, according to prefix).
|
||||
// It is a Test (say) if there is a character after Test that is not a lower-case letter.
|
||||
// We don't want TesticularCancer.
|
||||
func isTest(name, prefix string) bool {
|
||||
if !strings.HasPrefix(name, prefix) {
|
||||
return false
|
||||
}
|
||||
if len(name) == len(prefix) { // "Test" is ok
|
||||
return true
|
||||
}
|
||||
rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
||||
return !unicode.IsLower(rune)
|
||||
}
|
||||
|
||||
// getWhitespaceString returns a string that is long enough to overwrite the default
|
||||
// output from the go testing framework.
|
||||
func getWhitespaceString() string {
|
||||
|
||||
_, file, line, ok := runtime.Caller(1)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
parts := strings.Split(file, "/")
|
||||
file = parts[len(parts)-1]
|
||||
|
||||
return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line)))
|
||||
|
||||
}
|
||||
|
||||
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
||||
if len(msgAndArgs) == 0 || msgAndArgs == nil {
|
||||
return ""
|
||||
}
|
||||
if len(msgAndArgs) == 1 {
|
||||
return msgAndArgs[0].(string)
|
||||
}
|
||||
if len(msgAndArgs) > 1 {
|
||||
return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's
|
||||
// test printing (see inner comment for specifics)
|
||||
func indentMessageLines(message string, tabs int) string {
|
||||
outBuf := new(bytes.Buffer)
|
||||
|
||||
for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
|
||||
if i != 0 {
|
||||
outBuf.WriteRune('\n')
|
||||
}
|
||||
for ii := 0; ii < tabs; ii++ {
|
||||
outBuf.WriteRune('\t')
|
||||
// Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter
|
||||
// by 1 prematurely.
|
||||
if ii == 0 && i > 0 {
|
||||
ii++
|
||||
}
|
||||
}
|
||||
outBuf.WriteString(scanner.Text())
|
||||
}
|
||||
|
||||
return outBuf.String()
|
||||
}
|
||||
|
||||
// Fail reports a failure through
|
||||
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
|
||||
|
||||
message := messageFromMsgAndArgs(msgAndArgs...)
|
||||
|
||||
errorTrace := strings.Join(CallerInfo(), "\n\r\t\t\t")
|
||||
if len(message) > 0 {
|
||||
t.Errorf("\r%s\r\tError Trace:\t%s\n"+
|
||||
"\r\tError:%s\n"+
|
||||
"\r\tMessages:\t%s\n\r",
|
||||
getWhitespaceString(),
|
||||
errorTrace,
|
||||
indentMessageLines(failureMessage, 2),
|
||||
message)
|
||||
} else {
|
||||
t.Errorf("\r%s\r\tError Trace:\t%s\n"+
|
||||
"\r\tError:%s\n\r",
|
||||
getWhitespaceString(),
|
||||
errorTrace,
|
||||
indentMessageLines(failureMessage, 2))
|
||||
}
|
||||
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Implements asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
|
||||
func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
interfaceType := reflect.TypeOf(interfaceObject).Elem()
|
||||
|
||||
if !reflect.TypeOf(object).Implements(interfaceType) {
|
||||
Fail(t, fmt.Sprintf("Object must implement %v", interfaceType), msgAndArgs...)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
|
||||
Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equal(t, 123, 123, "123 and 123 should be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
if !ObjectsAreEqual(expected, actual) {
|
||||
Fail(t, fmt.Sprintf("Not equal: %s", DiffValues(expected, actual)), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
if !ObjectsAreEqualValues(expected, actual) {
|
||||
Fail(t, fmt.Sprintf("Not equal: %s", DiffValues(expected, actual)), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal is value and type.
|
||||
//
|
||||
// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
aType := reflect.TypeOf(expected)
|
||||
bType := reflect.TypeOf(actual)
|
||||
|
||||
if aType != bType {
|
||||
Fail(t, "Types expected to match exactly", "%v != %v", aType, bType)
|
||||
}
|
||||
|
||||
Equal(t, expected, actual, msgAndArgs...)
|
||||
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNil(t, err, "err should be something")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if !isNil(object) {
|
||||
return
|
||||
}
|
||||
Fail(t, "Expected value not to be nil.", msgAndArgs...)
|
||||
}
|
||||
|
||||
// isNil checks if a specified object is nil or not, without Failing.
|
||||
func isNil(object interface{}) bool {
|
||||
if object == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(object)
|
||||
kind := value.Kind()
|
||||
if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Nil asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nil(t, err, "err should be nothing")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if isNil(object) {
|
||||
return
|
||||
}
|
||||
Fail(t, fmt.Sprintf("Expected nil, but got: %s", repr.String(object, repr.OmitEmpty(true))), msgAndArgs...)
|
||||
}
|
||||
|
||||
var numericZeros = []interface{}{
|
||||
int(0),
|
||||
int8(0),
|
||||
int16(0),
|
||||
int32(0),
|
||||
int64(0),
|
||||
uint(0),
|
||||
uint8(0),
|
||||
uint16(0),
|
||||
uint32(0),
|
||||
uint64(0),
|
||||
float32(0),
|
||||
float64(0),
|
||||
}
|
||||
|
||||
// isEmpty gets whether the specified object is considered empty or not.
|
||||
func isEmpty(object interface{}) bool {
|
||||
|
||||
if object == nil {
|
||||
return true
|
||||
} else if object == "" {
|
||||
return true
|
||||
} else if object == false {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, v := range numericZeros {
|
||||
if object == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
objValue := reflect.ValueOf(object)
|
||||
|
||||
switch objValue.Kind() {
|
||||
case reflect.Map:
|
||||
fallthrough
|
||||
case reflect.Slice, reflect.Chan:
|
||||
{
|
||||
return (objValue.Len() == 0)
|
||||
}
|
||||
case reflect.Ptr:
|
||||
{
|
||||
switch object.(type) {
|
||||
case *time.Time:
|
||||
return object.(*time.Time).IsZero()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// assert.Empty(t, obj)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
pass := isEmpty(object)
|
||||
if !pass {
|
||||
Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// assert.NotEmpty(t, obj)
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
pass := !isEmpty(object)
|
||||
if !pass {
|
||||
Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// getLen try to get length of object.
|
||||
// return (false, 0) if impossible.
|
||||
func getLen(x interface{}) (ok bool, length int) {
|
||||
v := reflect.ValueOf(x)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
return true, v.Len()
|
||||
}
|
||||
|
||||
// Len asserts that the specified object has specific length.
|
||||
// Len also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Len(t, mySlice, 3, "The size of slice is not 3")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
|
||||
ok, l := getLen(object)
|
||||
if !ok {
|
||||
Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
|
||||
}
|
||||
|
||||
if l != length {
|
||||
Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// True asserts that the specified value is true.
|
||||
//
|
||||
// assert.True(t, myBool, "myBool should be true")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func True(t TestingT, value bool, msgAndArgs ...interface{}) {
|
||||
|
||||
if value != true {
|
||||
Fail(t, "Should be true", msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// False asserts that the specified value is true.
|
||||
//
|
||||
// assert.False(t, myBool, "myBool should be false")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func False(t TestingT, value bool, msgAndArgs ...interface{}) {
|
||||
|
||||
if value != false {
|
||||
Fail(t, "Should be false", msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
if ObjectsAreEqual(expected, actual) {
|
||||
Fail(t, fmt.Sprintf("Should not be: %s\n", repr.String(actual, repr.OmitEmpty(true))), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// containsElement try loop over the list check if the list includes the element.
|
||||
// return (false, false) if impossible.
|
||||
// return (true, false) if element was not found.
|
||||
// return (true, true) if element was found.
|
||||
func includeElement(list interface{}, element interface{}) (ok, found bool) {
|
||||
|
||||
listValue := reflect.ValueOf(list)
|
||||
elementValue := reflect.ValueOf(element)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ok = false
|
||||
found = false
|
||||
}
|
||||
}()
|
||||
|
||||
if reflect.TypeOf(list).Kind() == reflect.String {
|
||||
return true, strings.Contains(listValue.String(), elementValue.String())
|
||||
}
|
||||
|
||||
for i := 0; i < listValue.Len(); i++ {
|
||||
if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
|
||||
return true, true
|
||||
}
|
||||
}
|
||||
return true, false
|
||||
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string or list(array, slice...) contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
ok, found := includeElement(s, contains)
|
||||
if !ok {
|
||||
Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
|
||||
}
|
||||
if !found {
|
||||
Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string or list(array, slice...) does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) {
|
||||
|
||||
ok, found := includeElement(s, contains)
|
||||
if !ok {
|
||||
Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
|
||||
}
|
||||
if found {
|
||||
Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// Condition uses a Comparison to assert a complex condition.
|
||||
func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) {
|
||||
result := comp()
|
||||
if !result {
|
||||
Fail(t, "Condition failed!", msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics
|
||||
// methods, and represents a simple func that takes no arguments, and returns nothing.
|
||||
type PanicTestFunc func()
|
||||
|
||||
// didPanic returns true if the function passed to it panics. Otherwise, it returns false.
|
||||
func didPanic(f PanicTestFunc) (bool, interface{}) {
|
||||
|
||||
didPanic := false
|
||||
var message interface{}
|
||||
func() {
|
||||
|
||||
defer func() {
|
||||
if message = recover(); message != nil {
|
||||
didPanic = true
|
||||
}
|
||||
}()
|
||||
|
||||
// call the target function
|
||||
f()
|
||||
|
||||
}()
|
||||
|
||||
return didPanic, message
|
||||
|
||||
}
|
||||
|
||||
// Panics asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panics(t, func(){
|
||||
// GoCrazy()
|
||||
// }, "Calling GoCrazy() should panic")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
|
||||
if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
|
||||
Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanics(t, func(){
|
||||
// RemainCalm()
|
||||
// }, "Calling RemainCalm() should NOT panic")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
|
||||
if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
|
||||
Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// WithinDuration asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
|
||||
|
||||
dt := expected.Sub(actual)
|
||||
if dt < -delta || dt > delta {
|
||||
Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
func toFloat(x interface{}) (float64, bool) {
|
||||
var xf float64
|
||||
xok := true
|
||||
|
||||
switch xn := x.(type) {
|
||||
case uint8:
|
||||
xf = float64(xn)
|
||||
case uint16:
|
||||
xf = float64(xn)
|
||||
case uint32:
|
||||
xf = float64(xn)
|
||||
case uint64:
|
||||
xf = float64(xn)
|
||||
case int:
|
||||
xf = float64(xn)
|
||||
case int8:
|
||||
xf = float64(xn)
|
||||
case int16:
|
||||
xf = float64(xn)
|
||||
case int32:
|
||||
xf = float64(xn)
|
||||
case int64:
|
||||
xf = float64(xn)
|
||||
case float32:
|
||||
xf = float64(xn)
|
||||
case float64:
|
||||
xf = float64(xn)
|
||||
default:
|
||||
xok = false
|
||||
}
|
||||
|
||||
return xf, xok
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
|
||||
af, aok := toFloat(expected)
|
||||
bf, bok := toFloat(actual)
|
||||
|
||||
if !aok || !bok {
|
||||
Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
|
||||
}
|
||||
|
||||
if math.IsNaN(af) {
|
||||
Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...)
|
||||
}
|
||||
|
||||
if math.IsNaN(bf) {
|
||||
Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
|
||||
}
|
||||
|
||||
dt := af - bf
|
||||
if dt < -delta || dt > delta {
|
||||
Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
if expected == nil || actual == nil ||
|
||||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
|
||||
reflect.TypeOf(expected).Kind() != reflect.Slice {
|
||||
Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
|
||||
}
|
||||
|
||||
actualSlice := reflect.ValueOf(actual)
|
||||
expectedSlice := reflect.ValueOf(expected)
|
||||
|
||||
for i := 0; i < actualSlice.Len(); i++ {
|
||||
InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta)
|
||||
}
|
||||
}
|
||||
|
||||
// min(|expected|, |actual|) * epsilon
|
||||
func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 {
|
||||
af, aok := toFloat(expected)
|
||||
bf, bok := toFloat(actual)
|
||||
|
||||
if !aok || !bok {
|
||||
// invalid input
|
||||
return 0
|
||||
}
|
||||
|
||||
if af < 0 {
|
||||
af = -af
|
||||
}
|
||||
if bf < 0 {
|
||||
bf = -bf
|
||||
}
|
||||
var delta float64
|
||||
if af < bf {
|
||||
delta = af * epsilon
|
||||
} else {
|
||||
delta = bf * epsilon
|
||||
}
|
||||
return delta
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
|
||||
delta := calcEpsilonDelta(expected, actual, epsilon)
|
||||
InDelta(t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InEpsilonSlice is the same as InEpsilon, except it compares two slices.
|
||||
func InEpsilonSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
if expected == nil || actual == nil ||
|
||||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
|
||||
reflect.TypeOf(expected).Kind() != reflect.Slice {
|
||||
Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
|
||||
}
|
||||
|
||||
actualSlice := reflect.ValueOf(actual)
|
||||
expectedSlice := reflect.ValueOf(expected)
|
||||
|
||||
for i := 0; i < actualSlice.Len(); i++ {
|
||||
InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Errors
|
||||
*/
|
||||
|
||||
// NoError asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.NoError(t, err)
|
||||
// assert.Equal(t, actualObj, expectedObj)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
|
||||
if isNil(err) {
|
||||
return
|
||||
}
|
||||
|
||||
Fail(t, fmt.Sprintf("No error is expected but got %v", err), msgAndArgs...)
|
||||
}
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.Error(t, err, "An error was expected")
|
||||
// assert.Equal(t, err, expectedError)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Error(t TestingT, err error, msgAndArgs ...interface{}) {
|
||||
message := messageFromMsgAndArgs(msgAndArgs...)
|
||||
NotNil(t, err, "An error is expected but got nil. %s", message)
|
||||
}
|
||||
|
||||
// EqualError asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.Error(t, err, "An error was expected")
|
||||
// assert.Equal(t, err, expectedError)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
|
||||
message := messageFromMsgAndArgs(msgAndArgs...)
|
||||
NotNil(t, theError, "An error is expected but got nil. %s", message)
|
||||
s := "An error with value \"%s\" is expected but got \"%s\". %s"
|
||||
Equal(t, errString, theError.Error(), s, errString, theError.Error(), message)
|
||||
}
|
||||
|
||||
// matchRegexp return true if a specified regexp matches a string.
|
||||
func matchRegexp(rx interface{}, str interface{}) bool {
|
||||
|
||||
var r *regexp.Regexp
|
||||
if rr, ok := rx.(*regexp.Regexp); ok {
|
||||
r = rr
|
||||
} else {
|
||||
r = regexp.MustCompile(fmt.Sprint(rx))
|
||||
}
|
||||
|
||||
return (r.FindStringIndex(fmt.Sprint(str)) != nil)
|
||||
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
|
||||
// assert.Regexp(t, "start...$", "it's not starting")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
|
||||
match := matchRegexp(rx, str)
|
||||
if !match {
|
||||
Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NotRegexp asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
|
||||
// assert.NotRegexp(t, "^start", "it's not starting")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
|
||||
match := matchRegexp(rx, str)
|
||||
if match {
|
||||
Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
||||
Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
||||
Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
|
||||
}
|
||||
}
|
56
vendor/github.com/alecthomas/assert/diff.go
generated
vendored
Normal file
56
vendor/github.com/alecthomas/assert/diff.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/alecthomas/colour"
|
||||
"github.com/alecthomas/repr"
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
)
|
||||
|
||||
func DiffValues(a, b interface{}) string {
|
||||
printer := colour.String()
|
||||
diff := diffmatchpatch.New()
|
||||
at := repr.String(a, repr.OmitEmpty(true))
|
||||
bt := repr.String(b, repr.OmitEmpty(true))
|
||||
diffs := diff.DiffMain(at, bt, true)
|
||||
for _, d := range diffs {
|
||||
switch d.Type {
|
||||
case diffmatchpatch.DiffEqual:
|
||||
if len(d.Text) <= 40 {
|
||||
printer.Print(d.Text)
|
||||
} else {
|
||||
printer.Printf("%s^B...^R%s", d.Text[:15], d.Text[len(d.Text)-15:])
|
||||
}
|
||||
case diffmatchpatch.DiffDelete:
|
||||
printer.Printf("^9%s^R", d.Text)
|
||||
case diffmatchpatch.DiffInsert:
|
||||
printer.Printf("^a%s^R", d.Text)
|
||||
}
|
||||
}
|
||||
return printer.String()
|
||||
}
|
||||
|
||||
func DiffValuesDefault(a, b interface{}) string {
|
||||
diff := diffmatchpatch.New()
|
||||
at := repr.String(a)
|
||||
bt := repr.String(b)
|
||||
diffs := diff.DiffMain(at, bt, true)
|
||||
w := bytes.NewBuffer(nil)
|
||||
for _, d := range diffs {
|
||||
switch d.Type {
|
||||
case diffmatchpatch.DiffEqual:
|
||||
if len(d.Text) <= 40 {
|
||||
w.WriteString(d.Text)
|
||||
} else {
|
||||
fmt.Fprintf(w, "%s...%s", d.Text[:15], d.Text[len(d.Text)-15:])
|
||||
}
|
||||
case diffmatchpatch.DiffDelete:
|
||||
fmt.Fprintf(w, "-{{%s}}", d.Text)
|
||||
case diffmatchpatch.DiffInsert:
|
||||
fmt.Fprintf(w, "+{{%s}}", d.Text)
|
||||
}
|
||||
}
|
||||
return w.String()
|
||||
}
|
45
vendor/github.com/alecthomas/assert/doc.go
generated
vendored
Normal file
45
vendor/github.com/alecthomas/assert/doc.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
|
||||
//
|
||||
// Example Usage
|
||||
//
|
||||
// The following is a complete example using assert in a standard test function:
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// assert.Equal(t, a, b, "The two words should be the same.")
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if you assert many times, use the format below:
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// assert := assert.New(t)
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// assert.Equal(a, b, "The two words should be the same.")
|
||||
// }
|
||||
//
|
||||
// Assertions
|
||||
//
|
||||
// Assertions allow you to easily write test code, and are global funcs in the `assert` package.
|
||||
// All assertion functions take, as the first argument, the `*testing.T` object provided by the
|
||||
// testing framework. This allows the assertion funcs to write the failings and other details to
|
||||
// the correct place.
|
||||
//
|
||||
// Every assertion function also takes an optional string message as the final argument,
|
||||
// allowing custom error messages to be appended to the message the assertion method outputs.
|
||||
package assert
|
10
vendor/github.com/alecthomas/assert/errors.go
generated
vendored
Normal file
10
vendor/github.com/alecthomas/assert/errors.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// AnError is an error instance useful for testing. If the code does not care
|
||||
// about error specifics, and only needs to return the error for example, this
|
||||
// error should be used to make the test code more readable.
|
||||
var AnError = errors.New("assert.AnError general error for testing")
|
275
vendor/github.com/alecthomas/assert/forward_assertions.go
generated
vendored
Normal file
275
vendor/github.com/alecthomas/assert/forward_assertions.go
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
package assert
|
||||
|
||||
import "time"
|
||||
|
||||
// Assertions provides assertion methods around the
|
||||
// TestingT interface.
|
||||
type Assertions struct {
|
||||
t TestingT
|
||||
}
|
||||
|
||||
// New makes a new Assertions object for the specified TestingT.
|
||||
func New(t TestingT) *Assertions {
|
||||
return &Assertions{
|
||||
t: t,
|
||||
}
|
||||
}
|
||||
|
||||
// Fail reports a failure through
|
||||
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {
|
||||
Fail(a.t, failureMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Implements asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
|
||||
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
Implements(a.t, interfaceObject, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
IsType(a.t, expectedType, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equal(123, 123, "123 and 123 should be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
Equal(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// assert.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualValues(expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
EqualValues(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal is value and type.
|
||||
//
|
||||
// assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Exactly(expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
Exactly(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNil(err, "err should be something")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {
|
||||
NotNil(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Nil asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nil(err, "err should be nothing")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {
|
||||
Nil(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a
|
||||
// slice with len == 0.
|
||||
//
|
||||
// assert.Empty(obj)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
|
||||
Empty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
|
||||
// slice with len == 0.
|
||||
//
|
||||
// if assert.NotEmpty(obj) {
|
||||
// assert.Equal("two", obj[1])
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
|
||||
NotEmpty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Len asserts that the specified object has specific length.
|
||||
// Len also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Len(mySlice, 3, "The size of slice is not 3")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {
|
||||
Len(a.t, object, length, msgAndArgs...)
|
||||
}
|
||||
|
||||
// True asserts that the specified value is true.
|
||||
//
|
||||
// assert.True(myBool, "myBool should be true")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) {
|
||||
True(a.t, value, msgAndArgs...)
|
||||
}
|
||||
|
||||
// False asserts that the specified value is true.
|
||||
//
|
||||
// assert.False(myBool, "myBool should be false")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) {
|
||||
False(a.t, value, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqual(obj1, obj2, "two objects shouldn't be equal")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotEqual(expected, actual interface{}, msgAndArgs ...interface{}) {
|
||||
NotEqual(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string contains the specified substring.
|
||||
//
|
||||
// assert.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Contains(s, contains interface{}, msgAndArgs ...interface{}) {
|
||||
Contains(a.t, s, contains, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string does NOT contain the specified substring.
|
||||
//
|
||||
// assert.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interface{}) {
|
||||
NotContains(a.t, s, contains, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Condition uses a Comparison to assert a complex condition.
|
||||
func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) {
|
||||
Condition(a.t, comp, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Panics asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panics(func(){
|
||||
// GoCrazy()
|
||||
// }, "Calling GoCrazy() should panic")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
Panics(a.t, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanics(func(){
|
||||
// RemainCalm()
|
||||
// }, "Calling RemainCalm() should NOT panic")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
NotPanics(a.t, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// WithinDuration asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
|
||||
WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
|
||||
InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NoError asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoError(err) {
|
||||
// assert.Equal(actualObj, expectedObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NoError(theError error, msgAndArgs ...interface{}) {
|
||||
NoError(a.t, theError, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Error(err, "An error was expected") {
|
||||
// assert.Equal(err, expectedError)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) {
|
||||
Error(a.t, theError, msgAndArgs...)
|
||||
}
|
||||
|
||||
// EqualError asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Error(err, "An error was expected") {
|
||||
// assert.Equal(err, expectedError)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {
|
||||
EqualError(a.t, theError, errString, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
|
||||
// assert.Regexp(t, "start...$", "it's not starting")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
|
||||
Regexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotRegexp asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
|
||||
// assert.NotRegexp(t, "^start", "it's not starting")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
|
||||
NotRegexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
|
||||
Zero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
|
||||
NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
157
vendor/github.com/alecthomas/assert/http_assertions.go
generated
vendored
Normal file
157
vendor/github.com/alecthomas/assert/http_assertions.go
generated
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// httpCode is a helper that returns HTTP code of the response. It returns -1
|
||||
// if building a new request fails.
|
||||
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int {
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
handler(w, req)
|
||||
return w.Code
|
||||
}
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
return false
|
||||
}
|
||||
return code >= http.StatusOK && code <= http.StatusPartialContent
|
||||
}
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
return false
|
||||
}
|
||||
return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
|
||||
}
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
return false
|
||||
}
|
||||
return code >= http.StatusBadRequest
|
||||
}
|
||||
|
||||
// HTTPBody is a helper that returns HTTP body of the response. It returns
|
||||
// empty string if building a new request fails.
|
||||
func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
handler(w, req)
|
||||
return w.Body.String()
|
||||
}
|
||||
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
body := HTTPBody(handler, method, url, values)
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if !contains {
|
||||
Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
|
||||
}
|
||||
|
||||
return contains
|
||||
}
|
||||
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
body := HTTPBody(handler, method, url, values)
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if contains {
|
||||
Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)
|
||||
}
|
||||
|
||||
return !contains
|
||||
}
|
||||
|
||||
//
|
||||
// Assertions Wrappers
|
||||
//
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
return HTTPSuccess(a.t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
return HTTPRedirect(a.t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
return HTTPError(a.t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
return HTTPBodyContains(a.t, handler, method, url, values, str)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
return HTTPBodyNotContains(a.t, handler, method, url, values, str)
|
||||
}
|
4
vendor/github.com/alecthomas/colour/.travis.yml
generated
vendored
Normal file
4
vendor/github.com/alecthomas/colour/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
sudo: false
|
||||
language: go
|
||||
install: go get -t -v ./...
|
||||
go: 1.2
|
21
vendor/github.com/alecthomas/colour/COPYING
generated
vendored
Normal file
21
vendor/github.com/alecthomas/colour/COPYING
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Alec Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
44
vendor/github.com/alecthomas/colour/README.md
generated
vendored
Normal file
44
vendor/github.com/alecthomas/colour/README.md
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
# Colour terminal text for Go (Golang) [](http://godoc.org/github.com/alecthomas/colour) [](https://travis-ci.org/alecthomas/colour)
|
||||
|
||||
Package colour provides [Quake-style colour formatting][2] for Unix terminals.
|
||||
|
||||
The package level functions can be used to write to stdout (or strings or
|
||||
other files). If stdout is not a terminal, colour formatting will be
|
||||
stripped.
|
||||
|
||||
eg.
|
||||
|
||||
colour.Printf("^0black ^1red ^2green ^3yellow ^4blue ^5magenta ^6cyan ^7white^R\n")
|
||||
|
||||
|
||||
For more control a Printer object can be created with various helper
|
||||
functions. This can be used to do useful things such as strip formatting,
|
||||
write to strings, and so on.
|
||||
|
||||
The following sequences are converted to their equivalent ANSI colours:
|
||||
|
||||
| Sequence | Effect |
|
||||
| -------- | ------ |
|
||||
| ^0 | Black |
|
||||
| ^1 | Red |
|
||||
| ^2 | Green |
|
||||
| ^3 | Yellow |
|
||||
| ^4 | Blue |
|
||||
| ^5 | Cyan (light blue) |
|
||||
| ^6 | Magenta (purple) |
|
||||
| ^7 | White |
|
||||
| ^8 | Black Background |
|
||||
| ^9 | Red Background |
|
||||
| ^a | Green Background |
|
||||
| ^b | Yellow Background |
|
||||
| ^c | Blue Background |
|
||||
| ^d | Cyan (light blue) Background |
|
||||
| ^e | Magenta (purple) Background |
|
||||
| ^f | White Background |
|
||||
| ^R | Reset |
|
||||
| ^U | Underline |
|
||||
| ^D | Dim |
|
||||
| ^B | Bold |
|
||||
|
||||
[1]: http://godoc.org/github.com/alecthomas/colour
|
||||
[2]: http://www.holysh1t.net/quake-live-colors-nickname/
|
257
vendor/github.com/alecthomas/colour/colour.go
generated
vendored
Normal file
257
vendor/github.com/alecthomas/colour/colour.go
generated
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
// Package colour ([docs][1]) provides [Quake-style colour formatting][2] for Unix terminals.
|
||||
//
|
||||
// It is a drop-in replacement for the fmt package.
|
||||
//
|
||||
// The package level functions can be used to write to stdout (or strings or
|
||||
// other files). If stdout is not a terminal, colour formatting will be
|
||||
// stripped.
|
||||
//
|
||||
// eg.
|
||||
//
|
||||
// colour.Printf("^0black ^1red ^2green ^3yellow ^4blue ^5magenta ^6cyan ^7white^R\n")
|
||||
//
|
||||
//
|
||||
// For more control a Printer object can be created with various helper
|
||||
// functions. This can be used to do useful things such as strip formatting,
|
||||
// write to strings, and so on.
|
||||
//
|
||||
// The following sequences are converted to their equivalent ANSI colours:
|
||||
//
|
||||
// ^0 = Black
|
||||
// ^1 = Red
|
||||
// ^2 = Green
|
||||
// ^3 = Yellow
|
||||
// ^4 = Blue
|
||||
// ^5 = Cyan (light blue)
|
||||
// ^6 = Magenta (purple)
|
||||
// ^7 = White
|
||||
// ^8 = Black Background
|
||||
// ^9 = Red Background
|
||||
// ^a = Green Background
|
||||
// ^b = Yellow Background
|
||||
// ^c = Blue Background
|
||||
// ^d = Cyan (light blue) Background
|
||||
// ^e = Magenta (purple) Background
|
||||
// ^f = White Background
|
||||
// ^R = Reset
|
||||
// ^U = Underline
|
||||
// ^B = Bold
|
||||
//
|
||||
// [1]: http://godoc.org/github.com/alecthomas/colour
|
||||
// [2]: http://www.holysh1t.net/quake-live-colors-nickname/
|
||||
package colour
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
var (
|
||||
extract = regexp.MustCompile(`(\^[0-9a-fRDUB])|(\^\^)|([^^]+)`)
|
||||
colours = map[byte]string{
|
||||
'0': "\033[30m",
|
||||
'1': "\033[31m",
|
||||
'2': "\033[32m",
|
||||
'3': "\033[33m",
|
||||
'4': "\033[34m",
|
||||
'5': "\033[35m",
|
||||
'6': "\033[36m",
|
||||
'7': "\033[37m",
|
||||
|
||||
'8': "\033[40m",
|
||||
'9': "\033[41m",
|
||||
'a': "\033[42m",
|
||||
'b': "\033[43m",
|
||||
'c': "\033[44m",
|
||||
'd': "\033[45m",
|
||||
'e': "\033[46m",
|
||||
'f': "\033[47m",
|
||||
|
||||
'R': "\033[0m", // reset
|
||||
'B': "\033[1m", // bold
|
||||
'D': "\033[2m", // dim
|
||||
'U': "\033[4m",
|
||||
}
|
||||
|
||||
// Stdout is an conditional colour writer for os.Stdout.
|
||||
Stdout = TTY(os.Stdout)
|
||||
// Stderr is an conditional colour writer for os.Stderr.
|
||||
Stderr = TTY(os.Stderr)
|
||||
)
|
||||
|
||||
func Println(args ...interface{}) (n int, err error) {
|
||||
return Stdout.Println(args...)
|
||||
}
|
||||
|
||||
func Sprintln(args ...interface{}) string {
|
||||
s := String()
|
||||
_, _ = s.Println(args...)
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func Fprintln(w io.Writer, args ...interface{}) (n int, err error) {
|
||||
return TTY(w).Println(args...)
|
||||
}
|
||||
|
||||
func Print(args ...interface{}) (n int, err error) {
|
||||
return Stdout.Print(args...)
|
||||
}
|
||||
|
||||
func Sprint(args ...interface{}) string {
|
||||
s := String()
|
||||
_, _ = s.Print(args...)
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func Fprint(w io.Writer, args ...interface{}) (n int, err error) {
|
||||
return TTY(w).Print(args...)
|
||||
}
|
||||
|
||||
func Printf(format string, args ...interface{}) (n int, err error) {
|
||||
return Stdout.Printf(format, args...)
|
||||
}
|
||||
|
||||
func Sprintf(format string, args ...interface{}) string {
|
||||
s := String()
|
||||
_, _ = s.Printf(format, args...)
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func Fprintf(w io.Writer, format string, args ...interface{}) (n int, err error) {
|
||||
return TTY(w).Printf(format, args...)
|
||||
}
|
||||
|
||||
// A Printer implements functions that accept Quake-style colour formatting
|
||||
// and print coloured text.
|
||||
type Printer interface {
|
||||
Println(args ...interface{}) (n int, err error)
|
||||
Print(args ...interface{}) (n int, err error)
|
||||
Printf(format string, args ...interface{}) (n int, err error)
|
||||
}
|
||||
|
||||
// TTY creates a Printer that colourises output if w is a terminal, or strips
|
||||
// formatting if it is not.
|
||||
func TTY(w io.Writer) Printer {
|
||||
if f, ok := w.(*os.File); ok && isatty.IsTerminal(f.Fd()) {
|
||||
return &colourPrinter{w}
|
||||
}
|
||||
return &stripPrinter{w}
|
||||
}
|
||||
|
||||
// Colour creats a new ANSI colour Printer on w.
|
||||
func Colour(w io.Writer) Printer {
|
||||
return &colourPrinter{w}
|
||||
}
|
||||
|
||||
// Strip returns a Printer that strips all colour codes from printed strings before writing to w.
|
||||
func Strip(w io.Writer) Printer {
|
||||
return &stripPrinter{w}
|
||||
}
|
||||
|
||||
type StringPrinter struct {
|
||||
Printer
|
||||
w *bytes.Buffer
|
||||
}
|
||||
|
||||
// String creates a new Printer that writes ANSI coloured text to a buffer.
|
||||
// Use the String() method to return the printed string.
|
||||
func String() *StringPrinter {
|
||||
w := &bytes.Buffer{}
|
||||
f := Colour(w)
|
||||
return &StringPrinter{f, w}
|
||||
}
|
||||
|
||||
// StringStripper writes text stripped of colour formatting codes to a string.
|
||||
// Use the String() method to return the printed string.
|
||||
func StringStripper() *StringPrinter {
|
||||
w := &bytes.Buffer{}
|
||||
f := Strip(w)
|
||||
return &StringPrinter{f, w}
|
||||
}
|
||||
|
||||
func (s *StringPrinter) String() string {
|
||||
return s.w.String()
|
||||
}
|
||||
|
||||
type colourPrinter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (c *colourPrinter) Println(args ...interface{}) (n int, err error) {
|
||||
for i, arg := range args {
|
||||
if s, ok := arg.(string); ok {
|
||||
args[i] = FormatString(s)
|
||||
}
|
||||
}
|
||||
return fmt.Fprintln(c.w, args...)
|
||||
}
|
||||
|
||||
func (c *colourPrinter) Print(args ...interface{}) (n int, err error) {
|
||||
for i, arg := range args {
|
||||
if s, ok := arg.(string); ok {
|
||||
args[i] = FormatString(s)
|
||||
}
|
||||
}
|
||||
return fmt.Fprint(c.w, args...)
|
||||
}
|
||||
|
||||
func (c *colourPrinter) Printf(format string, args ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(c.w, FormatString(format), args...)
|
||||
}
|
||||
|
||||
type stripPrinter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (p *stripPrinter) Println(args ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(p.w, stripArgs(args...)...)
|
||||
}
|
||||
|
||||
func (p *stripPrinter) Print(args ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(p.w, stripArgs(args...)...)
|
||||
}
|
||||
|
||||
func (p *stripPrinter) Printf(format string, args ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(p.w, StripFormatting(format), args...)
|
||||
}
|
||||
|
||||
func FormatString(s string) string {
|
||||
out := &bytes.Buffer{}
|
||||
for _, match := range extract.FindAllStringSubmatch(s, -1) {
|
||||
if match[1] != "" {
|
||||
n := match[1][1]
|
||||
out.WriteString(colours[n])
|
||||
} else if match[2] != "" {
|
||||
out.WriteString("^")
|
||||
} else {
|
||||
out.WriteString(match[3])
|
||||
}
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func StripFormatting(s string) string {
|
||||
out := &bytes.Buffer{}
|
||||
for _, match := range extract.FindAllStringSubmatch(s, -1) {
|
||||
if match[2] != "" {
|
||||
out.WriteString("^")
|
||||
} else if match[1] == "" {
|
||||
out.WriteString(match[3])
|
||||
}
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func stripArgs(args ...interface{}) []interface{} {
|
||||
for i, arg := range args {
|
||||
if s, ok := arg.(string); ok {
|
||||
args[i] = StripFormatting(s)
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
4
vendor/github.com/alecthomas/repr/.travis.yml
generated
vendored
Normal file
4
vendor/github.com/alecthomas/repr/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
sudo: false
|
||||
language: go
|
||||
install: go get -t -v ./...
|
||||
go: 1.9
|
21
vendor/github.com/alecthomas/repr/COPYING
generated
vendored
Normal file
21
vendor/github.com/alecthomas/repr/COPYING
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Alec Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
90
vendor/github.com/alecthomas/repr/README.md
generated
vendored
Normal file
90
vendor/github.com/alecthomas/repr/README.md
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
# Python's repr() for Go [](http://godoc.org/github.com/alecthomas/repr) [](https://travis-ci.org/alecthomas/repr)
|
||||
|
||||
This package attempts to represent Go values in a form that can be used almost directly in Go source
|
||||
code.
|
||||
|
||||
Unfortunately, some values (such as pointers to basic types) can not be represented directly in Go.
|
||||
These values will be represented as `&<value>`. eg. `&23`
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
type test struct {
|
||||
S string
|
||||
I int
|
||||
A []int
|
||||
}
|
||||
|
||||
func main() {
|
||||
repr.Print(&test{
|
||||
S: "String",
|
||||
I: 123,
|
||||
A: []int{1, 2, 3},
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Outputs
|
||||
|
||||
```
|
||||
&main.test{S: "String", I: 123, A: []int{1, 2, 3}}
|
||||
```
|
||||
|
||||
## Why repr and not [pp](https://github.com/k0kubun/pp)?
|
||||
|
||||
pp is designed for printing coloured output to consoles, with (seemingly?) no way to disable this. If you don't want coloured output (eg. for use in diffs, logs, etc.) repr is for you.
|
||||
|
||||
## Why repr and not [go-spew](https://github.com/davecgh/go-spew)?
|
||||
|
||||
Repr deliberately contains much less metadata about values. It is designed to (generally) be copyable directly into source code.
|
||||
|
||||
Compare go-spew:
|
||||
|
||||
```go
|
||||
(parser.expression) (len=1 cap=1) {
|
||||
(parser.alternative) (len=1 cap=1) {
|
||||
([]interface {}) (len=1 cap=1) {
|
||||
(*parser.repitition)(0xc82000b220)({
|
||||
expression: (parser.expression) (len=2 cap=2) {
|
||||
(parser.alternative) (len=1 cap=1) {
|
||||
([]interface {}) (len=1 cap=1) {
|
||||
(parser.str) (len=1) "a"
|
||||
}
|
||||
},
|
||||
(parser.alternative) (len=1 cap=1) {
|
||||
([]interface {}) (len=1 cap=1) {
|
||||
(*parser.self)(0x593ef0)({
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To repr:
|
||||
|
||||
```go
|
||||
parser.expression{
|
||||
parser.alternative{
|
||||
[]interface {}{
|
||||
&parser.repitition{
|
||||
expression: parser.expression{
|
||||
parser.alternative{
|
||||
[]interface {}{
|
||||
parser.str("a"),
|
||||
},
|
||||
},
|
||||
parser.alternative{
|
||||
[]interface {}{
|
||||
&parser.self{ },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
320
vendor/github.com/alecthomas/repr/repr.go
generated
vendored
Normal file
320
vendor/github.com/alecthomas/repr/repr.go
generated
vendored
Normal file
@ -0,0 +1,320 @@
|
||||
// Package repr attempts to represent Go values in a form that can be copy-and-pasted into source
|
||||
// code directly.
|
||||
//
|
||||
// Some values (such as pointers to basic types) can not be represented directly in
|
||||
// Go. These values will be output as `&<value>`. eg. `&23`
|
||||
package repr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
// "Real" names of basic kinds, used to differentiate type aliases.
|
||||
realKindName = map[reflect.Kind]string{
|
||||
reflect.Bool: "bool",
|
||||
reflect.Int: "int",
|
||||
reflect.Int8: "int8",
|
||||
reflect.Int16: "int16",
|
||||
reflect.Int32: "int32",
|
||||
reflect.Int64: "int64",
|
||||
reflect.Uint: "uint",
|
||||
reflect.Uint8: "uint8",
|
||||
reflect.Uint16: "uint16",
|
||||
reflect.Uint32: "uint32",
|
||||
reflect.Uint64: "uint64",
|
||||
reflect.Uintptr: "uintptr",
|
||||
reflect.Float32: "float32",
|
||||
reflect.Float64: "float64",
|
||||
reflect.Complex64: "complex64",
|
||||
reflect.Complex128: "complex128",
|
||||
reflect.Array: "array",
|
||||
reflect.Chan: "chan",
|
||||
reflect.Func: "func",
|
||||
reflect.Map: "map",
|
||||
reflect.Slice: "slice",
|
||||
reflect.String: "string",
|
||||
}
|
||||
|
||||
goStringerType = reflect.TypeOf((*fmt.GoStringer)(nil)).Elem()
|
||||
|
||||
byteSliceType = reflect.TypeOf([]byte{})
|
||||
)
|
||||
|
||||
// Default prints to os.Stdout with two space indentation.
|
||||
var Default = New(os.Stdout, Indent(" "))
|
||||
|
||||
// An Option modifies the default behaviour of a Printer.
|
||||
type Option func(o *Printer)
|
||||
|
||||
// Indent output by this much.
|
||||
func Indent(indent string) Option { return func(o *Printer) { o.indent = indent } }
|
||||
|
||||
// NoIndent disables indenting.
|
||||
func NoIndent() Option { return Indent("") }
|
||||
|
||||
// OmitEmpty sets whether empty field members should be omitted from output.
|
||||
func OmitEmpty(omitEmpty bool) Option { return func(o *Printer) { o.omitEmpty = omitEmpty } }
|
||||
|
||||
func IgnoreGoStringer() Option { return func(o *Printer) { o.ignoreGoStringer = true } }
|
||||
|
||||
// Hide excludes the given types from representation, instead just printing the name of the type.
|
||||
func Hide(ts ...interface{}) Option {
|
||||
return func(o *Printer) {
|
||||
for _, t := range ts {
|
||||
rt := reflect.Indirect(reflect.ValueOf(t)).Type()
|
||||
o.exclude[rt] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Printer represents structs in a printable manner.
|
||||
type Printer struct {
|
||||
indent string
|
||||
omitEmpty bool
|
||||
ignoreGoStringer bool
|
||||
exclude map[reflect.Type]bool
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
// New creates a new Printer on w with the given Options.
|
||||
func New(w io.Writer, options ...Option) *Printer {
|
||||
p := &Printer{
|
||||
w: w,
|
||||
indent: " ",
|
||||
omitEmpty: true,
|
||||
exclude: map[reflect.Type]bool{},
|
||||
}
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Printer) nextIndent(indent string) string {
|
||||
if p.indent != "" {
|
||||
return indent + p.indent
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *Printer) thisIndent(indent string) string {
|
||||
if p.indent != "" {
|
||||
return indent
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Print the values.
|
||||
func (p *Printer) Print(vs ...interface{}) {
|
||||
for i, v := range vs {
|
||||
if i > 0 {
|
||||
fmt.Fprint(p.w, " ")
|
||||
}
|
||||
p.reprValue(map[reflect.Value]bool{}, reflect.ValueOf(v), "")
|
||||
}
|
||||
}
|
||||
|
||||
// Println prints each value on a new line.
|
||||
func (p *Printer) Println(vs ...interface{}) {
|
||||
for i, v := range vs {
|
||||
if i > 0 {
|
||||
fmt.Fprint(p.w, " ")
|
||||
}
|
||||
p.reprValue(map[reflect.Value]bool{}, reflect.ValueOf(v), "")
|
||||
}
|
||||
fmt.Fprintln(p.w)
|
||||
}
|
||||
|
||||
func (p *Printer) reprValue(seen map[reflect.Value]bool, v reflect.Value, indent string) { // nolint: gocyclo
|
||||
if seen[v] {
|
||||
fmt.Fprint(p.w, "...")
|
||||
return
|
||||
}
|
||||
seen[v] = true
|
||||
defer delete(seen, v)
|
||||
|
||||
if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Map || v.Kind() == reflect.Chan || v.Kind() == reflect.Slice || v.Kind() == reflect.Func || v.Kind() == reflect.Interface) && v.IsNil() {
|
||||
fmt.Fprint(p.w, "nil")
|
||||
return
|
||||
}
|
||||
if p.exclude[v.Type()] {
|
||||
fmt.Fprintf(p.w, "%s...", v.Type().Name())
|
||||
return
|
||||
}
|
||||
t := v.Type()
|
||||
|
||||
if t == byteSliceType {
|
||||
fmt.Fprintf(p.w, "[]byte(%q)", v.Interface())
|
||||
return
|
||||
}
|
||||
|
||||
// If we can't access a private field directly with reflection, try and do so via unsafe.
|
||||
if !v.CanInterface() && v.CanAddr() {
|
||||
uv := reflect.NewAt(t, unsafe.Pointer(v.UnsafeAddr())).Elem()
|
||||
if uv.CanInterface() {
|
||||
v = uv
|
||||
}
|
||||
}
|
||||
// Attempt to use fmt.GoStringer interface.
|
||||
if !p.ignoreGoStringer && t.Implements(goStringerType) {
|
||||
fmt.Fprint(p.w, v.Interface().(fmt.GoStringer).GoString())
|
||||
return
|
||||
}
|
||||
in := p.thisIndent(indent)
|
||||
ni := p.nextIndent(indent)
|
||||
switch v.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
if p.omitEmpty && v.Len() == 0 {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(p.w, "%s{", v.Type())
|
||||
if v.Len() == 0 {
|
||||
fmt.Fprint(p.w, "}")
|
||||
} else {
|
||||
if p.indent != "" {
|
||||
fmt.Fprintf(p.w, "\n")
|
||||
}
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
e := v.Index(i)
|
||||
fmt.Fprintf(p.w, "%s", ni)
|
||||
p.reprValue(seen, e, ni)
|
||||
if p.indent != "" {
|
||||
fmt.Fprintf(p.w, ",\n")
|
||||
} else if i < v.Len()-1 {
|
||||
fmt.Fprintf(p.w, ", ")
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(p.w, "%s}", in)
|
||||
}
|
||||
|
||||
case reflect.Chan:
|
||||
fmt.Fprintf(p.w, "make(")
|
||||
fmt.Fprintf(p.w, "%s", v.Type())
|
||||
fmt.Fprintf(p.w, ", %d)", v.Cap())
|
||||
|
||||
case reflect.Map:
|
||||
fmt.Fprintf(p.w, "%s{", v.Type())
|
||||
if p.indent != "" && v.Len() != 0 {
|
||||
fmt.Fprintf(p.w, "\n")
|
||||
}
|
||||
for i, k := range v.MapKeys() {
|
||||
kv := v.MapIndex(k)
|
||||
fmt.Fprintf(p.w, "%s", ni)
|
||||
p.reprValue(seen, k, ni)
|
||||
fmt.Fprintf(p.w, ": ")
|
||||
p.reprValue(seen, kv, ni)
|
||||
if p.indent != "" {
|
||||
fmt.Fprintf(p.w, ",\n")
|
||||
} else if i < v.Len()-1 {
|
||||
fmt.Fprintf(p.w, ", ")
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(p.w, "%s}", in)
|
||||
|
||||
case reflect.Struct:
|
||||
fmt.Fprintf(p.w, "%s{", v.Type())
|
||||
if p.indent != "" && v.NumField() != 0 {
|
||||
fmt.Fprintf(p.w, "\n")
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
t := v.Type().Field(i)
|
||||
f := v.Field(i)
|
||||
if p.omitEmpty && isZero(f) {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(p.w, "%s%s: ", ni, t.Name)
|
||||
p.reprValue(seen, f, ni)
|
||||
if p.indent != "" {
|
||||
fmt.Fprintf(p.w, ",\n")
|
||||
} else if i < v.NumField()-1 {
|
||||
fmt.Fprintf(p.w, ", ")
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(p.w, "%s}", indent)
|
||||
|
||||
case reflect.Ptr:
|
||||
if v.IsNil() {
|
||||
fmt.Fprintf(p.w, "nil")
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(p.w, "&")
|
||||
p.reprValue(seen, v.Elem(), indent)
|
||||
|
||||
case reflect.String:
|
||||
if t.Name() != "string" {
|
||||
fmt.Fprintf(p.w, "%s(%q)", t, v.String())
|
||||
} else {
|
||||
fmt.Fprintf(p.w, "%q", v.String())
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
if v.IsNil() {
|
||||
fmt.Fprintf(p.w, "interface {}(nil)")
|
||||
} else {
|
||||
p.reprValue(seen, v.Elem(), indent)
|
||||
}
|
||||
|
||||
default:
|
||||
if t.Name() != realKindName[t.Kind()] {
|
||||
fmt.Fprintf(p.w, "%s(%v)", t, v)
|
||||
} else {
|
||||
fmt.Fprintf(p.w, "%v", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a string representing v.
|
||||
func String(v interface{}, options ...Option) string {
|
||||
w := bytes.NewBuffer(nil)
|
||||
options = append([]Option{NoIndent()}, options...)
|
||||
p := New(w, options...)
|
||||
p.Print(v)
|
||||
return w.String()
|
||||
}
|
||||
|
||||
func extractOptions(vs ...interface{}) (args []interface{}, options []Option) {
|
||||
for _, v := range vs {
|
||||
if o, ok := v.(Option); ok {
|
||||
options = append(options, o)
|
||||
} else {
|
||||
args = append(args, v)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Println prints v to os.Stdout, one per line.
|
||||
func Println(vs ...interface{}) {
|
||||
args, options := extractOptions(vs...)
|
||||
New(os.Stdout, options...).Println(args...)
|
||||
}
|
||||
|
||||
// Print writes a representation of v to os.Stdout, separated by spaces.
|
||||
func Print(vs ...interface{}) {
|
||||
args, options := extractOptions(vs...)
|
||||
New(os.Stdout, options...).Print(args...)
|
||||
}
|
||||
|
||||
func isZero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
21
vendor/github.com/dave/jennifer/LICENSE
generated
vendored
Normal file
21
vendor/github.com/dave/jennifer/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 David Brophy
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
19
vendor/github.com/dave/jennifer/jen/add.go
generated
vendored
Normal file
19
vendor/github.com/dave/jennifer/jen/add.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package jen
|
||||
|
||||
// Add appends the provided items to the statement.
|
||||
func Add(code ...Code) *Statement {
|
||||
return newStatement().Add(code...)
|
||||
}
|
||||
|
||||
// Add appends the provided items to the statement.
|
||||
func (g *Group) Add(code ...Code) *Statement {
|
||||
s := Add(code...)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Add appends the provided items to the statement.
|
||||
func (s *Statement) Add(code ...Code) *Statement {
|
||||
*s = append(*s, code...)
|
||||
return s
|
||||
}
|
108
vendor/github.com/dave/jennifer/jen/comments.go
generated
vendored
Normal file
108
vendor/github.com/dave/jennifer/jen/comments.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Comment adds a comment. If the provided string contains a newline, the
|
||||
// comment is formatted in multiline style. If the comment string starts
|
||||
// with "//" or "/*", the automatic formatting is disabled and the string is
|
||||
// rendered directly.
|
||||
func Comment(str string) *Statement {
|
||||
return newStatement().Comment(str)
|
||||
}
|
||||
|
||||
// Comment adds a comment. If the provided string contains a newline, the
|
||||
// comment is formatted in multiline style. If the comment string starts
|
||||
// with "//" or "/*", the automatic formatting is disabled and the string is
|
||||
// rendered directly.
|
||||
func (g *Group) Comment(str string) *Statement {
|
||||
s := Comment(str)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Comment adds a comment. If the provided string contains a newline, the
|
||||
// comment is formatted in multiline style. If the comment string starts
|
||||
// with "//" or "/*", the automatic formatting is disabled and the string is
|
||||
// rendered directly.
|
||||
func (s *Statement) Comment(str string) *Statement {
|
||||
c := comment{
|
||||
comment: str,
|
||||
}
|
||||
*s = append(*s, c)
|
||||
return s
|
||||
}
|
||||
|
||||
// Commentf adds a comment, using a format string and a list of parameters. If
|
||||
// the provided string contains a newline, the comment is formatted in
|
||||
// multiline style. If the comment string starts with "//" or "/*", the
|
||||
// automatic formatting is disabled and the string is rendered directly.
|
||||
func Commentf(format string, a ...interface{}) *Statement {
|
||||
return newStatement().Commentf(format, a...)
|
||||
}
|
||||
|
||||
// Commentf adds a comment, using a format string and a list of parameters. If
|
||||
// the provided string contains a newline, the comment is formatted in
|
||||
// multiline style. If the comment string starts with "//" or "/*", the
|
||||
// automatic formatting is disabled and the string is rendered directly.
|
||||
func (g *Group) Commentf(format string, a ...interface{}) *Statement {
|
||||
s := Commentf(format, a...)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Commentf adds a comment, using a format string and a list of parameters. If
|
||||
// the provided string contains a newline, the comment is formatted in
|
||||
// multiline style. If the comment string starts with "//" or "/*", the
|
||||
// automatic formatting is disabled and the string is rendered directly.
|
||||
func (s *Statement) Commentf(format string, a ...interface{}) *Statement {
|
||||
c := comment{
|
||||
comment: fmt.Sprintf(format, a...),
|
||||
}
|
||||
*s = append(*s, c)
|
||||
return s
|
||||
}
|
||||
|
||||
type comment struct {
|
||||
comment string
|
||||
}
|
||||
|
||||
func (c comment) isNull(f *File) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c comment) render(f *File, w io.Writer, s *Statement) error {
|
||||
if strings.HasPrefix(c.comment, "//") || strings.HasPrefix(c.comment, "/*") {
|
||||
// automatic formatting disabled.
|
||||
if _, err := w.Write([]byte(c.comment)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if strings.Contains(c.comment, "\n") {
|
||||
if _, err := w.Write([]byte("/*\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := w.Write([]byte("// ")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := w.Write([]byte(c.comment)); err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.Contains(c.comment, "\n") {
|
||||
if !strings.HasSuffix(c.comment, "\n") {
|
||||
if _, err := w.Write([]byte("\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := w.Write([]byte("*/")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
61
vendor/github.com/dave/jennifer/jen/custom.go
generated
vendored
Normal file
61
vendor/github.com/dave/jennifer/jen/custom.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
package jen
|
||||
|
||||
// Options specifies options for the Custom method
|
||||
type Options struct {
|
||||
Open string
|
||||
Close string
|
||||
Separator string
|
||||
Multi bool
|
||||
}
|
||||
|
||||
// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
|
||||
func Custom(options Options, statements ...Code) *Statement {
|
||||
return newStatement().Custom(options, statements...)
|
||||
}
|
||||
|
||||
// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
|
||||
func (g *Group) Custom(options Options, statements ...Code) *Statement {
|
||||
s := Custom(options, statements...)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
|
||||
func (s *Statement) Custom(options Options, statements ...Code) *Statement {
|
||||
g := &Group{
|
||||
close: options.Close,
|
||||
items: statements,
|
||||
multi: options.Multi,
|
||||
name: "custom",
|
||||
open: options.Open,
|
||||
separator: options.Separator,
|
||||
}
|
||||
*s = append(*s, g)
|
||||
return s
|
||||
}
|
||||
|
||||
// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
|
||||
func CustomFunc(options Options, f func(*Group)) *Statement {
|
||||
return newStatement().CustomFunc(options, f)
|
||||
}
|
||||
|
||||
// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
|
||||
func (g *Group) CustomFunc(options Options, f func(*Group)) *Statement {
|
||||
s := CustomFunc(options, f)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
|
||||
func (s *Statement) CustomFunc(options Options, f func(*Group)) *Statement {
|
||||
g := &Group{
|
||||
close: options.Close,
|
||||
multi: options.Multi,
|
||||
name: "custom",
|
||||
open: options.Open,
|
||||
separator: options.Separator,
|
||||
}
|
||||
f(g)
|
||||
*s = append(*s, g)
|
||||
return s
|
||||
}
|
81
vendor/github.com/dave/jennifer/jen/dict.go
generated
vendored
Normal file
81
vendor/github.com/dave/jennifer/jen/dict.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Dict renders as key/value pairs. Use with Values for map or composite
|
||||
// literals.
|
||||
type Dict map[Code]Code
|
||||
|
||||
// DictFunc executes a func(Dict) to generate the value. Use with Values for
|
||||
// map or composite literals.
|
||||
func DictFunc(f func(Dict)) Dict {
|
||||
d := Dict{}
|
||||
f(d)
|
||||
return d
|
||||
}
|
||||
|
||||
func (d Dict) render(f *File, w io.Writer, s *Statement) error {
|
||||
first := true
|
||||
// must order keys to ensure repeatable source
|
||||
type kv struct {
|
||||
k Code
|
||||
v Code
|
||||
}
|
||||
lookup := map[string]kv{}
|
||||
keys := []string{}
|
||||
for k, v := range d {
|
||||
if k.isNull(f) || v.isNull(f) {
|
||||
continue
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
if err := k.render(f, buf, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
keys = append(keys, buf.String())
|
||||
lookup[buf.String()] = kv{k: k, v: v}
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
k := lookup[key].k
|
||||
v := lookup[key].v
|
||||
if first && len(keys) > 1 {
|
||||
if _, err := w.Write([]byte("\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
first = false
|
||||
}
|
||||
if err := k.render(f, w, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte(":")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v.render(f, w, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(keys) > 1 {
|
||||
if _, err := w.Write([]byte(",\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d Dict) isNull(f *File) bool {
|
||||
if d == nil || len(d) == 0 {
|
||||
return true
|
||||
}
|
||||
for k, v := range d {
|
||||
if !k.isNull(f) && !v.isNull(f) {
|
||||
// if any of the key/value pairs are both not null, the Dict is not
|
||||
// null
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
22
vendor/github.com/dave/jennifer/jen/do.go
generated
vendored
Normal file
22
vendor/github.com/dave/jennifer/jen/do.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
package jen
|
||||
|
||||
// Do calls the provided function with the statement as a parameter. Use for
|
||||
// embedding logic.
|
||||
func Do(f func(*Statement)) *Statement {
|
||||
return newStatement().Do(f)
|
||||
}
|
||||
|
||||
// Do calls the provided function with the statement as a parameter. Use for
|
||||
// embedding logic.
|
||||
func (g *Group) Do(f func(*Statement)) *Statement {
|
||||
s := Do(f)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Do calls the provided function with the statement as a parameter. Use for
|
||||
// embedding logic.
|
||||
func (s *Statement) Do(f func(*Statement)) *Statement {
|
||||
f(s)
|
||||
return s
|
||||
}
|
256
vendor/github.com/dave/jennifer/jen/file.go
generated
vendored
Normal file
256
vendor/github.com/dave/jennifer/jen/file.go
generated
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// NewFile Creates a new file, with the specified package name.
|
||||
func NewFile(packageName string) *File {
|
||||
return &File{
|
||||
Group: &Group{
|
||||
multi: true,
|
||||
},
|
||||
name: packageName,
|
||||
imports: map[string]importdef{},
|
||||
hints: map[string]importdef{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewFilePath creates a new file while specifying the package path - the
|
||||
// package name is inferred from the path.
|
||||
func NewFilePath(packagePath string) *File {
|
||||
return &File{
|
||||
Group: &Group{
|
||||
multi: true,
|
||||
},
|
||||
name: guessAlias(packagePath),
|
||||
path: packagePath,
|
||||
imports: map[string]importdef{},
|
||||
hints: map[string]importdef{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewFilePathName creates a new file with the specified package path and name.
|
||||
func NewFilePathName(packagePath, packageName string) *File {
|
||||
return &File{
|
||||
Group: &Group{
|
||||
multi: true,
|
||||
},
|
||||
name: packageName,
|
||||
path: packagePath,
|
||||
imports: map[string]importdef{},
|
||||
hints: map[string]importdef{},
|
||||
}
|
||||
}
|
||||
|
||||
// File represents a single source file. Package imports are managed
|
||||
// automaticaly by File.
|
||||
type File struct {
|
||||
*Group
|
||||
name string
|
||||
path string
|
||||
imports map[string]importdef
|
||||
hints map[string]importdef
|
||||
comments []string
|
||||
headers []string
|
||||
cgoPreamble []string
|
||||
// If you're worried about generated package aliases conflicting with local variable names, you
|
||||
// can set a prefix here. Package foo becomes {prefix}_foo.
|
||||
PackagePrefix string
|
||||
// CanonicalPath adds a canonical import path annotation to the package clause.
|
||||
CanonicalPath string
|
||||
}
|
||||
|
||||
// importdef is used to differentiate packages where we know the package name from packages where the
|
||||
// import is aliased. If alias == false, then name is the actual package name, and the import will be
|
||||
// rendered without an alias. If used == false, the import has not been used in code yet and should be
|
||||
// excluded from the import block.
|
||||
type importdef struct {
|
||||
name string
|
||||
alias bool
|
||||
}
|
||||
|
||||
// HeaderComment adds a comment to the top of the file, above any package
|
||||
// comments. A blank line is rendered below the header comments, ensuring
|
||||
// header comments are not included in the package doc.
|
||||
func (f *File) HeaderComment(comment string) {
|
||||
f.headers = append(f.headers, comment)
|
||||
}
|
||||
|
||||
// PackageComment adds a comment to the top of the file, above the package
|
||||
// keyword.
|
||||
func (f *File) PackageComment(comment string) {
|
||||
f.comments = append(f.comments, comment)
|
||||
}
|
||||
|
||||
// CgoPreamble adds a cgo preamble comment that is rendered directly before the "C" pseudo-package
|
||||
// import.
|
||||
func (f *File) CgoPreamble(comment string) {
|
||||
f.cgoPreamble = append(f.cgoPreamble, comment)
|
||||
}
|
||||
|
||||
// Anon adds an anonymous import.
|
||||
func (f *File) Anon(paths ...string) {
|
||||
for _, p := range paths {
|
||||
f.imports[p] = importdef{name: "_", alias: true}
|
||||
}
|
||||
}
|
||||
|
||||
// ImportName provides the package name for a path. If specified, the alias will be omitted from the
|
||||
// import block. This is optional. If not specified, a sensible package name is used based on the path
|
||||
// and this is added as an alias in the import block.
|
||||
func (f *File) ImportName(path, name string) {
|
||||
f.hints[path] = importdef{name: name, alias: false}
|
||||
}
|
||||
|
||||
// ImportNames allows multiple names to be imported as a map. Use the [gennames](gennames) command to
|
||||
// automatically generate a go file containing a map of a selection of package names.
|
||||
func (f *File) ImportNames(names map[string]string) {
|
||||
for path, name := range names {
|
||||
f.hints[path] = importdef{name: name, alias: false}
|
||||
}
|
||||
}
|
||||
|
||||
// ImportAlias provides the alias for a package path that should be used in the import block. A
|
||||
// period can be used to force a dot-import.
|
||||
func (f *File) ImportAlias(path, alias string) {
|
||||
f.hints[path] = importdef{name: alias, alias: true}
|
||||
}
|
||||
|
||||
func (f *File) isLocal(path string) bool {
|
||||
return f.path == path
|
||||
}
|
||||
|
||||
func (f *File) isValidAlias(alias string) bool {
|
||||
// multiple dot-imports are ok
|
||||
if alias == "." {
|
||||
return true
|
||||
}
|
||||
// the import alias is invalid if it's a reserved word
|
||||
if IsReservedWord(alias) {
|
||||
return false
|
||||
}
|
||||
// the import alias is invalid if it's already been registered
|
||||
for _, v := range f.imports {
|
||||
if alias == v.name {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *File) isDotImport(path string) bool {
|
||||
if id, ok := f.hints[path]; ok {
|
||||
return id.name == "." && id.alias
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *File) register(path string) string {
|
||||
if f.isLocal(path) {
|
||||
// notest
|
||||
// should never get here becasue in Qual the packageToken will be null,
|
||||
// so render will never be called.
|
||||
return ""
|
||||
}
|
||||
|
||||
// if the path has been registered previously, simply return the name
|
||||
def := f.imports[path]
|
||||
if def.name != "" && def.name != "_" {
|
||||
return def.name
|
||||
}
|
||||
|
||||
// special case for "C" pseudo-package
|
||||
if path == "C" {
|
||||
f.imports["C"] = importdef{name: "C", alias: false}
|
||||
return "C"
|
||||
}
|
||||
|
||||
var name string
|
||||
var alias bool
|
||||
|
||||
if hint := f.hints[path]; hint.name != "" {
|
||||
// look up the path in the list of provided package names and aliases by ImportName / ImportAlias
|
||||
name = hint.name
|
||||
alias = hint.alias
|
||||
} else if standardLibraryHints[path] != "" {
|
||||
// look up the path in the list of standard library packages
|
||||
name = standardLibraryHints[path]
|
||||
alias = false
|
||||
} else {
|
||||
// if a hint is not found for the package, guess the alias from the package path
|
||||
name = guessAlias(path)
|
||||
alias = true
|
||||
}
|
||||
|
||||
// If the name is invalid or has been registered already, make it unique by appending a number
|
||||
unique := name
|
||||
i := 0
|
||||
for !f.isValidAlias(unique) {
|
||||
i++
|
||||
unique = fmt.Sprintf("%s%d", name, i)
|
||||
}
|
||||
|
||||
// If we've changed the name to make it unique, it should definitely be an alias
|
||||
if unique != name {
|
||||
alias = true
|
||||
}
|
||||
|
||||
// Only add a prefix if the name is an alias
|
||||
if f.PackagePrefix != "" && alias {
|
||||
unique = f.PackagePrefix + "_" + unique
|
||||
}
|
||||
|
||||
// Register the eventual name
|
||||
f.imports[path] = importdef{name: unique, alias: alias}
|
||||
|
||||
return unique
|
||||
}
|
||||
|
||||
// GoString renders the File for testing. Any error will cause a panic.
|
||||
func (f *File) GoString() string {
|
||||
buf := &bytes.Buffer{}
|
||||
if err := f.Render(buf); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func guessAlias(path string) string {
|
||||
alias := path
|
||||
|
||||
if strings.HasSuffix(alias, "/") {
|
||||
// training slashes are usually tolerated, so we can get rid of one if
|
||||
// it exists
|
||||
alias = alias[:len(alias)-1]
|
||||
}
|
||||
|
||||
if strings.Contains(alias, "/") {
|
||||
// if the path contains a "/", use the last part
|
||||
alias = alias[strings.LastIndex(alias, "/")+1:]
|
||||
}
|
||||
|
||||
// alias should be lower case
|
||||
alias = strings.ToLower(alias)
|
||||
|
||||
// alias should now only contain alphanumerics
|
||||
importsRegex := regexp.MustCompile(`[^a-z0-9]`)
|
||||
alias = importsRegex.ReplaceAllString(alias, "")
|
||||
|
||||
// can't have a first digit, per Go identifier rules, so just skip them
|
||||
for firstRune, runeLen := utf8.DecodeRuneInString(alias); unicode.IsDigit(firstRune); firstRune, runeLen = utf8.DecodeRuneInString(alias) {
|
||||
alias = alias[runeLen:]
|
||||
}
|
||||
|
||||
// If path part was all digits, we may be left with an empty string. In this case use "pkg" as the alias.
|
||||
if alias == "" {
|
||||
alias = "pkg"
|
||||
}
|
||||
|
||||
return alias
|
||||
}
|
2274
vendor/github.com/dave/jennifer/jen/generated.go
generated
vendored
Normal file
2274
vendor/github.com/dave/jennifer/jen/generated.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
147
vendor/github.com/dave/jennifer/jen/group.go
generated
vendored
Normal file
147
vendor/github.com/dave/jennifer/jen/group.go
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Group represents a list of Code items, separated by tokens with an optional
|
||||
// open and close token.
|
||||
type Group struct {
|
||||
name string
|
||||
items []Code
|
||||
open string
|
||||
close string
|
||||
separator string
|
||||
multi bool
|
||||
}
|
||||
|
||||
func (g *Group) isNull(f *File) bool {
|
||||
if g == nil {
|
||||
return true
|
||||
}
|
||||
if g.open != "" || g.close != "" {
|
||||
return false
|
||||
}
|
||||
for _, c := range g.items {
|
||||
if !c.isNull(f) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *Group) render(f *File, w io.Writer, s *Statement) error {
|
||||
if g.name == "block" && s != nil {
|
||||
// Special CaseBlock format for then the previous item in the statement
|
||||
// is a Case group or the default keyword.
|
||||
prev := s.previous(g)
|
||||
grp, isGrp := prev.(*Group)
|
||||
tkn, isTkn := prev.(token)
|
||||
if isGrp && grp.name == "case" || isTkn && tkn.content == "default" {
|
||||
g.open = ""
|
||||
g.close = ""
|
||||
}
|
||||
}
|
||||
if g.open != "" {
|
||||
if _, err := w.Write([]byte(g.open)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
isNull, err := g.renderItems(f, w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isNull && g.multi && g.close != "" {
|
||||
// For multi-line blocks with a closing token, we insert a new line after the last item (but
|
||||
// not if all items were null). This is to ensure that if the statement finishes with a comment,
|
||||
// the closing token is not commented out.
|
||||
s := "\n"
|
||||
if g.separator == "," {
|
||||
// We also insert add trailing comma if the separator was ",".
|
||||
s = ",\n"
|
||||
}
|
||||
if _, err := w.Write([]byte(s)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if g.close != "" {
|
||||
if _, err := w.Write([]byte(g.close)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Group) renderItems(f *File, w io.Writer) (isNull bool, err error) {
|
||||
first := true
|
||||
for _, code := range g.items {
|
||||
if pt, ok := code.(token); ok && pt.typ == packageToken {
|
||||
// Special case for package tokens in Qual groups - for dot-imports, the package token
|
||||
// will be null, so will not render and will not be registered in the imports block.
|
||||
// This ensures all packageTokens that are rendered are registered.
|
||||
f.register(pt.content.(string))
|
||||
}
|
||||
if code == nil || code.isNull(f) {
|
||||
// Null() token produces no output but also
|
||||
// no separator. Empty() token products no
|
||||
// output but adds a separator.
|
||||
continue
|
||||
}
|
||||
if g.name == "values" {
|
||||
if _, ok := code.(Dict); ok && len(g.items) > 1 {
|
||||
panic("Error in Values: if Dict is used, must be one item only")
|
||||
}
|
||||
}
|
||||
if !first && g.separator != "" {
|
||||
// The separator token is added before each non-null item, but not before the first item.
|
||||
if _, err := w.Write([]byte(g.separator)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
if g.multi {
|
||||
// For multi-line blocks, we insert a new line before each non-null item.
|
||||
if _, err := w.Write([]byte("\n")); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
if err := code.render(f, w, nil); err != nil {
|
||||
return false, err
|
||||
}
|
||||
first = false
|
||||
}
|
||||
return first, nil
|
||||
}
|
||||
|
||||
// Render renders the Group to the provided writer.
|
||||
func (g *Group) Render(writer io.Writer) error {
|
||||
return g.RenderWithFile(writer, NewFile(""))
|
||||
}
|
||||
|
||||
// GoString renders the Group for testing. Any error will cause a panic.
|
||||
func (g *Group) GoString() string {
|
||||
buf := bytes.Buffer{}
|
||||
if err := g.Render(&buf); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// RenderWithFile renders the Group to the provided writer, using imports from the provided file.
|
||||
func (g *Group) RenderWithFile(writer io.Writer, file *File) error {
|
||||
buf := &bytes.Buffer{}
|
||||
if err := g.render(file, buf, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error %s while formatting source:\n%s", err, buf.String())
|
||||
}
|
||||
if _, err := writer.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
273
vendor/github.com/dave/jennifer/jen/hints.go
generated
vendored
Normal file
273
vendor/github.com/dave/jennifer/jen/hints.go
generated
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
// This file is generated - do not edit.
|
||||
|
||||
package jen
|
||||
|
||||
// standardLibraryHints contains package name hints
|
||||
var standardLibraryHints = map[string]string{
|
||||
"archive/tar": "tar",
|
||||
"archive/zip": "zip",
|
||||
"bufio": "bufio",
|
||||
"builtin": "builtin",
|
||||
"bytes": "bytes",
|
||||
"cmd/asm/internal/arch": "arch",
|
||||
"cmd/asm/internal/asm": "asm",
|
||||
"cmd/asm/internal/flags": "flags",
|
||||
"cmd/asm/internal/lex": "lex",
|
||||
"cmd/compile/internal/amd64": "amd64",
|
||||
"cmd/compile/internal/arm": "arm",
|
||||
"cmd/compile/internal/arm64": "arm64",
|
||||
"cmd/compile/internal/gc": "gc",
|
||||
"cmd/compile/internal/mips": "mips",
|
||||
"cmd/compile/internal/mips64": "mips64",
|
||||
"cmd/compile/internal/ppc64": "ppc64",
|
||||
"cmd/compile/internal/s390x": "s390x",
|
||||
"cmd/compile/internal/ssa": "ssa",
|
||||
"cmd/compile/internal/syntax": "syntax",
|
||||
"cmd/compile/internal/test": "test",
|
||||
"cmd/compile/internal/types": "types",
|
||||
"cmd/compile/internal/wasm": "wasm",
|
||||
"cmd/compile/internal/x86": "x86",
|
||||
"cmd/go/internal/base": "base",
|
||||
"cmd/go/internal/bug": "bug",
|
||||
"cmd/go/internal/cache": "cache",
|
||||
"cmd/go/internal/cfg": "cfg",
|
||||
"cmd/go/internal/clean": "clean",
|
||||
"cmd/go/internal/cmdflag": "cmdflag",
|
||||
"cmd/go/internal/dirhash": "dirhash",
|
||||
"cmd/go/internal/doc": "doc",
|
||||
"cmd/go/internal/envcmd": "envcmd",
|
||||
"cmd/go/internal/fix": "fix",
|
||||
"cmd/go/internal/fmtcmd": "fmtcmd",
|
||||
"cmd/go/internal/generate": "generate",
|
||||
"cmd/go/internal/get": "get",
|
||||
"cmd/go/internal/help": "help",
|
||||
"cmd/go/internal/imports": "imports",
|
||||
"cmd/go/internal/list": "list",
|
||||
"cmd/go/internal/load": "load",
|
||||
"cmd/go/internal/modcmd": "modcmd",
|
||||
"cmd/go/internal/modconv": "modconv",
|
||||
"cmd/go/internal/modfetch": "modfetch",
|
||||
"cmd/go/internal/modfetch/codehost": "codehost",
|
||||
"cmd/go/internal/modfile": "modfile",
|
||||
"cmd/go/internal/modget": "modget",
|
||||
"cmd/go/internal/modinfo": "modinfo",
|
||||
"cmd/go/internal/modload": "modload",
|
||||
"cmd/go/internal/module": "module",
|
||||
"cmd/go/internal/mvs": "mvs",
|
||||
"cmd/go/internal/par": "par",
|
||||
"cmd/go/internal/run": "run",
|
||||
"cmd/go/internal/search": "search",
|
||||
"cmd/go/internal/semver": "semver",
|
||||
"cmd/go/internal/str": "str",
|
||||
"cmd/go/internal/test": "test",
|
||||
"cmd/go/internal/tool": "tool",
|
||||
"cmd/go/internal/txtar": "txtar",
|
||||
"cmd/go/internal/version": "version",
|
||||
"cmd/go/internal/vet": "vet",
|
||||
"cmd/go/internal/web": "web",
|
||||
"cmd/go/internal/web2": "web2",
|
||||
"cmd/go/internal/webtest": "webtest",
|
||||
"cmd/go/internal/work": "work",
|
||||
"cmd/internal/bio": "bio",
|
||||
"cmd/internal/browser": "browser",
|
||||
"cmd/internal/buildid": "buildid",
|
||||
"cmd/internal/dwarf": "dwarf",
|
||||
"cmd/internal/edit": "edit",
|
||||
"cmd/internal/gcprog": "gcprog",
|
||||
"cmd/internal/goobj": "goobj",
|
||||
"cmd/internal/obj": "obj",
|
||||
"cmd/internal/obj/arm": "arm",
|
||||
"cmd/internal/obj/arm64": "arm64",
|
||||
"cmd/internal/obj/mips": "mips",
|
||||
"cmd/internal/obj/ppc64": "ppc64",
|
||||
"cmd/internal/obj/s390x": "s390x",
|
||||
"cmd/internal/obj/wasm": "wasm",
|
||||
"cmd/internal/obj/x86": "x86",
|
||||
"cmd/internal/objabi": "objabi",
|
||||
"cmd/internal/objfile": "objfile",
|
||||
"cmd/internal/src": "src",
|
||||
"cmd/internal/sys": "sys",
|
||||
"cmd/internal/test2json": "test2json",
|
||||
"cmd/link/internal/amd64": "amd64",
|
||||
"cmd/link/internal/arm": "arm",
|
||||
"cmd/link/internal/arm64": "arm64",
|
||||
"cmd/link/internal/ld": "ld",
|
||||
"cmd/link/internal/loadelf": "loadelf",
|
||||
"cmd/link/internal/loadmacho": "loadmacho",
|
||||
"cmd/link/internal/loadpe": "loadpe",
|
||||
"cmd/link/internal/mips": "mips",
|
||||
"cmd/link/internal/mips64": "mips64",
|
||||
"cmd/link/internal/objfile": "objfile",
|
||||
"cmd/link/internal/ppc64": "ppc64",
|
||||
"cmd/link/internal/s390x": "s390x",
|
||||
"cmd/link/internal/sym": "sym",
|
||||
"cmd/link/internal/wasm": "wasm",
|
||||
"cmd/link/internal/x86": "x86",
|
||||
"cmd/vet/internal/cfg": "cfg",
|
||||
"cmd/vet/internal/whitelist": "whitelist",
|
||||
"compress/bzip2": "bzip2",
|
||||
"compress/flate": "flate",
|
||||
"compress/gzip": "gzip",
|
||||
"compress/lzw": "lzw",
|
||||
"compress/zlib": "zlib",
|
||||
"container/heap": "heap",
|
||||
"container/list": "list",
|
||||
"container/ring": "ring",
|
||||
"context": "context",
|
||||
"crypto": "crypto",
|
||||
"crypto/aes": "aes",
|
||||
"crypto/cipher": "cipher",
|
||||
"crypto/des": "des",
|
||||
"crypto/dsa": "dsa",
|
||||
"crypto/ecdsa": "ecdsa",
|
||||
"crypto/elliptic": "elliptic",
|
||||
"crypto/hmac": "hmac",
|
||||
"crypto/internal/randutil": "randutil",
|
||||
"crypto/internal/subtle": "subtle",
|
||||
"crypto/md5": "md5",
|
||||
"crypto/rand": "rand",
|
||||
"crypto/rc4": "rc4",
|
||||
"crypto/rsa": "rsa",
|
||||
"crypto/sha1": "sha1",
|
||||
"crypto/sha256": "sha256",
|
||||
"crypto/sha512": "sha512",
|
||||
"crypto/subtle": "subtle",
|
||||
"crypto/tls": "tls",
|
||||
"crypto/x509": "x509",
|
||||
"crypto/x509/pkix": "pkix",
|
||||
"database/sql": "sql",
|
||||
"database/sql/driver": "driver",
|
||||
"debug/dwarf": "dwarf",
|
||||
"debug/elf": "elf",
|
||||
"debug/gosym": "gosym",
|
||||
"debug/macho": "macho",
|
||||
"debug/pe": "pe",
|
||||
"debug/plan9obj": "plan9obj",
|
||||
"encoding": "encoding",
|
||||
"encoding/ascii85": "ascii85",
|
||||
"encoding/asn1": "asn1",
|
||||
"encoding/base32": "base32",
|
||||
"encoding/base64": "base64",
|
||||
"encoding/binary": "binary",
|
||||
"encoding/csv": "csv",
|
||||
"encoding/gob": "gob",
|
||||
"encoding/hex": "hex",
|
||||
"encoding/json": "json",
|
||||
"encoding/pem": "pem",
|
||||
"encoding/xml": "xml",
|
||||
"errors": "errors",
|
||||
"expvar": "expvar",
|
||||
"flag": "flag",
|
||||
"fmt": "fmt",
|
||||
"go/ast": "ast",
|
||||
"go/build": "build",
|
||||
"go/constant": "constant",
|
||||
"go/doc": "doc",
|
||||
"go/format": "format",
|
||||
"go/importer": "importer",
|
||||
"go/internal/gccgoimporter": "gccgoimporter",
|
||||
"go/internal/gcimporter": "gcimporter",
|
||||
"go/internal/srcimporter": "srcimporter",
|
||||
"go/parser": "parser",
|
||||
"go/printer": "printer",
|
||||
"go/scanner": "scanner",
|
||||
"go/token": "token",
|
||||
"go/types": "types",
|
||||
"hash": "hash",
|
||||
"hash/adler32": "adler32",
|
||||
"hash/crc32": "crc32",
|
||||
"hash/crc64": "crc64",
|
||||
"hash/fnv": "fnv",
|
||||
"html": "html",
|
||||
"html/template": "template",
|
||||
"image": "image",
|
||||
"image/color": "color",
|
||||
"image/color/palette": "palette",
|
||||
"image/draw": "draw",
|
||||
"image/gif": "gif",
|
||||
"image/internal/imageutil": "imageutil",
|
||||
"image/jpeg": "jpeg",
|
||||
"image/png": "png",
|
||||
"index/suffixarray": "suffixarray",
|
||||
"internal/bytealg": "bytealg",
|
||||
"internal/cpu": "cpu",
|
||||
"internal/nettrace": "nettrace",
|
||||
"internal/poll": "poll",
|
||||
"internal/race": "race",
|
||||
"internal/singleflight": "singleflight",
|
||||
"internal/syscall/unix": "unix",
|
||||
"internal/syscall/windows": "windows",
|
||||
"internal/syscall/windows/registry": "registry",
|
||||
"internal/syscall/windows/sysdll": "sysdll",
|
||||
"internal/testenv": "testenv",
|
||||
"internal/testlog": "testlog",
|
||||
"internal/trace": "trace",
|
||||
"io": "io",
|
||||
"io/ioutil": "ioutil",
|
||||
"log": "log",
|
||||
"log/syslog": "syslog",
|
||||
"math": "math",
|
||||
"math/big": "big",
|
||||
"math/bits": "bits",
|
||||
"math/cmplx": "cmplx",
|
||||
"math/rand": "rand",
|
||||
"mime": "mime",
|
||||
"mime/multipart": "multipart",
|
||||
"mime/quotedprintable": "quotedprintable",
|
||||
"net": "net",
|
||||
"net/http": "http",
|
||||
"net/http/cgi": "cgi",
|
||||
"net/http/cookiejar": "cookiejar",
|
||||
"net/http/fcgi": "fcgi",
|
||||
"net/http/httptest": "httptest",
|
||||
"net/http/httptrace": "httptrace",
|
||||
"net/http/httputil": "httputil",
|
||||
"net/http/internal": "internal",
|
||||
"net/http/pprof": "pprof",
|
||||
"net/internal/socktest": "socktest",
|
||||
"net/mail": "mail",
|
||||
"net/rpc": "rpc",
|
||||
"net/rpc/jsonrpc": "jsonrpc",
|
||||
"net/smtp": "smtp",
|
||||
"net/textproto": "textproto",
|
||||
"net/url": "url",
|
||||
"os": "os",
|
||||
"os/exec": "exec",
|
||||
"os/signal": "signal",
|
||||
"os/signal/internal/pty": "pty",
|
||||
"os/user": "user",
|
||||
"path": "path",
|
||||
"path/filepath": "filepath",
|
||||
"plugin": "plugin",
|
||||
"reflect": "reflect",
|
||||
"regexp": "regexp",
|
||||
"regexp/syntax": "syntax",
|
||||
"runtime": "runtime",
|
||||
"runtime/cgo": "cgo",
|
||||
"runtime/debug": "debug",
|
||||
"runtime/internal/atomic": "atomic",
|
||||
"runtime/internal/sys": "sys",
|
||||
"runtime/pprof": "pprof",
|
||||
"runtime/pprof/internal/profile": "profile",
|
||||
"runtime/race": "race",
|
||||
"runtime/trace": "trace",
|
||||
"sort": "sort",
|
||||
"strconv": "strconv",
|
||||
"strings": "strings",
|
||||
"sync": "sync",
|
||||
"sync/atomic": "atomic",
|
||||
"syscall": "syscall",
|
||||
"testing": "testing",
|
||||
"testing/internal/testdeps": "testdeps",
|
||||
"testing/iotest": "iotest",
|
||||
"testing/quick": "quick",
|
||||
"text/scanner": "scanner",
|
||||
"text/tabwriter": "tabwriter",
|
||||
"text/template": "template",
|
||||
"text/template/parse": "parse",
|
||||
"time": "time",
|
||||
"unicode": "unicode",
|
||||
"unicode/utf16": "utf16",
|
||||
"unicode/utf8": "utf8",
|
||||
"unsafe": "unsafe",
|
||||
}
|
168
vendor/github.com/dave/jennifer/jen/jen.go
generated
vendored
Normal file
168
vendor/github.com/dave/jennifer/jen/jen.go
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
// Package jen is a code generator for Go
|
||||
package jen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Code represents an item of code that can be rendered.
|
||||
type Code interface {
|
||||
render(f *File, w io.Writer, s *Statement) error
|
||||
isNull(f *File) bool
|
||||
}
|
||||
|
||||
// Save renders the file and saves to the filename provided.
|
||||
func (f *File) Save(filename string) error {
|
||||
// notest
|
||||
buf := &bytes.Buffer{}
|
||||
if err := f.Render(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(filename, buf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Render renders the file to the provided writer.
|
||||
func (f *File) Render(w io.Writer) error {
|
||||
body := &bytes.Buffer{}
|
||||
if err := f.render(f, body, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
source := &bytes.Buffer{}
|
||||
if len(f.headers) > 0 {
|
||||
for _, c := range f.headers {
|
||||
if err := Comment(c).render(f, source, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(source, "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Append an extra newline so that header comments don't get lumped in
|
||||
// with package comments.
|
||||
if _, err := fmt.Fprint(source, "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, c := range f.comments {
|
||||
if err := Comment(c).render(f, source, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(source, "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprintf(source, "package %s", f.name); err != nil {
|
||||
return err
|
||||
}
|
||||
if f.CanonicalPath != "" {
|
||||
if _, err := fmt.Fprintf(source, " // import %q", f.CanonicalPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(source, "\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.renderImports(source); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := source.Write(body.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
formatted, err := format.Source(source.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error %s while formatting source:\n%s", err, source.String())
|
||||
}
|
||||
if _, err := w.Write(formatted); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) renderImports(source io.Writer) error {
|
||||
|
||||
// Render the "C" import if it's been used in a `Qual`, `Anon` or if there's a preamble comment
|
||||
hasCgo := f.imports["C"].name != "" || len(f.cgoPreamble) > 0
|
||||
|
||||
// Only separate the import from the main imports block if there's a preamble
|
||||
separateCgo := hasCgo && len(f.cgoPreamble) > 0
|
||||
|
||||
filtered := map[string]importdef{}
|
||||
for path, def := range f.imports {
|
||||
// filter out the "C" pseudo-package so it's not rendered in a block with the other
|
||||
// imports, but only if it is accompanied by a preamble comment
|
||||
if path == "C" && separateCgo {
|
||||
continue
|
||||
}
|
||||
filtered[path] = def
|
||||
}
|
||||
|
||||
if len(filtered) == 1 {
|
||||
for path, def := range filtered {
|
||||
if def.alias && path != "C" {
|
||||
// "C" package should be rendered without alias even when used as an anonymous import
|
||||
// (e.g. should never have an underscore).
|
||||
if _, err := fmt.Fprintf(source, "import %s %s\n\n", def.name, strconv.Quote(path)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprintf(source, "import %s\n\n", strconv.Quote(path)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if len(filtered) > 1 {
|
||||
if _, err := fmt.Fprint(source, "import (\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
// We must sort the imports to ensure repeatable
|
||||
// source.
|
||||
paths := []string{}
|
||||
for path := range filtered {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
sort.Strings(paths)
|
||||
for _, path := range paths {
|
||||
def := filtered[path]
|
||||
if def.alias && path != "C" {
|
||||
// "C" package should be rendered without alias even when used as an anonymous import
|
||||
// (e.g. should never have an underscore).
|
||||
if _, err := fmt.Fprintf(source, "%s %s\n", def.name, strconv.Quote(path)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
if _, err := fmt.Fprintf(source, "%s\n", strconv.Quote(path)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(source, ")\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if separateCgo {
|
||||
for _, c := range f.cgoPreamble {
|
||||
if err := Comment(c).render(f, source, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(source, "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(source, "import \"C\"\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
154
vendor/github.com/dave/jennifer/jen/lit.go
generated
vendored
Normal file
154
vendor/github.com/dave/jennifer/jen/lit.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
package jen
|
||||
|
||||
// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
|
||||
// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
|
||||
// Passing any other type will panic.
|
||||
func Lit(v interface{}) *Statement {
|
||||
return newStatement().Lit(v)
|
||||
}
|
||||
|
||||
// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
|
||||
// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
|
||||
// Passing any other type will panic.
|
||||
func (g *Group) Lit(v interface{}) *Statement {
|
||||
s := Lit(v)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
|
||||
// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
|
||||
// Passing any other type will panic.
|
||||
func (s *Statement) Lit(v interface{}) *Statement {
|
||||
t := token{
|
||||
typ: literalToken,
|
||||
content: v,
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitFunc renders a literal. LitFunc generates the value to render by executing the provided
|
||||
// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32,
|
||||
// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
|
||||
// Returning any other type will panic.
|
||||
func LitFunc(f func() interface{}) *Statement {
|
||||
return newStatement().LitFunc(f)
|
||||
}
|
||||
|
||||
// LitFunc renders a literal. LitFunc generates the value to render by executing the provided
|
||||
// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32,
|
||||
// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
|
||||
// Returning any other type will panic.
|
||||
func (g *Group) LitFunc(f func() interface{}) *Statement {
|
||||
s := LitFunc(f)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitFunc renders a literal. LitFunc generates the value to render by executing the provided
|
||||
// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32,
|
||||
// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
|
||||
// Returning any other type will panic.
|
||||
func (s *Statement) LitFunc(f func() interface{}) *Statement {
|
||||
t := token{
|
||||
typ: literalToken,
|
||||
content: f(),
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitRune renders a rune literal.
|
||||
func LitRune(v rune) *Statement {
|
||||
return newStatement().LitRune(v)
|
||||
}
|
||||
|
||||
// LitRune renders a rune literal.
|
||||
func (g *Group) LitRune(v rune) *Statement {
|
||||
s := LitRune(v)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitRune renders a rune literal.
|
||||
func (s *Statement) LitRune(v rune) *Statement {
|
||||
t := token{
|
||||
typ: literalRuneToken,
|
||||
content: v,
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to
|
||||
// render by executing the provided function.
|
||||
func LitRuneFunc(f func() rune) *Statement {
|
||||
return newStatement().LitRuneFunc(f)
|
||||
}
|
||||
|
||||
// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to
|
||||
// render by executing the provided function.
|
||||
func (g *Group) LitRuneFunc(f func() rune) *Statement {
|
||||
s := LitRuneFunc(f)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to
|
||||
// render by executing the provided function.
|
||||
func (s *Statement) LitRuneFunc(f func() rune) *Statement {
|
||||
t := token{
|
||||
typ: literalRuneToken,
|
||||
content: f(),
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitByte renders a byte literal.
|
||||
func LitByte(v byte) *Statement {
|
||||
return newStatement().LitByte(v)
|
||||
}
|
||||
|
||||
// LitByte renders a byte literal.
|
||||
func (g *Group) LitByte(v byte) *Statement {
|
||||
s := LitByte(v)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitByte renders a byte literal.
|
||||
func (s *Statement) LitByte(v byte) *Statement {
|
||||
t := token{
|
||||
typ: literalByteToken,
|
||||
content: v,
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitByteFunc renders a byte literal. LitByteFunc generates the value to
|
||||
// render by executing the provided function.
|
||||
func LitByteFunc(f func() byte) *Statement {
|
||||
return newStatement().LitByteFunc(f)
|
||||
}
|
||||
|
||||
// LitByteFunc renders a byte literal. LitByteFunc generates the value to
|
||||
// render by executing the provided function.
|
||||
func (g *Group) LitByteFunc(f func() byte) *Statement {
|
||||
s := LitByteFunc(f)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// LitByteFunc renders a byte literal. LitByteFunc generates the value to
|
||||
// render by executing the provided function.
|
||||
func (s *Statement) LitByteFunc(f func() byte) *Statement {
|
||||
t := token{
|
||||
typ: literalByteToken,
|
||||
content: f(),
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
20
vendor/github.com/dave/jennifer/jen/reserved.go
generated
vendored
Normal file
20
vendor/github.com/dave/jennifer/jen/reserved.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
package jen
|
||||
|
||||
var reserved = []string{
|
||||
/* keywords */
|
||||
"break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", "import", "return", "var",
|
||||
/* predeclared */
|
||||
"bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "true", "false", "iota", "nil", "append", "cap", "close", "complex", "copy", "delete", "imag", "len", "make", "new", "panic", "print", "println", "real", "recover",
|
||||
/* common variables */
|
||||
"err",
|
||||
}
|
||||
|
||||
// IsReservedWord returns if this is a reserved word in go
|
||||
func IsReservedWord(alias string) bool {
|
||||
for _, name := range reserved {
|
||||
if alias == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
101
vendor/github.com/dave/jennifer/jen/statement.go
generated
vendored
Normal file
101
vendor/github.com/dave/jennifer/jen/statement.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Statement represents a simple list of code items. When rendered the items
|
||||
// are separated by spaces.
|
||||
type Statement []Code
|
||||
|
||||
func newStatement() *Statement {
|
||||
return &Statement{}
|
||||
}
|
||||
|
||||
// Clone makes a copy of the Statement, so further tokens can be appended
|
||||
// without affecting the original.
|
||||
func (s *Statement) Clone() *Statement {
|
||||
return &Statement{s}
|
||||
}
|
||||
|
||||
func (s *Statement) previous(c Code) Code {
|
||||
index := -1
|
||||
for i, item := range *s {
|
||||
if item == c {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if index > 0 {
|
||||
return (*s)[index-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Statement) isNull(f *File) bool {
|
||||
if s == nil {
|
||||
return true
|
||||
}
|
||||
for _, c := range *s {
|
||||
if !c.isNull(f) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Statement) render(f *File, w io.Writer, _ *Statement) error {
|
||||
first := true
|
||||
for _, code := range *s {
|
||||
if code == nil || code.isNull(f) {
|
||||
// Null() token produces no output but also
|
||||
// no separator. Empty() token products no
|
||||
// output but adds a separator.
|
||||
continue
|
||||
}
|
||||
if !first {
|
||||
if _, err := w.Write([]byte(" ")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := code.render(f, w, s); err != nil {
|
||||
return err
|
||||
}
|
||||
first = false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Render renders the Statement to the provided writer.
|
||||
func (s *Statement) Render(writer io.Writer) error {
|
||||
return s.RenderWithFile(writer, NewFile(""))
|
||||
}
|
||||
|
||||
// GoString renders the Statement for testing. Any error will cause a panic.
|
||||
func (s *Statement) GoString() string {
|
||||
buf := bytes.Buffer{}
|
||||
if err := s.Render(&buf); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// RenderWithFile renders the Statement to the provided writer, using imports from the provided file.
|
||||
func (s *Statement) RenderWithFile(writer io.Writer, file *File) error {
|
||||
buf := &bytes.Buffer{}
|
||||
if err := s.render(file, buf, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error %s while formatting source:\n%s", err, buf.String())
|
||||
}
|
||||
if _, err := writer.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
76
vendor/github.com/dave/jennifer/jen/tag.go
generated
vendored
Normal file
76
vendor/github.com/dave/jennifer/jen/tag.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Tag renders a struct tag
|
||||
func Tag(items map[string]string) *Statement {
|
||||
return newStatement().Tag(items)
|
||||
}
|
||||
|
||||
// Tag renders a struct tag
|
||||
func (g *Group) Tag(items map[string]string) *Statement {
|
||||
// notest
|
||||
// don't think this can ever be used in valid code?
|
||||
s := Tag(items)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Tag renders a struct tag
|
||||
func (s *Statement) Tag(items map[string]string) *Statement {
|
||||
c := tag{
|
||||
items: items,
|
||||
}
|
||||
*s = append(*s, c)
|
||||
return s
|
||||
}
|
||||
|
||||
type tag struct {
|
||||
items map[string]string
|
||||
}
|
||||
|
||||
func (t tag) isNull(f *File) bool {
|
||||
return len(t.items) == 0
|
||||
}
|
||||
|
||||
func (t tag) render(f *File, w io.Writer, s *Statement) error {
|
||||
|
||||
if t.isNull(f) {
|
||||
// notest
|
||||
// render won't be called if t is null
|
||||
return nil
|
||||
}
|
||||
|
||||
var str string
|
||||
|
||||
var sorted []string
|
||||
for k := range t.items {
|
||||
sorted = append(sorted, k)
|
||||
}
|
||||
sort.Strings(sorted)
|
||||
|
||||
for _, k := range sorted {
|
||||
v := t.items[k]
|
||||
if len(str) > 0 {
|
||||
str += " "
|
||||
}
|
||||
str += fmt.Sprintf(`%s:"%s"`, k, v)
|
||||
}
|
||||
|
||||
if strconv.CanBackquote(str) {
|
||||
str = "`" + str + "`"
|
||||
} else {
|
||||
str = strconv.Quote(str)
|
||||
}
|
||||
|
||||
if _, err := w.Write([]byte(str)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
301
vendor/github.com/dave/jennifer/jen/tokens.go
generated
vendored
Normal file
301
vendor/github.com/dave/jennifer/jen/tokens.go
generated
vendored
Normal file
@ -0,0 +1,301 @@
|
||||
package jen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type tokenType string
|
||||
|
||||
const (
|
||||
packageToken tokenType = "package"
|
||||
identifierToken tokenType = "identifier"
|
||||
qualifiedToken tokenType = "qualified"
|
||||
keywordToken tokenType = "keyword"
|
||||
operatorToken tokenType = "operator"
|
||||
delimiterToken tokenType = "delimiter"
|
||||
literalToken tokenType = "literal"
|
||||
literalRuneToken tokenType = "literal_rune"
|
||||
literalByteToken tokenType = "literal_byte"
|
||||
nullToken tokenType = "null"
|
||||
layoutToken tokenType = "layout"
|
||||
)
|
||||
|
||||
type token struct {
|
||||
typ tokenType
|
||||
content interface{}
|
||||
}
|
||||
|
||||
func (t token) isNull(f *File) bool {
|
||||
if t.typ == packageToken {
|
||||
// package token is null if the path is a dot-import or the local package path
|
||||
return f.isDotImport(t.content.(string)) || f.isLocal(t.content.(string))
|
||||
}
|
||||
return t.typ == nullToken
|
||||
}
|
||||
|
||||
func (t token) render(f *File, w io.Writer, s *Statement) error {
|
||||
switch t.typ {
|
||||
case literalToken:
|
||||
var out string
|
||||
switch t.content.(type) {
|
||||
case bool, string, int, complex128:
|
||||
// default constant types can be left bare
|
||||
out = fmt.Sprintf("%#v", t.content)
|
||||
case float64:
|
||||
out = fmt.Sprintf("%#v", t.content)
|
||||
if !strings.Contains(out, ".") && !strings.Contains(out, "e") {
|
||||
// If the formatted value is not in scientific notation, and does not have a dot, then
|
||||
// we add ".0". Otherwise it will be interpreted as an int.
|
||||
// See:
|
||||
// https://github.com/dave/jennifer/issues/39
|
||||
// https://github.com/golang/go/issues/26363
|
||||
out += ".0"
|
||||
}
|
||||
case float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
|
||||
// other built-in types need specific type info
|
||||
out = fmt.Sprintf("%T(%#v)", t.content, t.content)
|
||||
case complex64:
|
||||
// fmt package already renders parenthesis for complex64
|
||||
out = fmt.Sprintf("%T%#v", t.content, t.content)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported type for literal: %T", t.content))
|
||||
}
|
||||
if _, err := w.Write([]byte(out)); err != nil {
|
||||
return err
|
||||
}
|
||||
case literalRuneToken:
|
||||
if _, err := w.Write([]byte(strconv.QuoteRune(t.content.(rune)))); err != nil {
|
||||
return err
|
||||
}
|
||||
case literalByteToken:
|
||||
if _, err := w.Write([]byte(fmt.Sprintf("byte(%#v)", t.content))); err != nil {
|
||||
return err
|
||||
}
|
||||
case keywordToken, operatorToken, layoutToken, delimiterToken:
|
||||
if _, err := w.Write([]byte(fmt.Sprintf("%s", t.content))); err != nil {
|
||||
return err
|
||||
}
|
||||
if t.content.(string) == "default" {
|
||||
// Special case for Default, which must always be followed by a colon
|
||||
if _, err := w.Write([]byte(":")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case packageToken:
|
||||
path := t.content.(string)
|
||||
alias := f.register(path)
|
||||
if _, err := w.Write([]byte(alias)); err != nil {
|
||||
return err
|
||||
}
|
||||
case identifierToken:
|
||||
if _, err := w.Write([]byte(t.content.(string))); err != nil {
|
||||
return err
|
||||
}
|
||||
case nullToken: // notest
|
||||
// do nothing (should never render a null token)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Null adds a null item. Null items render nothing and are not followed by a
|
||||
// separator in lists.
|
||||
func Null() *Statement {
|
||||
return newStatement().Null()
|
||||
}
|
||||
|
||||
// Null adds a null item. Null items render nothing and are not followed by a
|
||||
// separator in lists.
|
||||
func (g *Group) Null() *Statement {
|
||||
s := Null()
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Null adds a null item. Null items render nothing and are not followed by a
|
||||
// separator in lists.
|
||||
func (s *Statement) Null() *Statement {
|
||||
t := token{
|
||||
typ: nullToken,
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// Empty adds an empty item. Empty items render nothing but are followed by a
|
||||
// separator in lists.
|
||||
func Empty() *Statement {
|
||||
return newStatement().Empty()
|
||||
}
|
||||
|
||||
// Empty adds an empty item. Empty items render nothing but are followed by a
|
||||
// separator in lists.
|
||||
func (g *Group) Empty() *Statement {
|
||||
s := Empty()
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Empty adds an empty item. Empty items render nothing but are followed by a
|
||||
// separator in lists.
|
||||
func (s *Statement) Empty() *Statement {
|
||||
t := token{
|
||||
typ: operatorToken,
|
||||
content: "",
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// Op renders the provided operator / token.
|
||||
func Op(op string) *Statement {
|
||||
return newStatement().Op(op)
|
||||
}
|
||||
|
||||
// Op renders the provided operator / token.
|
||||
func (g *Group) Op(op string) *Statement {
|
||||
s := Op(op)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Op renders the provided operator / token.
|
||||
func (s *Statement) Op(op string) *Statement {
|
||||
t := token{
|
||||
typ: operatorToken,
|
||||
content: op,
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// Dot renders a period followed by an identifier. Use for fields and selectors.
|
||||
func Dot(name string) *Statement {
|
||||
// notest
|
||||
// don't think this can be used in valid code?
|
||||
return newStatement().Dot(name)
|
||||
}
|
||||
|
||||
// Dot renders a period followed by an identifier. Use for fields and selectors.
|
||||
func (g *Group) Dot(name string) *Statement {
|
||||
// notest
|
||||
// don't think this can be used in valid code?
|
||||
s := Dot(name)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Dot renders a period followed by an identifier. Use for fields and selectors.
|
||||
func (s *Statement) Dot(name string) *Statement {
|
||||
d := token{
|
||||
typ: delimiterToken,
|
||||
content: ".",
|
||||
}
|
||||
t := token{
|
||||
typ: identifierToken,
|
||||
content: name,
|
||||
}
|
||||
*s = append(*s, d, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// Id renders an identifier.
|
||||
func Id(name string) *Statement {
|
||||
return newStatement().Id(name)
|
||||
}
|
||||
|
||||
// Id renders an identifier.
|
||||
func (g *Group) Id(name string) *Statement {
|
||||
s := Id(name)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Id renders an identifier.
|
||||
func (s *Statement) Id(name string) *Statement {
|
||||
t := token{
|
||||
typ: identifierToken,
|
||||
content: name,
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
||||
|
||||
// Qual renders a qualified identifier. Imports are automatically added when
|
||||
// used with a File. If the path matches the local path, the package name is
|
||||
// omitted. If package names conflict they are automatically renamed. Note that
|
||||
// it is not possible to reliably determine the package name given an arbitrary
|
||||
// package path, so a sensible name is guessed from the path and added as an
|
||||
// alias. The names of all standard library packages are known so these do not
|
||||
// need to be aliased. If more control is needed of the aliases, see
|
||||
// [File.ImportName](#importname) or [File.ImportAlias](#importalias).
|
||||
func Qual(path, name string) *Statement {
|
||||
return newStatement().Qual(path, name)
|
||||
}
|
||||
|
||||
// Qual renders a qualified identifier. Imports are automatically added when
|
||||
// used with a File. If the path matches the local path, the package name is
|
||||
// omitted. If package names conflict they are automatically renamed. Note that
|
||||
// it is not possible to reliably determine the package name given an arbitrary
|
||||
// package path, so a sensible name is guessed from the path and added as an
|
||||
// alias. The names of all standard library packages are known so these do not
|
||||
// need to be aliased. If more control is needed of the aliases, see
|
||||
// [File.ImportName](#importname) or [File.ImportAlias](#importalias).
|
||||
func (g *Group) Qual(path, name string) *Statement {
|
||||
s := Qual(path, name)
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Qual renders a qualified identifier. Imports are automatically added when
|
||||
// used with a File. If the path matches the local path, the package name is
|
||||
// omitted. If package names conflict they are automatically renamed. Note that
|
||||
// it is not possible to reliably determine the package name given an arbitrary
|
||||
// package path, so a sensible name is guessed from the path and added as an
|
||||
// alias. The names of all standard library packages are known so these do not
|
||||
// need to be aliased. If more control is needed of the aliases, see
|
||||
// [File.ImportName](#importname) or [File.ImportAlias](#importalias).
|
||||
func (s *Statement) Qual(path, name string) *Statement {
|
||||
g := &Group{
|
||||
close: "",
|
||||
items: []Code{
|
||||
token{
|
||||
typ: packageToken,
|
||||
content: path,
|
||||
},
|
||||
token{
|
||||
typ: identifierToken,
|
||||
content: name,
|
||||
},
|
||||
},
|
||||
name: "qual",
|
||||
open: "",
|
||||
separator: ".",
|
||||
}
|
||||
*s = append(*s, g)
|
||||
return s
|
||||
}
|
||||
|
||||
// Line inserts a blank line.
|
||||
func Line() *Statement {
|
||||
return newStatement().Line()
|
||||
}
|
||||
|
||||
// Line inserts a blank line.
|
||||
func (g *Group) Line() *Statement {
|
||||
s := Line()
|
||||
g.items = append(g.items, s)
|
||||
return s
|
||||
}
|
||||
|
||||
// Line inserts a blank line.
|
||||
func (s *Statement) Line() *Statement {
|
||||
t := token{
|
||||
typ: layoutToken,
|
||||
content: "\n",
|
||||
}
|
||||
*s = append(*s, t)
|
||||
return s
|
||||
}
|
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
@ -2,7 +2,7 @@ ISC License
|
||||
|
||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
|
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
@ -16,7 +16,9 @@
|
||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build !js,!appengine,!safe,!disableunsafe
|
||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||
|
||||
package spew
|
||||
|
||||
@ -34,80 +36,49 @@ const (
|
||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||
)
|
||||
|
||||
var (
|
||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
||||
// internal reflect.Value fields. These values are valid before golang
|
||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
||||
// the original format. Code in the init function updates these offsets
|
||||
// as necessary.
|
||||
offsetPtr = uintptr(ptrSize)
|
||||
offsetScalar = uintptr(0)
|
||||
offsetFlag = uintptr(ptrSize * 2)
|
||||
type flag uintptr
|
||||
|
||||
// flagKindWidth and flagKindShift indicate various bits that the
|
||||
// reflect package uses internally to track kind information.
|
||||
//
|
||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
||||
// read-only.
|
||||
//
|
||||
// flagIndir indicates whether the value field of a reflect.Value is
|
||||
// the actual data or a pointer to the data.
|
||||
//
|
||||
// These values are valid before golang commit 90a7c3c86944 which
|
||||
// changed their positions. Code in the init function updates these
|
||||
// flags as necessary.
|
||||
flagKindWidth = uintptr(5)
|
||||
flagKindShift = uintptr(flagKindWidth - 1)
|
||||
flagRO = uintptr(1 << 0)
|
||||
flagIndir = uintptr(1 << 1)
|
||||
var (
|
||||
// flagRO indicates whether the value field of a reflect.Value
|
||||
// is read-only.
|
||||
flagRO flag
|
||||
|
||||
// flagAddr indicates whether the address of the reflect.Value's
|
||||
// value may be taken.
|
||||
flagAddr flag
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Older versions of reflect.Value stored small integers directly in the
|
||||
// ptr field (which is named val in the older versions). Versions
|
||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
||||
// scalar for this purpose which unfortunately came before the flag
|
||||
// field, so the offset of the flag field is different for those
|
||||
// versions.
|
||||
//
|
||||
// This code constructs a new reflect.Value from a known small integer
|
||||
// and checks if the size of the reflect.Value struct indicates it has
|
||||
// the scalar field. When it does, the offsets are updated accordingly.
|
||||
vv := reflect.ValueOf(0xf00)
|
||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
||||
offsetScalar = ptrSize * 2
|
||||
offsetFlag = ptrSize * 3
|
||||
}
|
||||
// flagKindMask holds the bits that make up the kind
|
||||
// part of the flags field. In all the supported versions,
|
||||
// it is in the lower 5 bits.
|
||||
const flagKindMask = flag(0x1f)
|
||||
|
||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
||||
// order bits are the kind. This code extracts the kind from the flags
|
||||
// field and ensures it's the correct type. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are updated
|
||||
// accordingly.
|
||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
||||
upfv := *(*uintptr)(upf)
|
||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
||||
flagKindShift = 0
|
||||
flagRO = 1 << 5
|
||||
flagIndir = 1 << 6
|
||||
// Different versions of Go have used different
|
||||
// bit layouts for the flags type. This table
|
||||
// records the known combinations.
|
||||
var okFlags = []struct {
|
||||
ro, addr flag
|
||||
}{{
|
||||
// From Go 1.4 to 1.5
|
||||
ro: 1 << 5,
|
||||
addr: 1 << 7,
|
||||
}, {
|
||||
// Up to Go tip.
|
||||
ro: 1<<5 | 1<<6,
|
||||
addr: 1 << 8,
|
||||
}}
|
||||
|
||||
// Commit adf9b30e5594 modified the flags to separate the
|
||||
// flagRO flag into two bits which specifies whether or not the
|
||||
// field is embedded. This causes flagIndir to move over a bit
|
||||
// and means that flagRO is the combination of either of the
|
||||
// original flagRO bit and the new bit.
|
||||
//
|
||||
// This code detects the change by extracting what used to be
|
||||
// the indirect bit to ensure it's set. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are
|
||||
// updated accordingly.
|
||||
if upfv&flagIndir == 0 {
|
||||
flagRO = 3 << 5
|
||||
flagIndir = 1 << 7
|
||||
}
|
||||
var flagValOffset = func() uintptr {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
return field.Offset
|
||||
}()
|
||||
|
||||
// flagField returns a pointer to the flag field of a reflect.Value.
|
||||
func flagField(v *reflect.Value) *flag {
|
||||
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
||||
}
|
||||
|
||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||
@ -119,34 +90,56 @@ func init() {
|
||||
// This allows us to check for implementations of the Stringer and error
|
||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||
// inaccessible values such as unexported struct fields.
|
||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||
indirects := 1
|
||||
vt := v.Type()
|
||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||
if rvf&flagIndir != 0 {
|
||||
vt = reflect.PtrTo(v.Type())
|
||||
indirects++
|
||||
} else if offsetScalar != 0 {
|
||||
// The value is in the scalar field when it's not one of the
|
||||
// reference types.
|
||||
switch vt.Kind() {
|
||||
case reflect.Uintptr:
|
||||
case reflect.Chan:
|
||||
case reflect.Func:
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.UnsafePointer:
|
||||
default:
|
||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
||||
offsetScalar)
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
||||
return v
|
||||
}
|
||||
flagFieldPtr := flagField(&v)
|
||||
*flagFieldPtr &^= flagRO
|
||||
*flagFieldPtr |= flagAddr
|
||||
return v
|
||||
}
|
||||
|
||||
// Sanity checks against future reflect package changes
|
||||
// to the type or semantics of the Value.flag field.
|
||||
func init() {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
||||
panic("reflect.Value flag field has changed kind")
|
||||
}
|
||||
type t0 int
|
||||
var t struct {
|
||||
A t0
|
||||
// t0 will have flagEmbedRO set.
|
||||
t0
|
||||
// a will have flagStickyRO set
|
||||
a t0
|
||||
}
|
||||
vA := reflect.ValueOf(t).FieldByName("A")
|
||||
va := reflect.ValueOf(t).FieldByName("a")
|
||||
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
||||
|
||||
// Infer flagRO from the difference between the flags
|
||||
// for the (otherwise identical) fields in t.
|
||||
flagPublic := *flagField(&vA)
|
||||
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
||||
flagRO = flagPublic ^ flagWithRO
|
||||
|
||||
// Infer flagAddr from the difference between a value
|
||||
// taken from a pointer and not.
|
||||
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
||||
flagNoPtr := *flagField(&vA)
|
||||
flagPtr := *flagField(&vPtrA)
|
||||
flagAddr = flagNoPtr ^ flagPtr
|
||||
|
||||
// Check that the inferred flags tally with one of the known versions.
|
||||
for _, f := range okFlags {
|
||||
if flagRO == f.ro && flagAddr == f.addr {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pv := reflect.NewAt(vt, upv)
|
||||
rv = pv
|
||||
for i := 0; i < indirects; i++ {
|
||||
rv = rv.Elem()
|
||||
}
|
||||
return rv
|
||||
panic("reflect.Value read-only flag has changed semantics")
|
||||
}
|
||||
|
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
@ -16,7 +16,7 @@
|
||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build js appengine safe disableunsafe
|
||||
// +build js appengine safe disableunsafe !go1.4
|
||||
|
||||
package spew
|
||||
|
||||
|
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
||||
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
||||
// prefix to Writer w.
|
||||
func printHexPtr(w io.Writer, p uintptr) {
|
||||
// Null pointer.
|
||||
|
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
@ -35,16 +35,16 @@ var (
|
||||
|
||||
// cCharRE is a regular expression that matches a cgo char.
|
||||
// It is used to detect character arrays to hexdump them.
|
||||
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
||||
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
||||
|
||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||
// char. It is used to detect unsigned character arrays to hexdump
|
||||
// them.
|
||||
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
||||
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
||||
|
||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||
// It is used to detect uint8_t arrays to hexdump them.
|
||||
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
||||
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
||||
)
|
||||
|
||||
// dumpState contains information about the state of a dump operation.
|
||||
@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
|
||||
// Display dereferenced value.
|
||||
d.w.Write(openParenBytes)
|
||||
switch {
|
||||
case nilFound == true:
|
||||
case nilFound:
|
||||
d.w.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
case cycleFound:
|
||||
d.w.Write(circularBytes)
|
||||
|
||||
default:
|
||||
|
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) {
|
||||
|
||||
// Display dereferenced value.
|
||||
switch {
|
||||
case nilFound == true:
|
||||
case nilFound:
|
||||
f.fs.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
case cycleFound:
|
||||
f.fs.Write(circularShortBytes)
|
||||
|
||||
default:
|
||||
|
20
vendor/github.com/gookit/color/.gitignore
generated
vendored
Normal file
20
vendor/github.com/gookit/color/.gitignore
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
*.log
|
||||
*.swp
|
||||
.idea
|
||||
*.patch
|
||||
### Go template
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
.DS_Store
|
||||
app
|
||||
demo
|
20
vendor/github.com/gookit/color/LICENSE
generated
vendored
Normal file
20
vendor/github.com/gookit/color/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 inhere
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
462
vendor/github.com/gookit/color/README.md
generated
vendored
Normal file
462
vendor/github.com/gookit/color/README.md
generated
vendored
Normal file
@ -0,0 +1,462 @@
|
||||
# CLI Color
|
||||
|
||||

|
||||
[](https://github.com/gookit/color/actions)
|
||||
[](https://app.codacy.com/app/inhere/color)
|
||||
[](https://pkg.go.dev/github.com/gookit/color?tab=overview)
|
||||
[](https://github.com/gookit/color)
|
||||
[](https://travis-ci.org/gookit/color)
|
||||
[](https://coveralls.io/github/gookit/color?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/gookit/color)
|
||||
|
||||
A command-line color library with true color support, universal API methods and Windows support.
|
||||
|
||||
> **[中文说明](README.zh-CN.md)**
|
||||
|
||||
Basic color preview:
|
||||
|
||||

|
||||
|
||||
Now, 256 colors and RGB colors have also been supported to work in Windows CMD and PowerShell:
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Simple to use, zero dependencies
|
||||
- Supports rich color output: 16-color (4-bit), 256-color (8-bit), true color (24-bit, RGB)
|
||||
- 16-color output is the most commonly used and most widely supported, working on any Windows version
|
||||
- Since `v1.2.4` **the 256-color (8-bit), true color (24-bit) support windows CMD and PowerShell**
|
||||
- See [this gist](https://gist.github.com/XVilka/8346728) for information on true color support
|
||||
- Generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf`
|
||||
- Supports HTML tag-style color rendering, such as `<green>message</>`. Support working on windows `cmd` `powerShell`
|
||||
- Basic colors: `Bold`, `Black`, `White`, `Gray`, `Red`, `Green`, `Yellow`, `Blue`, `Magenta`, `Cyan`
|
||||
- Additional styles: `Info`, `Note`, `Light`, `Error`, `Danger`, `Notice`, `Success`, `Comment`, `Primary`, `Warning`, `Question`, `Secondary`
|
||||
|
||||
## GoDoc
|
||||
|
||||
- [godoc for gopkg](https://pkg.go.dev/gopkg.in/gookit/color.v1)
|
||||
- [godoc for github](https://pkg.go.dev/github.com/gookit/color)
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get github.com/gookit/color
|
||||
```
|
||||
|
||||
### NOTICE
|
||||
|
||||
If you want print custom colors message on windows, should use `color.PrintX` instead of `fmt.PrintX`
|
||||
|
||||
```go
|
||||
str := color.Red.Sprint("an colored message string")
|
||||
|
||||
// Color will not be output under Windows
|
||||
fmt.Println(str)
|
||||
|
||||
// Color will be output under Windows
|
||||
color.Println(str)
|
||||
```
|
||||
|
||||
> `color.PrintX` is universal, you can use it directly instead of `fmt.PrintX`
|
||||
|
||||
## Quick start
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gookit/color"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// quick use like fmt.Print*
|
||||
color.Red.Println("Simple to use color")
|
||||
color.Green.Print("Simple to use color\n")
|
||||
color.Cyan.Printf("Simple to use %s\n", "color")
|
||||
color.Yellow.Printf("Simple to use %s\n", "color")
|
||||
|
||||
// use like func
|
||||
red := color.FgRed.Render
|
||||
green := color.FgGreen.Render
|
||||
fmt.Printf("%s line %s library\n", red("Command"), green("color"))
|
||||
|
||||
// custom color
|
||||
color.New(color.FgWhite, color.BgBlack).Println("custom color style")
|
||||
|
||||
// can also:
|
||||
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
|
||||
|
||||
// internal theme/style:
|
||||
color.Info.Tips("message")
|
||||
color.Info.Prompt("message")
|
||||
color.Info.Println("message")
|
||||
color.Warn.Println("message")
|
||||
color.Error.Println("message")
|
||||
|
||||
// use style tag
|
||||
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n")
|
||||
|
||||
// apply a style tag
|
||||
color.Tag("info").Println("info style text")
|
||||
|
||||
// prompt message
|
||||
color.Info.Prompt("prompt style message")
|
||||
color.Warn.Prompt("prompt style message")
|
||||
|
||||
// tips message
|
||||
color.Info.Tips("tips style message")
|
||||
color.Warn.Tips("tips style message")
|
||||
}
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/demo.go`
|
||||
|
||||

|
||||
|
||||
## Custom Build Color
|
||||
|
||||
```go
|
||||
// Only use foreground color
|
||||
color.FgCyan.Printf("Simple to use %s\n", "color")
|
||||
// Only use background color
|
||||
color.BgRed.Printf("Simple to use %s\n", "color")
|
||||
|
||||
// Full custom: foreground, background, option
|
||||
myStyle := color.New(color.FgWhite, color.BgBlack, color.OpBold)
|
||||
myStyle.Println("custom color style")
|
||||
|
||||
// can also:
|
||||
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
|
||||
```
|
||||
|
||||
custom set console settings:
|
||||
|
||||
```go
|
||||
// set console color
|
||||
color.Set(color.FgCyan)
|
||||
|
||||
// print message
|
||||
fmt.Print("message")
|
||||
|
||||
// reset console settings
|
||||
color.Reset()
|
||||
```
|
||||
|
||||
## Basic Color
|
||||
|
||||
Supported on any Windows version.
|
||||
|
||||
- `color.Bold`
|
||||
- `color.Black`
|
||||
- `color.White`
|
||||
- `color.Gray`
|
||||
- `color.Red`
|
||||
- `color.Green`
|
||||
- `color.Yellow`
|
||||
- `color.Blue`
|
||||
- `color.Magenta`
|
||||
- `color.Cyan`
|
||||
|
||||
```go
|
||||
color.Bold.Println("bold message")
|
||||
color.Yellow.Println("yellow message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/basiccolor.go`
|
||||
|
||||

|
||||
|
||||
## Additional styles
|
||||
|
||||
Supported on any Windows version.
|
||||
|
||||
- `color.Info`
|
||||
- `color.Note`
|
||||
- `color.Warn`
|
||||
- `color.Light`
|
||||
- `color.Error`
|
||||
- `color.Danger`
|
||||
- `color.Debug`
|
||||
- `color.Notice`
|
||||
- `color.Success`
|
||||
- `color.Comment`
|
||||
- `color.Primary`
|
||||
- `color.Question`
|
||||
- `color.Secondary`
|
||||
|
||||
### Basic Style
|
||||
|
||||
print message use defined style:
|
||||
|
||||
```go
|
||||
color.Info.Println("Info message")
|
||||
color.Note.Println("Note message")
|
||||
color.Notice.Println("Notice message")
|
||||
color.Error.Println("Error message")
|
||||
color.Danger.Println("Danger message")
|
||||
color.Warn.Println("Warn message")
|
||||
color.Debug.Println("Debug message")
|
||||
color.Primary.Println("Primary message")
|
||||
color.Question.Println("Question message")
|
||||
color.Secondary.Println("Secondary message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_basic.go`
|
||||
|
||||

|
||||
|
||||
### Tips Style
|
||||
|
||||
```go
|
||||
color.Info.Tips("Info tips message")
|
||||
color.Note.Tips("Note tips message")
|
||||
color.Notice.Tips("Notice tips message")
|
||||
color.Error.Tips("Error tips message")
|
||||
color.Danger.Tips("Danger tips message")
|
||||
color.Warn.Tips("Warn tips message")
|
||||
color.Debug.Tips("Debug tips message")
|
||||
color.Primary.Tips("Primary tips message")
|
||||
color.Question.Tips("Question tips message")
|
||||
color.Secondary.Tips("Secondary tips message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_tips.go`
|
||||
|
||||

|
||||
|
||||
### Prompt Style
|
||||
|
||||
```go
|
||||
color.Info.Prompt("Info prompt message")
|
||||
color.Note.Prompt("Note prompt message")
|
||||
color.Notice.Prompt("Notice prompt message")
|
||||
color.Error.Prompt("Error prompt message")
|
||||
color.Danger.Prompt("Danger prompt message")
|
||||
color.Warn.Prompt("Warn prompt message")
|
||||
color.Debug.Prompt("Debug prompt message")
|
||||
color.Primary.Prompt("Primary prompt message")
|
||||
color.Question.Prompt("Question prompt message")
|
||||
color.Secondary.Prompt("Secondary prompt message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_prompt.go`
|
||||
|
||||

|
||||
|
||||
### Block Style
|
||||
|
||||
```go
|
||||
color.Info.Block("Info block message")
|
||||
color.Note.Block("Note block message")
|
||||
color.Notice.Block("Notice block message")
|
||||
color.Error.Block("Error block message")
|
||||
color.Danger.Block("Danger block message")
|
||||
color.Warn.Block("Warn block message")
|
||||
color.Debug.Block("Debug block message")
|
||||
color.Primary.Block("Primary block message")
|
||||
color.Question.Block("Question block message")
|
||||
color.Secondary.Block("Secondary block message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_block.go`
|
||||
|
||||

|
||||
|
||||
## HTML-like tag usage
|
||||
|
||||
**Supported** on Windows `cmd.exe` `PowerShell` .
|
||||
|
||||
```go
|
||||
// use style tag
|
||||
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>")
|
||||
color.Println("<suc>hello</>")
|
||||
color.Println("<error>hello</>")
|
||||
color.Println("<warning>hello</>")
|
||||
|
||||
// custom color attributes
|
||||
color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n")
|
||||
```
|
||||
|
||||
- `color.Tag`
|
||||
|
||||
```go
|
||||
// set a style tag
|
||||
color.Tag("info").Print("info style text")
|
||||
color.Tag("info").Printf("%s style text", "info")
|
||||
color.Tag("info").Println("info style text")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/colortag.go`
|
||||
|
||||

|
||||
|
||||
## 256-color usage
|
||||
|
||||
> 256 colors support Windows CMD, PowerShell environment after `v1.2.4`
|
||||
|
||||
### Set the foreground or background color
|
||||
|
||||
- `color.C256(val uint8, isBg ...bool) Color256`
|
||||
|
||||
```go
|
||||
c := color.C256(132) // fg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
|
||||
c := color.C256(132, true) // bg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
### Use a 256-color style
|
||||
|
||||
Can be used to set foreground and background colors at the same time.
|
||||
|
||||
- `S256(fgAndBg ...uint8) *Style256`
|
||||
|
||||
```go
|
||||
s := color.S256(32, 203)
|
||||
s.Println("message")
|
||||
s.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
with options:
|
||||
|
||||
```go
|
||||
s := color.S256(32, 203)
|
||||
s.SetOpts(color.Opts{color.OpBold})
|
||||
|
||||
s.Println("style with options")
|
||||
s.Printf("style with %s\n", "options")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/color256.go`
|
||||
|
||||

|
||||
|
||||
## Use RGB color
|
||||
|
||||
> RGB colors support Windows `CMD`, `PowerShell` environment after `v1.2.4`
|
||||
|
||||
**Preview:**
|
||||
|
||||
> Run demo: `Run demo: go run ./_examples/color_rgb.go`
|
||||
|
||||

|
||||
|
||||
example:
|
||||
|
||||
```go
|
||||
color.RGB(30, 144, 255).Println("message. use RGB number")
|
||||
|
||||
color.HEX("#1976D2").Println("blue-darken")
|
||||
color.HEX("#D50000", true).Println("red-accent. use HEX style")
|
||||
|
||||
color.RGBStyleFromString("213,0,0").Println("red-accent. use RGB number")
|
||||
color.HEXStyle("eee", "D50000").Println("deep-purple color")
|
||||
```
|
||||
|
||||
### Set the foreground or background color
|
||||
|
||||
- `color.RGB(r, g, b uint8, isBg ...bool) RGBColor`
|
||||
|
||||
```go
|
||||
c := color.RGB(30,144,255) // fg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
|
||||
c := color.RGB(30,144,255, true) // bg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
Create a style from an hexadecimal color string:
|
||||
|
||||
- `color.HEX(hex string, isBg ...bool) RGBColor`
|
||||
|
||||
```go
|
||||
c := color.HEX("ccc") // can also: "cccccc" "#cccccc"
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
|
||||
c = color.HEX("aabbcc", true) // as bg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
### Use an RGB color style
|
||||
|
||||
Can be used to set the foreground and background colors at the same time.
|
||||
|
||||
- `color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle`
|
||||
|
||||
```go
|
||||
s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23))
|
||||
s.Println("message")
|
||||
s.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
Create a style from an hexadecimal color string:
|
||||
|
||||
- `color.HEXStyle(fg string, bg ...string) *RGBStyle`
|
||||
|
||||
```go
|
||||
s := color.HEXStyle("11aa23", "eee")
|
||||
s.Println("message")
|
||||
s.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
with options:
|
||||
|
||||
```go
|
||||
s := color.HEXStyle("11aa23", "eee")
|
||||
s.SetOpts(color.Opts{color.OpBold})
|
||||
|
||||
s.Println("style with options")
|
||||
s.Printf("style with %s\n", "options")
|
||||
```
|
||||
|
||||
## Func refer
|
||||
|
||||
there are some useful functions reference
|
||||
|
||||
- `Disable()` disable color render
|
||||
- `SetOutput(io.Writer)` custom set the colored text output writer
|
||||
- `ForceOpenColor()` force open color render
|
||||
- `Colors2code(colors ...Color) string` Convert colors to code. return like "32;45;3"
|
||||
- `ClearCode(str string) string` Use for clear color codes
|
||||
- `ClearTag(s string) string` clear all color html-tag for a string
|
||||
- `IsConsole(w io.Writer)` Determine whether w is one of stderr, stdout, stdin
|
||||
- `HexToRgb(hex string) (rgb []int)` Convert hex color string to RGB numbers
|
||||
- `RgbToHex(rgb []int) string` Convert RGB to hex code
|
||||
|
||||
## Gookit packages
|
||||
|
||||
- [gookit/ini](https://github.com/gookit/ini) Go config management, use INI files
|
||||
- [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP
|
||||
- [gookit/gcli](https://github.com/gookit/gcli) build CLI application, tool library, running CLI commands
|
||||
- [gookit/slog](https://github.com/gookit/slog) Concise and extensible go log library
|
||||
- [gookit/event](https://github.com/gookit/event) Lightweight event manager and dispatcher implements by Go
|
||||
- [gookit/cache](https://github.com/gookit/cache) Generic cache use and cache manager for golang. support File, Memory, Redis, Memcached.
|
||||
- [gookit/config](https://github.com/gookit/config) Go config management. support JSON, YAML, TOML, INI, HCL, ENV and Flags
|
||||
- [gookit/color](https://github.com/gookit/color) A command-line color library with true color support, universal API methods and Windows support
|
||||
- [gookit/filter](https://github.com/gookit/filter) Provide filtering, sanitizing, and conversion of golang data
|
||||
- [gookit/validate](https://github.com/gookit/validate) Use for data validation and filtering. support Map, Struct, Form data
|
||||
- [gookit/goutil](https://github.com/gookit/goutil) Some utils for the Go: string, array/slice, map, format, cli, env, filesystem, test and more
|
||||
- More, please see https://github.com/gookit
|
||||
|
||||
## See also
|
||||
|
||||
- [inhere/console](https://github.com/inhere/php-console)
|
||||
- [xo/terminfo](https://github.com/xo/terminfo)
|
||||
- [beego/bee](https://github.com/beego/bee)
|
||||
- [issue9/term](https://github.com/issue9/term)
|
||||
- [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
- [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](/LICENSE)
|
432
vendor/github.com/gookit/color/README.zh-CN.md
generated
vendored
Normal file
432
vendor/github.com/gookit/color/README.zh-CN.md
generated
vendored
Normal file
@ -0,0 +1,432 @@
|
||||
# CLI Color
|
||||
|
||||

|
||||
[](https://github.com/gookit/color/actions)
|
||||
[](https://app.codacy.com/app/inhere/color)
|
||||
[](https://pkg.go.dev/github.com/gookit/color?tab=overview)
|
||||
[](https://github.com/gookit/color)
|
||||
[](https://travis-ci.org/gookit/color)
|
||||
[](https://coveralls.io/github/gookit/color?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/gookit/color)
|
||||
|
||||
Golang下的命令行色彩使用库, 拥有丰富的色彩渲染输出,通用的API方法,兼容Windows系统
|
||||
|
||||
> **[EN README](README.md)**
|
||||
|
||||
基本颜色预览:
|
||||
|
||||

|
||||
|
||||
现在,256色和RGB色彩也已经支持windows CMD和PowerShell中工作:
|
||||
|
||||

|
||||
|
||||
## 功能特色
|
||||
|
||||
- 使用简单方便,无其他依赖
|
||||
- 支持丰富的颜色输出, 16色(4bit),256色(8bit),RGB色彩(24bit, RGB)
|
||||
- 16色(4bit)是最常用和支持最广的,支持Windows `cmd.exe`
|
||||
- 自 `v1.2.4` 起 **256色(8bit),RGB色彩(24bit)均支持windows CMD和PowerShell终端**
|
||||
- 请查看 [this gist](https://gist.github.com/XVilka/8346728) 了解支持RGB色彩的终端
|
||||
- 通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf`
|
||||
- 同时支持html标签式的颜色渲染. eg: `<green>message</>`
|
||||
- 基础色彩: `Bold` `Black` `White` `Gray` `Red` `Green` `Yellow` `Blue` `Magenta` `Cyan`
|
||||
- 扩展风格: `Info` `Note` `Light` `Error` `Danger` `Notice` `Success` `Comment` `Primary` `Warning` `Question` `Secondary`
|
||||
- 支持Linux、Mac同时兼容Windows系统环境
|
||||
|
||||
## GoDoc
|
||||
|
||||
- [godoc for gopkg](https://pkg.go.dev/gopkg.in/gookit/color.v1)
|
||||
- [godoc for github](https://pkg.go.dev/github.com/gookit/color)
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
go get github.com/gookit/color
|
||||
```
|
||||
|
||||
### 提示
|
||||
|
||||
如果要在Windows上打印颜色消息,应使用 `color.PrintX` 而不是 `fmt.PrintX`
|
||||
|
||||
```go
|
||||
str := color.Red.Sprint("an colored message string")
|
||||
|
||||
// Windows 下将不会输出颜色
|
||||
fmt.Println(str)
|
||||
|
||||
// Windows 也可以输出色彩
|
||||
color.Println(str)
|
||||
```
|
||||
|
||||
> `color.PrintX` 系列方法是通用的,您可以直接使用它们替代 `fmt.PrintX` 方法
|
||||
|
||||
## 快速开始
|
||||
|
||||
如下,引入当前包就可以快速的使用
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gookit/color"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 简单快速的使用,跟 fmt.Print* 类似
|
||||
color.Red.Println("Simple to use color")
|
||||
color.Green.Print("Simple to use color\n")
|
||||
color.Cyan.Printf("Simple to use %s\n", "color")
|
||||
color.Yellow.Printf("Simple to use %s\n", "color")
|
||||
|
||||
// use like func
|
||||
red := color.FgRed.Render
|
||||
green := color.FgGreen.Render
|
||||
fmt.Printf("%s line %s library\n", red("Command"), green("color"))
|
||||
|
||||
// 自定义颜色
|
||||
color.New(color.FgWhite, color.BgBlack).Println("custom color style")
|
||||
|
||||
// 也可以:
|
||||
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
|
||||
|
||||
// internal style:
|
||||
color.Info.Println("message")
|
||||
color.Warn.Println("message")
|
||||
color.Error.Println("message")
|
||||
|
||||
// 使用颜色标签
|
||||
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n")
|
||||
|
||||
// apply a style tag
|
||||
color.Tag("info").Println("info style text")
|
||||
|
||||
// prompt message
|
||||
color.Info.Prompt("prompt style message")
|
||||
color.Warn.Prompt("prompt style message")
|
||||
|
||||
// tips message
|
||||
color.Info.Tips("tips style message")
|
||||
color.Warn.Tips("tips style message")
|
||||
}
|
||||
```
|
||||
|
||||
> 运行 demo: `go run ./_examples/demo.go`
|
||||
|
||||

|
||||
|
||||
## 构建风格
|
||||
|
||||
```go
|
||||
// 仅设置前景色
|
||||
color.FgCyan.Printf("Simple to use %s\n", "color")
|
||||
// 仅设置背景色
|
||||
color.BgRed.Printf("Simple to use %s\n", "color")
|
||||
|
||||
// 完全自定义: 前景色 背景色 选项
|
||||
style := color.New(color.FgWhite, color.BgBlack, color.OpBold)
|
||||
style.Println("custom color style")
|
||||
|
||||
// 也可以:
|
||||
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
|
||||
```
|
||||
|
||||
直接设置控制台属性:
|
||||
|
||||
```go
|
||||
// 设置console颜色
|
||||
color.Set(color.FgCyan)
|
||||
|
||||
// 输出信息
|
||||
fmt.Print("message")
|
||||
|
||||
// 重置console颜色
|
||||
color.Reset()
|
||||
```
|
||||
|
||||
> 当然,color已经内置丰富的色彩风格支持
|
||||
|
||||
## 基础颜色方法
|
||||
|
||||
> 支持在windows `cmd.exe` `powerShell` 等终端使用
|
||||
|
||||
- `color.Bold`
|
||||
- `color.Black`
|
||||
- `color.White`
|
||||
- `color.Gray`
|
||||
- `color.Red`
|
||||
- `color.Green`
|
||||
- `color.Yellow`
|
||||
- `color.Blue`
|
||||
- `color.Magenta`
|
||||
- `color.Cyan`
|
||||
|
||||
```go
|
||||
color.Bold.Println("bold message")
|
||||
color.Yellow.Println("yellow message")
|
||||
```
|
||||
|
||||
> 运行demo: `go run ./_examples/basiccolor.go`
|
||||
|
||||

|
||||
|
||||
## 扩展风格方法
|
||||
|
||||
> 支持在windows `cmd.exe` `powerShell` 等终端使用
|
||||
|
||||
- `color.Info`
|
||||
- `color.Note`
|
||||
- `color.Light`
|
||||
- `color.Error`
|
||||
- `color.Danger`
|
||||
- `color.Notice`
|
||||
- `color.Success`
|
||||
- `color.Comment`
|
||||
- `color.Primary`
|
||||
- `color.Warning`
|
||||
- `color.Question`
|
||||
- `color.Secondary`
|
||||
|
||||
### 基础风格
|
||||
|
||||
```go
|
||||
// print message
|
||||
color.Info.Println("Info message")
|
||||
color.Success.Println("Success message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_basic.go`
|
||||
|
||||

|
||||
|
||||
### 简约提示风格
|
||||
|
||||
```go
|
||||
color.Info.Tips("tips style message")
|
||||
color.Warn.Tips("tips style message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_tips.go`
|
||||
|
||||

|
||||
|
||||
### 着重提示风格
|
||||
|
||||
```go
|
||||
color.Info.Prompt("prompt style message")
|
||||
color.Warn.Prompt("prompt style message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_prompt.go`
|
||||
|
||||

|
||||
|
||||
### 强调提示风格
|
||||
|
||||
```go
|
||||
color.Info.Block("prompt style message")
|
||||
color.Warn.Block("prompt style message")
|
||||
```
|
||||
|
||||
Run demo: `go run ./_examples/theme_block.go`
|
||||
|
||||

|
||||
|
||||
### 使用颜色标签
|
||||
|
||||
> **支持** 在windows `cmd.exe` `PowerShell` 使用
|
||||
|
||||
使用内置的颜色标签,可以非常方便简单的构建自己需要的任何格式
|
||||
|
||||
```go
|
||||
// 使用内置的 color tag
|
||||
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>")
|
||||
color.Println("<suc>hello</>")
|
||||
color.Println("<error>hello</>")
|
||||
color.Println("<warning>hello</>")
|
||||
|
||||
// 自定义颜色属性
|
||||
color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n")
|
||||
```
|
||||
|
||||
- 使用 `color.Tag`
|
||||
|
||||
给后面输出的文本信息加上给定的颜色风格标签
|
||||
|
||||
```go
|
||||
// set a style tag
|
||||
color.Tag("info").Print("info style text")
|
||||
color.Tag("info").Printf("%s style text", "info")
|
||||
color.Tag("info").Println("info style text")
|
||||
```
|
||||
|
||||
> 运行 demo: `go run ./_examples/colortag.go`
|
||||
|
||||

|
||||
|
||||
## 256色使用
|
||||
|
||||
> 256色彩在 `v1.2.4` 后支持Windows CMD,PowerShell 环境
|
||||
|
||||
### 使用前景或后景色
|
||||
|
||||
- `color.C256(val uint8, isBg ...bool) Color256`
|
||||
|
||||
```go
|
||||
c := color.C256(132) // fg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
|
||||
c := color.C256(132, true) // bg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
### 使用风格
|
||||
|
||||
> 可同时设置前景和背景色
|
||||
|
||||
- `color.S256(fgAndBg ...uint8) *Style256`
|
||||
|
||||
```go
|
||||
s := color.S256(32, 203)
|
||||
s.Println("message")
|
||||
s.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
可以同时添加选项设置:
|
||||
|
||||
```go
|
||||
s := color.S256(32, 203)
|
||||
s.SetOpts(color.Opts{color.OpBold})
|
||||
|
||||
s.Println("style with options")
|
||||
s.Printf("style with %s\n", "options")
|
||||
```
|
||||
|
||||
> 运行 demo: `go run ./_examples/color256.go`
|
||||
|
||||

|
||||
|
||||
## RGB色彩使用
|
||||
|
||||
> RGB色彩在 `v1.2.4` 后支持 Windows `CMD`, `PowerShell` 环境
|
||||
|
||||
**效果预览:**
|
||||
|
||||
> 运行 demo: `Run demo: go run ./_examples/color_rgb.go`
|
||||
|
||||

|
||||
|
||||
代码示例:
|
||||
|
||||
```go
|
||||
color.RGB(30, 144, 255).Println("message. use RGB number")
|
||||
|
||||
color.HEX("#1976D2").Println("blue-darken")
|
||||
color.HEX("#D50000", true).Println("red-accent. use HEX style")
|
||||
|
||||
color.RGBStyleFromString("213,0,0").Println("red-accent. use RGB number")
|
||||
color.HEXStyle("eee", "D50000").Println("deep-purple color")
|
||||
```
|
||||
|
||||
### 使用前景或后景色
|
||||
|
||||
- `color.RGB(r, g, b uint8, isBg ...bool) RGBColor`
|
||||
|
||||
```go
|
||||
c := color.RGB(30,144,255) // fg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
|
||||
c := color.RGB(30,144,255, true) // bg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
- `color.HEX(hex string, isBg ...bool) RGBColor` 从16进制颜色创建
|
||||
|
||||
```go
|
||||
c := color.HEX("ccc") // 也可以写为: "cccccc" "#cccccc"
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
|
||||
c = color.HEX("aabbcc", true) // as bg color
|
||||
c.Println("message")
|
||||
c.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
### 使用风格
|
||||
|
||||
> 可同时设置前景和背景色
|
||||
|
||||
- `color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle`
|
||||
|
||||
```go
|
||||
s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23))
|
||||
s.Println("message")
|
||||
s.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
- `color.HEXStyle(fg string, bg ...string) *RGBStyle` 从16进制颜色创建
|
||||
|
||||
```go
|
||||
s := color.HEXStyle("11aa23", "eee")
|
||||
s.Println("message")
|
||||
s.Printf("format %s", "message")
|
||||
```
|
||||
|
||||
- 可以同时添加选项设置:
|
||||
|
||||
```go
|
||||
s := color.HEXStyle("11aa23", "eee")
|
||||
s.SetOpts(color.Opts{color.OpBold})
|
||||
|
||||
s.Println("style with options")
|
||||
s.Printf("style with %s\n", "options")
|
||||
```
|
||||
|
||||
## 方法参考
|
||||
|
||||
一些有用的工具方法参考
|
||||
|
||||
- `Disable()` disable color render
|
||||
- `SetOutput(io.Writer)` custom set the colored text output writer
|
||||
- `ForceOpenColor()` force open color render
|
||||
- `ClearCode(str string) string` Use for clear color codes
|
||||
- `Colors2code(colors ...Color) string` Convert colors to code. return like "32;45;3"
|
||||
- `ClearTag(s string) string` clear all color html-tag for a string
|
||||
- `IsConsole(w io.Writer)` Determine whether w is one of stderr, stdout, stdin
|
||||
- `HexToRgb(hex string) (rgb []int)` Convert hex color string to RGB numbers
|
||||
- `RgbToHex(rgb []int) string` Convert RGB to hex code
|
||||
- 更多请查看文档 https://pkg.go.dev/github.com/gookit/color
|
||||
|
||||
## Gookit 工具包
|
||||
|
||||
- [gookit/ini](https://github.com/gookit/ini) INI配置读取管理,支持多文件加载,数据覆盖合并, 解析ENV变量, 解析变量引用
|
||||
- [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP
|
||||
- [gookit/gcli](https://github.com/gookit/gcli) Go的命令行应用,工具库,运行CLI命令,支持命令行色彩,用户交互,进度显示,数据格式化显示
|
||||
- [gookit/slog](https://github.com/gookit/slog) 简洁易扩展的go日志库
|
||||
- [gookit/event](https://github.com/gookit/event) Go实现的轻量级的事件管理、调度程序库, 支持设置监听器的优先级, 支持对一组事件进行监听
|
||||
- [gookit/cache](https://github.com/gookit/cache) 通用的缓存使用包装库,通过包装各种常用的驱动,来提供统一的使用API
|
||||
- [gookit/config](https://github.com/gookit/config) Go应用配置管理,支持多种格式(JSON, YAML, TOML, INI, HCL, ENV, Flags),多文件加载,远程文件加载,数据合并
|
||||
- [gookit/color](https://github.com/gookit/color) CLI 控制台颜色渲染工具库, 拥有简洁的使用API,支持16色,256色,RGB色彩渲染输出
|
||||
- [gookit/filter](https://github.com/gookit/filter) 提供对Golang数据的过滤,净化,转换
|
||||
- [gookit/validate](https://github.com/gookit/validate) Go通用的数据验证与过滤库,使用简单,内置大部分常用验证、过滤器
|
||||
- [gookit/goutil](https://github.com/gookit/goutil) Go 的一些工具函数,格式化,特殊处理,常用信息获取等
|
||||
- 更多请查看 https://github.com/gookit
|
||||
|
||||
## 参考项目
|
||||
|
||||
- [inhere/console](https://github.com/inhere/php-console)
|
||||
- [xo/terminfo](https://github.com/xo/terminfo)
|
||||
- [beego/bee](https://github.com/beego/bee)
|
||||
- [issue9/term](https://github.com/issue9/term)
|
||||
- [ANSI转义序列](https://zh.wikipedia.org/wiki/ANSI转义序列)
|
||||
- [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
275
vendor/github.com/gookit/color/color.go
generated
vendored
Normal file
275
vendor/github.com/gookit/color/color.go
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
Package color is Command line color library.
|
||||
Support rich color rendering output, universal API method, compatible with Windows system
|
||||
|
||||
Source code and other details for the project are available at GitHub:
|
||||
|
||||
https://github.com/gookit/color
|
||||
|
||||
More usage please see README and tests.
|
||||
*/
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// console color mode
|
||||
// const (
|
||||
// ModeNormal = iota
|
||||
// Mode256 // 8 bite
|
||||
// ModeRGB // 24 bite
|
||||
// ModeGrayscale
|
||||
// )
|
||||
|
||||
// color render templates
|
||||
// ESC 操作的表示:
|
||||
// "\033"(Octal 8进制) = "\x1b"(Hexadecimal 16进制) = 27 (10进制)
|
||||
const (
|
||||
SettingTpl = "\x1b[%sm"
|
||||
FullColorTpl = "\x1b[%sm%s\x1b[0m"
|
||||
)
|
||||
|
||||
// ResetSet Close all properties.
|
||||
const ResetSet = "\x1b[0m"
|
||||
|
||||
// CodeExpr regex to clear color codes eg "\033[1;36mText\x1b[0m"
|
||||
const CodeExpr = `\033\[[\d;?]+m`
|
||||
|
||||
var (
|
||||
// Enable switch color render and display
|
||||
Enable = true
|
||||
// RenderTag render HTML tag on call color.Xprint, color.PrintX
|
||||
RenderTag = true
|
||||
// errors on windows render OR print to io.Writer
|
||||
errors []error
|
||||
// output the default io.Writer message print
|
||||
output io.Writer = os.Stdout
|
||||
// mark current env, It's like in `cmd.exe`
|
||||
// if not in windows, is's always is False.
|
||||
isLikeInCmd bool
|
||||
// match color codes
|
||||
codeRegex = regexp.MustCompile(CodeExpr)
|
||||
// mark current env is support color.
|
||||
// Always: isLikeInCmd != supportColor
|
||||
supportColor = IsSupportColor()
|
||||
)
|
||||
|
||||
/*************************************************************
|
||||
* global settings
|
||||
*************************************************************/
|
||||
|
||||
// Set set console color attributes
|
||||
func Set(colors ...Color) (int, error) {
|
||||
if !Enable { // not enable
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if !supportColor {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return fmt.Printf(SettingTpl, Colors2code(colors...))
|
||||
}
|
||||
|
||||
// Reset reset console color attributes
|
||||
func Reset() (int, error) {
|
||||
if !Enable { // not enable
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if !supportColor {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return fmt.Print(ResetSet)
|
||||
}
|
||||
|
||||
// Disable disable color output
|
||||
func Disable() bool {
|
||||
oldVal := Enable
|
||||
Enable = false
|
||||
return oldVal
|
||||
}
|
||||
|
||||
// NotRenderTag on call color.Xprint, color.PrintX
|
||||
func NotRenderTag() {
|
||||
RenderTag = false
|
||||
}
|
||||
|
||||
// SetOutput set default colored text output
|
||||
func SetOutput(w io.Writer) {
|
||||
output = w
|
||||
}
|
||||
|
||||
// ResetOutput reset output
|
||||
func ResetOutput() {
|
||||
output = os.Stdout
|
||||
}
|
||||
|
||||
// ResetOptions reset all package option setting
|
||||
func ResetOptions() {
|
||||
RenderTag = true
|
||||
Enable = true
|
||||
output = os.Stdout
|
||||
}
|
||||
|
||||
// SupportColor of the current ENV
|
||||
func SupportColor() bool {
|
||||
return supportColor
|
||||
}
|
||||
|
||||
// ForceColor force open color render
|
||||
func ForceColor() bool {
|
||||
return ForceOpenColor()
|
||||
}
|
||||
|
||||
// ForceOpenColor force open color render
|
||||
func ForceOpenColor() bool {
|
||||
oldVal := supportColor
|
||||
supportColor = true
|
||||
|
||||
return oldVal
|
||||
}
|
||||
|
||||
// IsLikeInCmd check result
|
||||
func IsLikeInCmd() bool {
|
||||
return isLikeInCmd
|
||||
}
|
||||
|
||||
// GetErrors info
|
||||
func GetErrors() []error {
|
||||
return errors
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* render color code
|
||||
*************************************************************/
|
||||
|
||||
// RenderCode render message by color code.
|
||||
// Usage:
|
||||
// msg := RenderCode("3;32;45", "some", "message")
|
||||
func RenderCode(code string, args ...interface{}) string {
|
||||
var message string
|
||||
if ln := len(args); ln == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
message = fmt.Sprint(args...)
|
||||
if len(code) == 0 {
|
||||
return message
|
||||
}
|
||||
|
||||
// disabled OR not support color
|
||||
if !Enable || !supportColor {
|
||||
return ClearCode(message)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(FullColorTpl, code, message)
|
||||
}
|
||||
|
||||
// RenderWithSpaces Render code with spaces.
|
||||
// If the number of args is > 1, a space will be added between the args
|
||||
func RenderWithSpaces(code string, args ...interface{}) string {
|
||||
message := formatArgsForPrintln(args)
|
||||
if len(code) == 0 {
|
||||
return message
|
||||
}
|
||||
|
||||
// disabled OR not support color
|
||||
if !Enable || !supportColor {
|
||||
return ClearCode(message)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(FullColorTpl, code, message)
|
||||
}
|
||||
|
||||
// RenderString render a string with color code.
|
||||
// Usage:
|
||||
// msg := RenderString("3;32;45", "a message")
|
||||
func RenderString(code string, str string) string {
|
||||
if len(code) == 0 || str == "" {
|
||||
return str
|
||||
}
|
||||
|
||||
// disabled OR not support color
|
||||
if !Enable || !supportColor {
|
||||
return ClearCode(str)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(FullColorTpl, code, str)
|
||||
}
|
||||
|
||||
// ClearCode clear color codes.
|
||||
// eg:
|
||||
// "\033[36;1mText\x1b[0m" -> "Text"
|
||||
func ClearCode(str string) string {
|
||||
return codeRegex.ReplaceAllString(str, "")
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* colored message Printer
|
||||
*************************************************************/
|
||||
|
||||
// PrinterFace interface
|
||||
type PrinterFace interface {
|
||||
fmt.Stringer
|
||||
Sprint(a ...interface{}) string
|
||||
Sprintf(format string, a ...interface{}) string
|
||||
Print(a ...interface{})
|
||||
Printf(format string, a ...interface{})
|
||||
Println(a ...interface{})
|
||||
}
|
||||
|
||||
// Printer a generic color message printer.
|
||||
// Usage:
|
||||
// p := &Printer{"32;45;3"}
|
||||
// p.Print("message")
|
||||
type Printer struct {
|
||||
// ColorCode color code string. eg "32;45;3"
|
||||
ColorCode string
|
||||
}
|
||||
|
||||
// NewPrinter instance
|
||||
func NewPrinter(colorCode string) *Printer {
|
||||
return &Printer{colorCode}
|
||||
}
|
||||
|
||||
// String returns color code string. eg: "32;45;3"
|
||||
func (p *Printer) String() string {
|
||||
// panic("implement me")
|
||||
return p.ColorCode
|
||||
}
|
||||
|
||||
// Sprint returns rendering colored messages
|
||||
func (p *Printer) Sprint(a ...interface{}) string {
|
||||
return RenderCode(p.String(), a...)
|
||||
}
|
||||
|
||||
// Sprintf returns format and rendering colored messages
|
||||
func (p *Printer) Sprintf(format string, a ...interface{}) string {
|
||||
return RenderString(p.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Print rendering colored messages
|
||||
func (p *Printer) Print(a ...interface{}) {
|
||||
doPrintV2(p.String(), fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Printf format and rendering colored messages
|
||||
func (p *Printer) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(p.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println rendering colored messages with newline
|
||||
func (p *Printer) Println(a ...interface{}) {
|
||||
doPrintlnV2(p.ColorCode, a)
|
||||
}
|
||||
|
||||
// IsEmpty color code
|
||||
func (p *Printer) IsEmpty() bool {
|
||||
return p.ColorCode == ""
|
||||
}
|
327
vendor/github.com/gookit/color/color_16.go
generated
vendored
Normal file
327
vendor/github.com/gookit/color/color_16.go
generated
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Color Color16, 16 color value type
|
||||
// 3(2^3=8) OR 4(2^4=16) bite color.
|
||||
type Color uint8
|
||||
|
||||
// Opts basic color options. code: 0 - 9
|
||||
type Opts []Color
|
||||
|
||||
// Add option value
|
||||
func (o *Opts) Add(ops ...Color) {
|
||||
for _, op := range ops {
|
||||
if uint8(op) < 10 {
|
||||
*o = append(*o, op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IsValid options
|
||||
func (o Opts) IsValid() bool {
|
||||
return len(o) > 0
|
||||
}
|
||||
|
||||
// IsEmpty options
|
||||
func (o Opts) IsEmpty() bool {
|
||||
return len(o) == 0
|
||||
}
|
||||
|
||||
// String options to string. eg: "1;3"
|
||||
func (o Opts) String() string {
|
||||
return Colors2code(o...)
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Basic 16 color definition
|
||||
*************************************************************/
|
||||
|
||||
// Base value for foreground/background color
|
||||
const (
|
||||
FgBase uint8 = 30
|
||||
BgBase uint8 = 40
|
||||
)
|
||||
|
||||
// Foreground colors. basic foreground colors 30 - 37
|
||||
const (
|
||||
FgBlack Color = iota + 30
|
||||
FgRed
|
||||
FgGreen
|
||||
FgYellow
|
||||
FgBlue
|
||||
FgMagenta // 品红
|
||||
FgCyan // 青色
|
||||
FgWhite
|
||||
// FgDefault revert default FG
|
||||
FgDefault Color = 39
|
||||
)
|
||||
|
||||
// Extra foreground color 90 - 97(非标准)
|
||||
const (
|
||||
FgDarkGray Color = iota + 90 // 亮黑(灰)
|
||||
FgLightRed
|
||||
FgLightGreen
|
||||
FgLightYellow
|
||||
FgLightBlue
|
||||
FgLightMagenta
|
||||
FgLightCyan
|
||||
FgLightWhite
|
||||
// FgGray is alias of FgDarkGray
|
||||
FgGray Color = 90 // 亮黑(灰)
|
||||
)
|
||||
|
||||
// Background colors. basic background colors 40 - 47
|
||||
const (
|
||||
BgBlack Color = iota + 40
|
||||
BgRed
|
||||
BgGreen
|
||||
BgYellow // BgBrown like yellow
|
||||
BgBlue
|
||||
BgMagenta
|
||||
BgCyan
|
||||
BgWhite
|
||||
// BgDefault revert default BG
|
||||
BgDefault Color = 49
|
||||
)
|
||||
|
||||
// Extra background color 100 - 107(非标准)
|
||||
const (
|
||||
BgDarkGray Color = iota + 100
|
||||
BgLightRed
|
||||
BgLightGreen
|
||||
BgLightYellow
|
||||
BgLightBlue
|
||||
BgLightMagenta
|
||||
BgLightCyan
|
||||
BgLightWhite
|
||||
// BgGray is alias of BgDarkGray
|
||||
BgGray Color = 100
|
||||
)
|
||||
|
||||
// Option settings
|
||||
const (
|
||||
OpReset Color = iota // 0 重置所有设置
|
||||
OpBold // 1 加粗
|
||||
OpFuzzy // 2 模糊(不是所有的终端仿真器都支持)
|
||||
OpItalic // 3 斜体(不是所有的终端仿真器都支持)
|
||||
OpUnderscore // 4 下划线
|
||||
OpBlink // 5 闪烁
|
||||
OpFastBlink // 5 快速闪烁(未广泛支持)
|
||||
OpReverse // 7 颠倒的 交换背景色与前景色
|
||||
OpConcealed // 8 隐匿的
|
||||
OpStrikethrough // 9 删除的,删除线(未广泛支持)
|
||||
)
|
||||
|
||||
// There are basic and light foreground color aliases
|
||||
const (
|
||||
Red = FgRed
|
||||
Cyan = FgCyan
|
||||
Gray = FgDarkGray // is light Black
|
||||
Blue = FgBlue
|
||||
Black = FgBlack
|
||||
Green = FgGreen
|
||||
White = FgWhite
|
||||
Yellow = FgYellow
|
||||
Magenta = FgMagenta
|
||||
|
||||
// special
|
||||
|
||||
Bold = OpBold
|
||||
Normal = FgDefault
|
||||
|
||||
// extra light
|
||||
|
||||
LightRed = FgLightRed
|
||||
LightCyan = FgLightCyan
|
||||
LightBlue = FgLightBlue
|
||||
LightGreen = FgLightGreen
|
||||
LightWhite = FgLightWhite
|
||||
LightYellow = FgLightYellow
|
||||
LightMagenta = FgLightMagenta
|
||||
)
|
||||
|
||||
// Bit4 an method for create Color
|
||||
func Bit4(code uint8) Color {
|
||||
return Color(code)
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Color render methods
|
||||
*************************************************************/
|
||||
|
||||
// Text render a text message
|
||||
func (c Color) Text(message string) string {
|
||||
return RenderString(c.String(), message)
|
||||
}
|
||||
|
||||
// Render messages by color setting
|
||||
// Usage:
|
||||
// green := color.FgGreen.Render
|
||||
// fmt.Println(green("message"))
|
||||
func (c Color) Render(a ...interface{}) string {
|
||||
return RenderCode(c.String(), a...)
|
||||
}
|
||||
|
||||
// Renderln messages by color setting.
|
||||
// like Println, will add spaces for each argument
|
||||
// Usage:
|
||||
// green := color.FgGreen.Renderln
|
||||
// fmt.Println(green("message"))
|
||||
func (c Color) Renderln(a ...interface{}) string {
|
||||
return RenderWithSpaces(c.String(), a...)
|
||||
}
|
||||
|
||||
// Sprint render messages by color setting. is alias of the Render()
|
||||
func (c Color) Sprint(a ...interface{}) string {
|
||||
return RenderCode(c.String(), a...)
|
||||
}
|
||||
|
||||
// Sprintf format and render message.
|
||||
// Usage:
|
||||
// green := color.Green.Sprintf
|
||||
// colored := green("message")
|
||||
func (c Color) Sprintf(format string, args ...interface{}) string {
|
||||
return RenderString(c.String(), fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
// Print messages.
|
||||
// Usage:
|
||||
// color.Green.Print("message")
|
||||
// OR:
|
||||
// green := color.FgGreen.Print
|
||||
// green("message")
|
||||
func (c Color) Print(args ...interface{}) {
|
||||
doPrintV2(c.Code(), fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// Printf format and print messages.
|
||||
// Usage:
|
||||
// color.Cyan.Printf("string %s", "arg0")
|
||||
func (c Color) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(c.Code(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println messages with new line
|
||||
func (c Color) Println(a ...interface{}) {
|
||||
doPrintlnV2(c.String(), a)
|
||||
}
|
||||
|
||||
// Light current color. eg: 36(FgCyan) -> 96(FgLightCyan).
|
||||
// Usage:
|
||||
// lightCyan := Cyan.Light()
|
||||
// lightCyan.Print("message")
|
||||
func (c Color) Light() Color {
|
||||
val := int(c)
|
||||
if val >= 30 && val <= 47 {
|
||||
return Color(uint8(c) + 60)
|
||||
}
|
||||
|
||||
// don't change
|
||||
return c
|
||||
}
|
||||
|
||||
// Darken current color. eg. 96(FgLightCyan) -> 36(FgCyan)
|
||||
// Usage:
|
||||
// cyan := LightCyan.Darken()
|
||||
// cyan.Print("message")
|
||||
func (c Color) Darken() Color {
|
||||
val := int(c)
|
||||
if val >= 90 && val <= 107 {
|
||||
return Color(uint8(c) - 60)
|
||||
}
|
||||
|
||||
// don't change
|
||||
return c
|
||||
}
|
||||
|
||||
// Code convert to code string. eg "35"
|
||||
func (c Color) Code() string {
|
||||
// return fmt.Sprintf("%d", c)
|
||||
return strconv.Itoa(int(c))
|
||||
}
|
||||
|
||||
// String convert to code string. eg "35"
|
||||
func (c Color) String() string {
|
||||
// return fmt.Sprintf("%d", c)
|
||||
return strconv.Itoa(int(c))
|
||||
}
|
||||
|
||||
// IsValid color value
|
||||
func (c Color) IsValid() bool {
|
||||
return c < 107
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* basic color maps
|
||||
*************************************************************/
|
||||
|
||||
// FgColors foreground colors map
|
||||
var FgColors = map[string]Color{
|
||||
"black": FgBlack,
|
||||
"red": FgRed,
|
||||
"green": FgGreen,
|
||||
"yellow": FgYellow,
|
||||
"blue": FgBlue,
|
||||
"magenta": FgMagenta,
|
||||
"cyan": FgCyan,
|
||||
"white": FgWhite,
|
||||
"default": FgDefault,
|
||||
}
|
||||
|
||||
// BgColors background colors map
|
||||
var BgColors = map[string]Color{
|
||||
"black": BgBlack,
|
||||
"red": BgRed,
|
||||
"green": BgGreen,
|
||||
"yellow": BgYellow,
|
||||
"blue": BgBlue,
|
||||
"magenta": BgMagenta,
|
||||
"cyan": BgCyan,
|
||||
"white": BgWhite,
|
||||
"default": BgDefault,
|
||||
}
|
||||
|
||||
// ExFgColors extra foreground colors map
|
||||
var ExFgColors = map[string]Color{
|
||||
"darkGray": FgDarkGray,
|
||||
"lightRed": FgLightRed,
|
||||
"lightGreen": FgLightGreen,
|
||||
"lightYellow": FgLightYellow,
|
||||
"lightBlue": FgLightBlue,
|
||||
"lightMagenta": FgLightMagenta,
|
||||
"lightCyan": FgLightCyan,
|
||||
"lightWhite": FgLightWhite,
|
||||
}
|
||||
|
||||
// ExBgColors extra background colors map
|
||||
var ExBgColors = map[string]Color{
|
||||
"darkGray": BgDarkGray,
|
||||
"lightRed": BgLightRed,
|
||||
"lightGreen": BgLightGreen,
|
||||
"lightYellow": BgLightYellow,
|
||||
"lightBlue": BgLightBlue,
|
||||
"lightMagenta": BgLightMagenta,
|
||||
"lightCyan": BgLightCyan,
|
||||
"lightWhite": BgLightWhite,
|
||||
}
|
||||
|
||||
// Options color options map
|
||||
// Deprecated
|
||||
// NOTICE: please use AllOptions instead.
|
||||
var Options = AllOptions
|
||||
|
||||
// AllOptions color options map
|
||||
var AllOptions = map[string]Color{
|
||||
"reset": OpReset,
|
||||
"bold": OpBold,
|
||||
"fuzzy": OpFuzzy,
|
||||
"italic": OpItalic,
|
||||
"underscore": OpUnderscore,
|
||||
"blink": OpBlink,
|
||||
"reverse": OpReverse,
|
||||
"concealed": OpConcealed,
|
||||
}
|
243
vendor/github.com/gookit/color/color_256.go
generated
vendored
Normal file
243
vendor/github.com/gookit/color/color_256.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
from wikipedia, 256 color:
|
||||
ESC[ … 38;5;<n> … m选择前景色
|
||||
ESC[ … 48;5;<n> … m选择背景色
|
||||
0- 7:标准颜色(同 ESC[30–37m)
|
||||
8- 15:高强度颜色(同 ESC[90–97m)
|
||||
16-231:6 × 6 × 6 立方(216色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
|
||||
232-255:从黑到白的24阶灰度色
|
||||
*/
|
||||
|
||||
// tpl for 8 bit 256 color(`2^8`)
|
||||
//
|
||||
// format:
|
||||
// ESC[ … 38;5;<n> … m // 选择前景色
|
||||
// ESC[ … 48;5;<n> … m // 选择背景色
|
||||
//
|
||||
// example:
|
||||
// fg "\x1b[38;5;242m"
|
||||
// bg "\x1b[48;5;208m"
|
||||
// both "\x1b[38;5;242;48;5;208m"
|
||||
//
|
||||
// links:
|
||||
// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位
|
||||
const (
|
||||
TplFg256 = "38;5;%d"
|
||||
TplBg256 = "48;5;%d"
|
||||
)
|
||||
|
||||
/*************************************************************
|
||||
* 8bit(256) Color: Bit8Color Color256
|
||||
*************************************************************/
|
||||
|
||||
// Color256 256 color (8 bit), uint8 range at 0 - 255
|
||||
//
|
||||
// 颜色值使用10进制和16进制都可 0x98 = 152
|
||||
//
|
||||
// The color consists of two uint8:
|
||||
// 0: color value
|
||||
// 1: color type; Fg=0, Bg=1, >1: unset value
|
||||
//
|
||||
// example:
|
||||
// fg color: [152, 0]
|
||||
// bg color: [152, 1]
|
||||
//
|
||||
// NOTICE: now support 256 color on windows CMD, PowerShell
|
||||
type Color256 [2]uint8
|
||||
|
||||
// Bit8 create a color256
|
||||
func Bit8(val uint8, isBg ...bool) Color256 {
|
||||
return C256(val, isBg...)
|
||||
}
|
||||
|
||||
// C256 create a color256
|
||||
func C256(val uint8, isBg ...bool) Color256 {
|
||||
bc := Color256{val}
|
||||
|
||||
// mark is bg color
|
||||
if len(isBg) > 0 && isBg[0] {
|
||||
bc[1] = AsBg
|
||||
}
|
||||
|
||||
return bc
|
||||
}
|
||||
|
||||
// Print print message
|
||||
func (c Color256) Print(a ...interface{}) {
|
||||
doPrintV2(c.String(), fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Printf format and print message
|
||||
func (c Color256) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(c.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println print message with newline
|
||||
func (c Color256) Println(a ...interface{}) {
|
||||
doPrintlnV2(c.String(), a)
|
||||
}
|
||||
|
||||
// Sprint returns rendered message
|
||||
func (c Color256) Sprint(a ...interface{}) string {
|
||||
return RenderCode(c.String(), a...)
|
||||
}
|
||||
|
||||
// Sprintf returns format and rendered message
|
||||
func (c Color256) Sprintf(format string, a ...interface{}) string {
|
||||
return RenderString(c.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// RGBColor convert color-256 to RGB color.
|
||||
func (c Color256) RGBColor() RGBColor {
|
||||
return RGBFromSlice(C256ToRgb(c[0]), c[1] == AsBg)
|
||||
}
|
||||
|
||||
// Value return color value
|
||||
func (c Color256) Value() uint8 {
|
||||
return c[0]
|
||||
}
|
||||
|
||||
// String convert to color code string.
|
||||
func (c Color256) String() string {
|
||||
if c[1] == AsFg { // 0 is Fg
|
||||
return fmt.Sprintf(TplFg256, c[0])
|
||||
}
|
||||
|
||||
if c[1] == AsBg { // 1 is Bg
|
||||
return fmt.Sprintf(TplBg256, c[0])
|
||||
}
|
||||
|
||||
// empty
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsEmpty value
|
||||
func (c Color256) IsEmpty() bool {
|
||||
return c[1] > 1
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* 8bit(256) Style
|
||||
*************************************************************/
|
||||
|
||||
// Style256 definition
|
||||
//
|
||||
// 前/背景色
|
||||
// 都是由两位uint8组成, 第一位是色彩值;
|
||||
// 第二位与Bit8Color不一样的是,在这里表示是否设置了值 0 未设置 ^0 已设置
|
||||
type Style256 struct {
|
||||
// p Printer
|
||||
|
||||
// Name of the style
|
||||
Name string
|
||||
// color options of the style
|
||||
opts Opts
|
||||
// fg and bg color
|
||||
fg, bg Color256
|
||||
}
|
||||
|
||||
// S256 create a color256 style
|
||||
// Usage:
|
||||
// s := color.S256()
|
||||
// s := color.S256(132) // fg
|
||||
// s := color.S256(132, 203) // fg and bg
|
||||
func S256(fgAndBg ...uint8) *Style256 {
|
||||
s := &Style256{}
|
||||
vl := len(fgAndBg)
|
||||
if vl > 0 { // with fg
|
||||
s.fg = Color256{fgAndBg[0], 1}
|
||||
|
||||
if vl > 1 { // and with bg
|
||||
s.bg = Color256{fgAndBg[1], 1}
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// Set fg and bg color value, can also with color options
|
||||
func (s *Style256) Set(fgVal, bgVal uint8, opts ...Color) *Style256 {
|
||||
s.fg = Color256{fgVal, 1}
|
||||
s.bg = Color256{bgVal, 1}
|
||||
s.opts.Add(opts...)
|
||||
return s
|
||||
}
|
||||
|
||||
// SetBg set bg color value
|
||||
func (s *Style256) SetBg(bgVal uint8) *Style256 {
|
||||
s.bg = Color256{bgVal, 1}
|
||||
return s
|
||||
}
|
||||
|
||||
// SetFg set fg color value
|
||||
func (s *Style256) SetFg(fgVal uint8) *Style256 {
|
||||
s.fg = Color256{fgVal, 1}
|
||||
return s
|
||||
}
|
||||
|
||||
// SetOpts set options
|
||||
func (s *Style256) SetOpts(opts Opts) *Style256 {
|
||||
s.opts = opts
|
||||
return s
|
||||
}
|
||||
|
||||
// AddOpts add options
|
||||
func (s *Style256) AddOpts(opts ...Color) *Style256 {
|
||||
s.opts.Add(opts...)
|
||||
return s
|
||||
}
|
||||
|
||||
// Print message
|
||||
func (s *Style256) Print(a ...interface{}) {
|
||||
doPrintV2(s.String(), fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Printf format and print message
|
||||
func (s *Style256) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(s.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println print message with newline
|
||||
func (s *Style256) Println(a ...interface{}) {
|
||||
doPrintlnV2(s.String(), a)
|
||||
}
|
||||
|
||||
// Sprint returns rendered message
|
||||
func (s *Style256) Sprint(a ...interface{}) string {
|
||||
return RenderCode(s.Code(), a...)
|
||||
}
|
||||
|
||||
// Sprintf returns format and rendered message
|
||||
func (s *Style256) Sprintf(format string, a ...interface{}) string {
|
||||
return RenderString(s.Code(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Code convert to color code string
|
||||
func (s *Style256) Code() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// String convert to color code string
|
||||
func (s *Style256) String() string {
|
||||
var ss []string
|
||||
if s.fg[1] > 0 {
|
||||
ss = append(ss, fmt.Sprintf(TplFg256, s.fg[0]))
|
||||
}
|
||||
|
||||
if s.bg[1] > 0 {
|
||||
ss = append(ss, fmt.Sprintf(TplBg256, s.bg[0]))
|
||||
}
|
||||
|
||||
if s.opts.IsValid() {
|
||||
ss = append(ss, s.opts.String())
|
||||
}
|
||||
|
||||
return strings.Join(ss, ";")
|
||||
}
|
24
vendor/github.com/gookit/color/color_nonwin.go
generated
vendored
Normal file
24
vendor/github.com/gookit/color/color_nonwin.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// +build !windows
|
||||
|
||||
// The method in the file has no effect
|
||||
// Only for compatibility with non-Windows systems
|
||||
|
||||
package color
|
||||
|
||||
func winSet(_ ...Color) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func winReset() (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func winPrint(_ string, _ ...Color) {}
|
||||
func winPrintln(_ string, _ ...Color) {}
|
||||
|
||||
// func renderColorCodeOnCmd(_ func()) {}
|
||||
|
||||
// IsTerminal check currently is terminal
|
||||
func IsTerminal(_ int) bool {
|
||||
return true
|
||||
}
|
358
vendor/github.com/gookit/color/color_rgb.go
generated
vendored
Normal file
358
vendor/github.com/gookit/color/color_rgb.go
generated
vendored
Normal file
@ -0,0 +1,358 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 24 bit RGB color
|
||||
// RGB:
|
||||
// R 0-255 G 0-255 B 0-255
|
||||
// R 00-FF G 00-FF B 00-FF (16进制)
|
||||
//
|
||||
// Format:
|
||||
// ESC[ … 38;2;<r>;<g>;<b> … m // Select RGB foreground color
|
||||
// ESC[ … 48;2;<r>;<g>;<b> … m // Choose RGB background color
|
||||
//
|
||||
// links:
|
||||
// https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#24位
|
||||
//
|
||||
// example:
|
||||
// fg: \x1b[38;2;30;144;255mMESSAGE\x1b[0m
|
||||
// bg: \x1b[48;2;30;144;255mMESSAGE\x1b[0m
|
||||
// both: \x1b[38;2;233;90;203;48;2;30;144;255mMESSAGE\x1b[0m
|
||||
const (
|
||||
TplFgRGB = "38;2;%d;%d;%d"
|
||||
TplBgRGB = "48;2;%d;%d;%d"
|
||||
)
|
||||
|
||||
// mark color is fg or bg.
|
||||
const (
|
||||
AsFg uint8 = iota
|
||||
AsBg
|
||||
)
|
||||
|
||||
// values from https://github.com/go-terminfo/terminfo
|
||||
// var (
|
||||
// RgbaBlack = image_color.RGBA{0, 0, 0, 255}
|
||||
// Red = color.RGBA{205, 0, 0, 255}
|
||||
// Green = color.RGBA{0, 205, 0, 255}
|
||||
// Orange = color.RGBA{205, 205, 0, 255}
|
||||
// Blue = color.RGBA{0, 0, 238, 255}
|
||||
// Magenta = color.RGBA{205, 0, 205, 255}
|
||||
// Cyan = color.RGBA{0, 205, 205, 255}
|
||||
// LightGrey = color.RGBA{229, 229, 229, 255}
|
||||
//
|
||||
// DarkGrey = color.RGBA{127, 127, 127, 255}
|
||||
// LightRed = color.RGBA{255, 0, 0, 255}
|
||||
// LightGreen = color.RGBA{0, 255, 0, 255}
|
||||
// Yellow = color.RGBA{255, 255, 0, 255}
|
||||
// LightBlue = color.RGBA{92, 92, 255, 255}
|
||||
// LightMagenta = color.RGBA{255, 0, 255, 255}
|
||||
// LightCyan = color.RGBA{0, 255, 255, 255}
|
||||
// White = color.RGBA{255, 255, 255, 255}
|
||||
// )
|
||||
|
||||
/*************************************************************
|
||||
* RGB Color(Bit24Color, TrueColor)
|
||||
*************************************************************/
|
||||
|
||||
// RGBColor definition.
|
||||
//
|
||||
// The first to third digits represent the color value.
|
||||
// The last digit represents the foreground(0), background(1), >1 is unset value
|
||||
//
|
||||
// Usage:
|
||||
// // 0, 1, 2 is R,G,B.
|
||||
// // 3rd: Fg=0, Bg=1, >1: unset value
|
||||
// RGBColor{30,144,255, 0}
|
||||
// RGBColor{30,144,255, 1}
|
||||
//
|
||||
// NOTICE: now support RGB color on windows CMD, PowerShell
|
||||
type RGBColor [4]uint8
|
||||
|
||||
// create a empty RGBColor
|
||||
var emptyRGBColor = RGBColor{3: 99}
|
||||
|
||||
// RGB color create.
|
||||
// Usage:
|
||||
// c := RGB(30,144,255)
|
||||
// c := RGB(30,144,255, true)
|
||||
// c.Print("message")
|
||||
func RGB(r, g, b uint8, isBg ...bool) RGBColor {
|
||||
rgb := RGBColor{r, g, b}
|
||||
if len(isBg) > 0 && isBg[0] {
|
||||
rgb[3] = AsBg
|
||||
}
|
||||
|
||||
return rgb
|
||||
}
|
||||
|
||||
// Rgb alias of the RGB()
|
||||
func Rgb(r, g, b uint8, isBg ...bool) RGBColor { return RGB(r, g, b, isBg...) }
|
||||
|
||||
// Bit24 alias of the RGB()
|
||||
func Bit24(r, g, b uint8, isBg ...bool) RGBColor { return RGB(r, g, b, isBg...) }
|
||||
|
||||
// RGBFromSlice quick RGBColor from slice
|
||||
func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColor {
|
||||
return RGB(rgb[0], rgb[1], rgb[2], isBg...)
|
||||
}
|
||||
|
||||
// HEX create RGB color from a HEX color string.
|
||||
// Usage:
|
||||
// c := HEX("ccc") // rgb: [204 204 204]
|
||||
// c := HEX("aabbcc") // rgb: [170 187 204]
|
||||
// c := HEX("#aabbcc")
|
||||
// c := HEX("0xaabbcc")
|
||||
// c.Print("message")
|
||||
func HEX(hex string, isBg ...bool) RGBColor {
|
||||
if rgb := HexToRgb(hex); len(rgb) > 0 {
|
||||
return RGB(uint8(rgb[0]), uint8(rgb[1]), uint8(rgb[2]), isBg...)
|
||||
}
|
||||
|
||||
// mark is empty
|
||||
return emptyRGBColor
|
||||
}
|
||||
|
||||
// Hex alias of the HEX()
|
||||
func Hex(hex string, isBg ...bool) RGBColor { return HEX(hex, isBg...) }
|
||||
|
||||
// RGBFromString create RGB color from a string.
|
||||
// Usage:
|
||||
// c := RGBFromString("170,187,204")
|
||||
// c.Print("message")
|
||||
func RGBFromString(rgb string, isBg ...bool) RGBColor {
|
||||
ss := stringToArr(rgb, ",")
|
||||
if len(ss) != 3 {
|
||||
return emptyRGBColor
|
||||
}
|
||||
|
||||
var ar [3]int
|
||||
for i, val := range ss {
|
||||
iv, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return emptyRGBColor
|
||||
}
|
||||
|
||||
ar[i] = iv
|
||||
}
|
||||
|
||||
return RGB(uint8(ar[0]), uint8(ar[1]), uint8(ar[2]), isBg...)
|
||||
}
|
||||
|
||||
// Print print message
|
||||
func (c RGBColor) Print(a ...interface{}) {
|
||||
doPrintV2(c.String(), fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Printf format and print message
|
||||
func (c RGBColor) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(c.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println print message with newline
|
||||
func (c RGBColor) Println(a ...interface{}) {
|
||||
doPrintlnV2(c.String(), a)
|
||||
}
|
||||
|
||||
// Sprint returns rendered message
|
||||
func (c RGBColor) Sprint(a ...interface{}) string {
|
||||
return RenderCode(c.String(), a...)
|
||||
}
|
||||
|
||||
// Sprintf returns format and rendered message
|
||||
func (c RGBColor) Sprintf(format string, a ...interface{}) string {
|
||||
return RenderString(c.Code(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Values to RGB values
|
||||
func (c RGBColor) Values() []int {
|
||||
return []int{int(c[0]), int(c[1]), int(c[2])}
|
||||
}
|
||||
|
||||
// Code to color code string
|
||||
func (c RGBColor) Code() string {
|
||||
return c.String()
|
||||
}
|
||||
|
||||
// String to color code string
|
||||
func (c RGBColor) String() string {
|
||||
if c[3] == AsFg {
|
||||
return fmt.Sprintf(TplFgRGB, c[0], c[1], c[2])
|
||||
}
|
||||
|
||||
if c[3] == AsBg {
|
||||
return fmt.Sprintf(TplBgRGB, c[0], c[1], c[2])
|
||||
|
||||
}
|
||||
|
||||
// >1 is empty
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsEmpty value
|
||||
func (c RGBColor) IsEmpty() bool {
|
||||
return c[3] > AsBg
|
||||
}
|
||||
|
||||
// IsValid value
|
||||
// func (c RGBColor) IsValid() bool {
|
||||
// return c[3] <= AsBg
|
||||
// }
|
||||
|
||||
// C256 returns the closest approximate 256 (8 bit) color
|
||||
func (c RGBColor) C256() Color256 {
|
||||
return C256(Rgb2short(c[0], c[1], c[2]), c[3] == AsBg)
|
||||
}
|
||||
|
||||
// C16 returns the closest approximate 16 (4 bit) color
|
||||
func (c RGBColor) C16() Color {
|
||||
return Color(RgbToAnsi(c[0], c[1], c[2], c[3] == AsBg))
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* RGB Style
|
||||
*************************************************************/
|
||||
|
||||
// RGBStyle definition.
|
||||
//
|
||||
// Foreground/Background color
|
||||
// All are composed of 4 digits uint8, the first three digits are the color value;
|
||||
// The last bit is different from RGBColor, here it indicates whether the value is set.
|
||||
// - 1 Has been set
|
||||
// - ^1 Not set
|
||||
type RGBStyle struct {
|
||||
// Name of the style
|
||||
Name string
|
||||
// color options of the style
|
||||
opts Opts
|
||||
// fg and bg color
|
||||
fg, bg RGBColor
|
||||
}
|
||||
|
||||
// NewRGBStyle create a RGBStyle.
|
||||
func NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle {
|
||||
s := &RGBStyle{}
|
||||
if len(bg) > 0 {
|
||||
s.SetBg(bg[0])
|
||||
}
|
||||
|
||||
return s.SetFg(fg)
|
||||
}
|
||||
|
||||
// HEXStyle create a RGBStyle from HEX color string.
|
||||
// Usage:
|
||||
// s := HEXStyle("aabbcc", "eee")
|
||||
// s.Print("message")
|
||||
func HEXStyle(fg string, bg ...string) *RGBStyle {
|
||||
s := &RGBStyle{}
|
||||
if len(bg) > 0 {
|
||||
s.SetBg(HEX(bg[0]))
|
||||
}
|
||||
|
||||
if len(fg) > 0 {
|
||||
s.SetFg(HEX(fg))
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// RGBStyleFromString create a RGBStyle from color value string.
|
||||
// Usage:
|
||||
// s := RGBStyleFromString("170,187,204", "70,87,4")
|
||||
// s.Print("message")
|
||||
func RGBStyleFromString(fg string, bg ...string) *RGBStyle {
|
||||
s := &RGBStyle{}
|
||||
if len(bg) > 0 {
|
||||
s.SetBg(RGBFromString(bg[0]))
|
||||
}
|
||||
|
||||
return s.SetFg(RGBFromString(fg))
|
||||
}
|
||||
|
||||
// Set fg and bg color, can also with color options
|
||||
func (s *RGBStyle) Set(fg, bg RGBColor, opts ...Color) *RGBStyle {
|
||||
return s.SetFg(fg).SetBg(bg).SetOpts(opts)
|
||||
}
|
||||
|
||||
// SetFg set fg color
|
||||
func (s *RGBStyle) SetFg(fg RGBColor) *RGBStyle {
|
||||
fg[3] = 1 // add fixed value, mark is valid
|
||||
s.fg = fg
|
||||
return s
|
||||
}
|
||||
|
||||
// SetBg set bg color
|
||||
func (s *RGBStyle) SetBg(bg RGBColor) *RGBStyle {
|
||||
bg[3] = 1 // add fixed value, mark is valid
|
||||
s.bg = bg
|
||||
return s
|
||||
}
|
||||
|
||||
// SetOpts set color options
|
||||
func (s *RGBStyle) SetOpts(opts Opts) *RGBStyle {
|
||||
s.opts = opts
|
||||
return s
|
||||
}
|
||||
|
||||
// AddOpts add options
|
||||
func (s *RGBStyle) AddOpts(opts ...Color) *RGBStyle {
|
||||
s.opts.Add(opts...)
|
||||
return s
|
||||
}
|
||||
|
||||
// Print print message
|
||||
func (s *RGBStyle) Print(a ...interface{}) {
|
||||
doPrintV2(s.String(), fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Printf format and print message
|
||||
func (s *RGBStyle) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(s.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println print message with newline
|
||||
func (s *RGBStyle) Println(a ...interface{}) {
|
||||
doPrintlnV2(s.String(), a)
|
||||
}
|
||||
|
||||
// Sprint returns rendered message
|
||||
func (s *RGBStyle) Sprint(a ...interface{}) string {
|
||||
return RenderCode(s.String(), a...)
|
||||
}
|
||||
|
||||
// Sprintf returns format and rendered message
|
||||
func (s *RGBStyle) Sprintf(format string, a ...interface{}) string {
|
||||
return RenderString(s.Code(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Code convert to color code string
|
||||
func (s *RGBStyle) Code() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// String convert to color code string
|
||||
func (s *RGBStyle) String() string {
|
||||
var ss []string
|
||||
// last value ensure is enable.
|
||||
if s.fg[3] == 1 {
|
||||
ss = append(ss, fmt.Sprintf(TplFgRGB, s.fg[0], s.fg[1], s.fg[2]))
|
||||
}
|
||||
|
||||
if s.bg[3] == 1 {
|
||||
ss = append(ss, fmt.Sprintf(TplBgRGB, s.bg[0], s.bg[1], s.bg[2]))
|
||||
}
|
||||
|
||||
if s.opts.IsValid() {
|
||||
ss = append(ss, s.opts.String())
|
||||
}
|
||||
|
||||
return strings.Join(ss, ";")
|
||||
}
|
||||
|
||||
// IsEmpty style
|
||||
func (s *RGBStyle) IsEmpty() bool {
|
||||
return s.fg[3] != 1 && s.bg[3] != 1
|
||||
}
|
181
vendor/github.com/gookit/color/color_windows.go
generated
vendored
Normal file
181
vendor/github.com/gookit/color/color_windows.go
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
// +build windows
|
||||
|
||||
// Display color on windows
|
||||
// refer:
|
||||
// golang.org/x/sys/windows
|
||||
// golang.org/x/crypto/ssh/terminal
|
||||
// https://docs.microsoft.com/en-us/windows/console
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// related docs
|
||||
// https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences
|
||||
// https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences#samples
|
||||
var (
|
||||
// isMSys bool
|
||||
kernel32 *syscall.LazyDLL
|
||||
|
||||
procGetConsoleMode *syscall.LazyProc
|
||||
procSetConsoleMode *syscall.LazyProc
|
||||
)
|
||||
|
||||
func init() {
|
||||
// if at windows's ConEmu, Cmder, putty ... terminals
|
||||
if supportColor {
|
||||
return
|
||||
}
|
||||
|
||||
isLikeInCmd = true
|
||||
|
||||
// if disabled.
|
||||
if !Enable {
|
||||
return
|
||||
}
|
||||
|
||||
// -------- try force enable colors on windows terminal -------
|
||||
|
||||
// init simple color code info
|
||||
// initWinColorsMap()
|
||||
|
||||
// load related windows dll
|
||||
// isMSys = utils.IsMSys()
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||
|
||||
// enable colors on windows terminal
|
||||
if tryApplyOnCONOUT() {
|
||||
// NOTICE: update var `supportColor` to TRUE.
|
||||
supportColor = true
|
||||
return
|
||||
}
|
||||
|
||||
if tryApplyOnStdout() {
|
||||
// NOTICE: update var `supportColor` to TRUE.
|
||||
supportColor = true
|
||||
}
|
||||
|
||||
// fetch console screen buffer info
|
||||
// err := getConsoleScreenBufferInfo(uintptr(syscall.Stdout), &defScreenInfo)
|
||||
}
|
||||
|
||||
func tryApplyOnCONOUT() bool {
|
||||
outHandle, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
|
||||
if err != nil {
|
||||
saveInternalError(err)
|
||||
return false
|
||||
}
|
||||
|
||||
err = EnableVirtualTerminalProcessing(outHandle, true)
|
||||
if err != nil {
|
||||
saveInternalError(err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func tryApplyOnStdout() bool {
|
||||
// try direct open syscall.Stdout
|
||||
err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
|
||||
if err != nil {
|
||||
saveInternalError(err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* render full color code on windows(8,16,24bit color)
|
||||
*************************************************************/
|
||||
|
||||
// docs https://docs.microsoft.com/zh-cn/windows/console/getconsolemode#parameters
|
||||
const (
|
||||
// equals to docs page's ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||
EnableVirtualTerminalProcessingMode uint32 = 0x4
|
||||
)
|
||||
|
||||
// EnableVirtualTerminalProcessing Enable virtual terminal processing
|
||||
//
|
||||
// ref from github.com/konsorten/go-windows-terminal-sequences
|
||||
// doc https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences#samples
|
||||
//
|
||||
// Usage:
|
||||
// err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
|
||||
// // support print color text
|
||||
// err = EnableVirtualTerminalProcessing(syscall.Stdout, false)
|
||||
func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error {
|
||||
var mode uint32
|
||||
// Check if it is currently in the terminal
|
||||
// err := syscall.GetConsoleMode(syscall.Stdout, &mode)
|
||||
err := syscall.GetConsoleMode(stream, &mode)
|
||||
if err != nil {
|
||||
fmt.Println(92, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if enable {
|
||||
mode |= EnableVirtualTerminalProcessingMode
|
||||
} else {
|
||||
mode &^= EnableVirtualTerminalProcessingMode
|
||||
}
|
||||
|
||||
ret, _, err := procSetConsoleMode.Call(uintptr(stream), uintptr(mode))
|
||||
if ret == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// renderColorCodeOnCmd enable cmd color render.
|
||||
// func renderColorCodeOnCmd(fn func()) {
|
||||
// err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
|
||||
// // if is not in terminal, will clear color tag.
|
||||
// if err != nil {
|
||||
// // panic(err)
|
||||
// fn()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // force open color render
|
||||
// old := ForceOpenColor()
|
||||
// fn()
|
||||
// // revert color setting
|
||||
// supportColor = old
|
||||
//
|
||||
// err = EnableVirtualTerminalProcessing(syscall.Stdout, false)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// }
|
||||
|
||||
/*************************************************************
|
||||
* render simple color code on windows
|
||||
*************************************************************/
|
||||
|
||||
// IsTty returns true if the given file descriptor is a terminal.
|
||||
func IsTty(fd uintptr) bool {
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
}
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
// Usage:
|
||||
// fd := os.Stdout.Fd()
|
||||
// fd := uintptr(syscall.Stdout) // for windows
|
||||
// IsTerminal(fd)
|
||||
func IsTerminal(fd int) bool {
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
}
|
5
vendor/github.com/gookit/color/go.mod
generated
vendored
Normal file
5
vendor/github.com/gookit/color/go.mod
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/gookit/color
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/stretchr/testify v1.3.0
|
22
vendor/github.com/gookit/color/go.sum
generated
vendored
Normal file
22
vendor/github.com/gookit/color/go.sum
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
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=
|
||||
github.com/go-playground/assert v1.2.1 h1:ad06XqC+TOv0nJWnbULSlh3ehp5uLuQEojZY5Tq8RgI=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gookit/color v1.2.9/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
|
||||
github.com/gookit/goutil v0.3.5 h1:95hWrCXcz7wuwlvcHw7YyUbFH0fV15YM0WPioYMcZww=
|
||||
github.com/gookit/goutil v0.3.5/go.mod h1:OHs5W5Xmfj4pCMXHnMxsDPrCc0SRbHLgJ2qs6wr5fxM=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
376
vendor/github.com/gookit/color/rgb_to_256.go
generated
vendored
Normal file
376
vendor/github.com/gookit/color/rgb_to_256.go
generated
vendored
Normal file
@ -0,0 +1,376 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// adapted from https://gist.github.com/MicahElliott/719710
|
||||
var (
|
||||
c256ToRgb = map[uint8]string{}
|
||||
|
||||
// rgb to 256 color look-up table
|
||||
lookupTable = map[string]uint8{
|
||||
// 8-bit, RGB hex
|
||||
|
||||
// Primary 3-bit (8 colors). Unique representation!
|
||||
"000000": 0,
|
||||
"800000": 1,
|
||||
"008000": 2,
|
||||
"808000": 3,
|
||||
"000080": 4,
|
||||
"800080": 5,
|
||||
"008080": 6,
|
||||
"c0c0c0": 7,
|
||||
|
||||
// Equivalent "bright" versions of original 8 colors.
|
||||
"808080": 8,
|
||||
"ff0000": 9,
|
||||
"00ff00": 10,
|
||||
"ffff00": 11,
|
||||
"0000ff": 12,
|
||||
"ff00ff": 13,
|
||||
"00ffff": 14,
|
||||
"ffffff": 15,
|
||||
|
||||
// values commented out below are duplicates from the prior sections
|
||||
|
||||
// Strictly ascending.
|
||||
// "000000": 16,
|
||||
"000001": 16, // up: avoid key conflicts, value + 1
|
||||
"00005f": 17,
|
||||
"000087": 18,
|
||||
"0000af": 19,
|
||||
"0000d7": 20,
|
||||
// "0000ff": 21,
|
||||
"0000fe": 21, // up: avoid key conflicts, value - 1
|
||||
"005f00": 22,
|
||||
"005f5f": 23,
|
||||
"005f87": 24,
|
||||
"005faf": 25,
|
||||
"005fd7": 26,
|
||||
"005fff": 27,
|
||||
"008700": 28,
|
||||
"00875f": 29,
|
||||
"008787": 30,
|
||||
"0087af": 31,
|
||||
"0087d7": 32,
|
||||
"0087ff": 33,
|
||||
"00af00": 34,
|
||||
"00af5f": 35,
|
||||
"00af87": 36,
|
||||
"00afaf": 37,
|
||||
"00afd7": 38,
|
||||
"00afff": 39,
|
||||
"00d700": 40,
|
||||
"00d75f": 41,
|
||||
"00d787": 42,
|
||||
"00d7af": 43,
|
||||
"00d7d7": 44,
|
||||
"00d7ff": 45,
|
||||
// "00ff00": 46,
|
||||
"00ff01": 46, // up: avoid key conflicts, value + 1
|
||||
"00ff5f": 47,
|
||||
"00ff87": 48,
|
||||
"00ffaf": 49,
|
||||
"00ffd7": 50,
|
||||
// "00ffff": 51,
|
||||
"00fffe": 51, // up: avoid key conflicts, value - 1
|
||||
"5f0000": 52,
|
||||
"5f005f": 53,
|
||||
"5f0087": 54,
|
||||
"5f00af": 55,
|
||||
"5f00d7": 56,
|
||||
"5f00ff": 57,
|
||||
"5f5f00": 58,
|
||||
"5f5f5f": 59,
|
||||
"5f5f87": 60,
|
||||
"5f5faf": 61,
|
||||
"5f5fd7": 62,
|
||||
"5f5fff": 63,
|
||||
"5f8700": 64,
|
||||
"5f875f": 65,
|
||||
"5f8787": 66,
|
||||
"5f87af": 67,
|
||||
"5f87d7": 68,
|
||||
"5f87ff": 69,
|
||||
"5faf00": 70,
|
||||
"5faf5f": 71,
|
||||
"5faf87": 72,
|
||||
"5fafaf": 73,
|
||||
"5fafd7": 74,
|
||||
"5fafff": 75,
|
||||
"5fd700": 76,
|
||||
"5fd75f": 77,
|
||||
"5fd787": 78,
|
||||
"5fd7af": 79,
|
||||
"5fd7d7": 80,
|
||||
"5fd7ff": 81,
|
||||
"5fff00": 82,
|
||||
"5fff5f": 83,
|
||||
"5fff87": 84,
|
||||
"5fffaf": 85,
|
||||
"5fffd7": 86,
|
||||
"5fffff": 87,
|
||||
"870000": 88,
|
||||
"87005f": 89,
|
||||
"870087": 90,
|
||||
"8700af": 91,
|
||||
"8700d7": 92,
|
||||
"8700ff": 93,
|
||||
"875f00": 94,
|
||||
"875f5f": 95,
|
||||
"875f87": 96,
|
||||
"875faf": 97,
|
||||
"875fd7": 98,
|
||||
"875fff": 99,
|
||||
"878700": 100,
|
||||
"87875f": 101,
|
||||
"878787": 102,
|
||||
"8787af": 103,
|
||||
"8787d7": 104,
|
||||
"8787ff": 105,
|
||||
"87af00": 106,
|
||||
"87af5f": 107,
|
||||
"87af87": 108,
|
||||
"87afaf": 109,
|
||||
"87afd7": 110,
|
||||
"87afff": 111,
|
||||
"87d700": 112,
|
||||
"87d75f": 113,
|
||||
"87d787": 114,
|
||||
"87d7af": 115,
|
||||
"87d7d7": 116,
|
||||
"87d7ff": 117,
|
||||
"87ff00": 118,
|
||||
"87ff5f": 119,
|
||||
"87ff87": 120,
|
||||
"87ffaf": 121,
|
||||
"87ffd7": 122,
|
||||
"87ffff": 123,
|
||||
"af0000": 124,
|
||||
"af005f": 125,
|
||||
"af0087": 126,
|
||||
"af00af": 127,
|
||||
"af00d7": 128,
|
||||
"af00ff": 129,
|
||||
"af5f00": 130,
|
||||
"af5f5f": 131,
|
||||
"af5f87": 132,
|
||||
"af5faf": 133,
|
||||
"af5fd7": 134,
|
||||
"af5fff": 135,
|
||||
"af8700": 136,
|
||||
"af875f": 137,
|
||||
"af8787": 138,
|
||||
"af87af": 139,
|
||||
"af87d7": 140,
|
||||
"af87ff": 141,
|
||||
"afaf00": 142,
|
||||
"afaf5f": 143,
|
||||
"afaf87": 144,
|
||||
"afafaf": 145,
|
||||
"afafd7": 146,
|
||||
"afafff": 147,
|
||||
"afd700": 148,
|
||||
"afd75f": 149,
|
||||
"afd787": 150,
|
||||
"afd7af": 151,
|
||||
"afd7d7": 152,
|
||||
"afd7ff": 153,
|
||||
"afff00": 154,
|
||||
"afff5f": 155,
|
||||
"afff87": 156,
|
||||
"afffaf": 157,
|
||||
"afffd7": 158,
|
||||
"afffff": 159,
|
||||
"d70000": 160,
|
||||
"d7005f": 161,
|
||||
"d70087": 162,
|
||||
"d700af": 163,
|
||||
"d700d7": 164,
|
||||
"d700ff": 165,
|
||||
"d75f00": 166,
|
||||
"d75f5f": 167,
|
||||
"d75f87": 168,
|
||||
"d75faf": 169,
|
||||
"d75fd7": 170,
|
||||
"d75fff": 171,
|
||||
"d78700": 172,
|
||||
"d7875f": 173,
|
||||
"d78787": 174,
|
||||
"d787af": 175,
|
||||
"d787d7": 176,
|
||||
"d787ff": 177,
|
||||
"d7af00": 178,
|
||||
"d7af5f": 179,
|
||||
"d7af87": 180,
|
||||
"d7afaf": 181,
|
||||
"d7afd7": 182,
|
||||
"d7afff": 183,
|
||||
"d7d700": 184,
|
||||
"d7d75f": 185,
|
||||
"d7d787": 186,
|
||||
"d7d7af": 187,
|
||||
"d7d7d7": 188,
|
||||
"d7d7ff": 189,
|
||||
"d7ff00": 190,
|
||||
"d7ff5f": 191,
|
||||
"d7ff87": 192,
|
||||
"d7ffaf": 193,
|
||||
"d7ffd7": 194,
|
||||
"d7ffff": 195,
|
||||
// "ff0000": 196,
|
||||
"ff0001": 196, // up: avoid key conflicts, value + 1
|
||||
"ff005f": 197,
|
||||
"ff0087": 198,
|
||||
"ff00af": 199,
|
||||
"ff00d7": 200,
|
||||
// "ff00ff": 201,
|
||||
"ff00fe": 201, // up: avoid key conflicts, value - 1
|
||||
"ff5f00": 202,
|
||||
"ff5f5f": 203,
|
||||
"ff5f87": 204,
|
||||
"ff5faf": 205,
|
||||
"ff5fd7": 206,
|
||||
"ff5fff": 207,
|
||||
"ff8700": 208,
|
||||
"ff875f": 209,
|
||||
"ff8787": 210,
|
||||
"ff87af": 211,
|
||||
"ff87d7": 212,
|
||||
"ff87ff": 213,
|
||||
"ffaf00": 214,
|
||||
"ffaf5f": 215,
|
||||
"ffaf87": 216,
|
||||
"ffafaf": 217,
|
||||
"ffafd7": 218,
|
||||
"ffafff": 219,
|
||||
"ffd700": 220,
|
||||
"ffd75f": 221,
|
||||
"ffd787": 222,
|
||||
"ffd7af": 223,
|
||||
"ffd7d7": 224,
|
||||
"ffd7ff": 225,
|
||||
// "ffff00": 226,
|
||||
"ffff01": 226, // up: avoid key conflicts, value + 1
|
||||
"ffff5f": 227,
|
||||
"ffff87": 228,
|
||||
"ffffaf": 229,
|
||||
"ffffd7": 230,
|
||||
// "ffffff": 231,
|
||||
"fffffe": 231, // up: avoid key conflicts, value - 1
|
||||
|
||||
// Gray-scale range.
|
||||
"080808": 232,
|
||||
"121212": 233,
|
||||
"1c1c1c": 234,
|
||||
"262626": 235,
|
||||
"303030": 236,
|
||||
"3a3a3a": 237,
|
||||
"444444": 238,
|
||||
"4e4e4e": 239,
|
||||
"585858": 240,
|
||||
"626262": 241,
|
||||
"6c6c6c": 242,
|
||||
"767676": 243,
|
||||
// "808080": 244,
|
||||
"808081": 244, // up: avoid key conflicts, value + 1
|
||||
"8a8a8a": 245,
|
||||
"949494": 246,
|
||||
"9e9e9e": 247,
|
||||
"a8a8a8": 248,
|
||||
"b2b2b2": 249,
|
||||
"bcbcbc": 250,
|
||||
"c6c6c6": 251,
|
||||
"d0d0d0": 252,
|
||||
"dadada": 253,
|
||||
"e4e4e4": 254,
|
||||
"eeeeee": 255,
|
||||
}
|
||||
|
||||
incs = []uint8{0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
|
||||
)
|
||||
|
||||
// RgbTo256Table mapping data
|
||||
func RgbTo256Table() map[string]uint8 {
|
||||
return lookupTable
|
||||
}
|
||||
|
||||
// Rgb2short convert RGB-code to 256-code
|
||||
func Rgb2short(r, g, b uint8) uint8 {
|
||||
res := make([]uint8, 3)
|
||||
for partI, part := range [3]uint8{r, g, b} {
|
||||
i := 0
|
||||
for i < len(incs)-1 {
|
||||
s, b := incs[i], incs[i+1] // smaller, bigger
|
||||
if s <= part && part <= b {
|
||||
s1 := math.Abs(float64(s) - float64(part))
|
||||
b1 := math.Abs(float64(b) - float64(part))
|
||||
var closest uint8
|
||||
if s1 < b1 {
|
||||
closest = s
|
||||
} else {
|
||||
closest = b
|
||||
}
|
||||
res[partI] = closest
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
hex := fmt.Sprintf("%02x%02x%02x", res[0], res[1], res[2])
|
||||
equiv := lookupTable[hex]
|
||||
return equiv
|
||||
}
|
||||
|
||||
// C256ToRgb convert an 256 color code to RGB numbers
|
||||
func C256ToRgb(val uint8) (rgb []uint8) {
|
||||
// TODO use sync.Once
|
||||
if len(c256ToRgb) == 0 {
|
||||
for hex, c256 := range lookupTable {
|
||||
c256ToRgb[c256] = hex
|
||||
}
|
||||
}
|
||||
|
||||
hex, ok := c256ToRgb[val]
|
||||
if false == ok {
|
||||
return
|
||||
}
|
||||
|
||||
// convert to rgb code
|
||||
rgbInts := Hex2rgb(hex)
|
||||
|
||||
return []uint8{
|
||||
uint8(rgbInts[0]),
|
||||
uint8(rgbInts[1]),
|
||||
uint8(rgbInts[2]),
|
||||
}
|
||||
}
|
||||
|
||||
// C256ToRgbV1 convert an 256 color code to RGB numbers
|
||||
// refer https://github.com/torvalds/linux/commit/cec5b2a97a11ade56a701e83044d0a2a984c67b4
|
||||
func C256ToRgbV1(val uint8) (rgb []uint8) {
|
||||
var r, g, b uint8
|
||||
if val < 8 { // Standard colours.
|
||||
// r = val&1 ? 0xaa : 0x00;
|
||||
r = compareVal(val&1 == 1, 0xaa, 0x00)
|
||||
g = compareVal(val&2 == 2, 0xaa, 0x00)
|
||||
b = compareVal(val&4 == 4, 0xaa, 0x00)
|
||||
} else if val < 16 {
|
||||
// r = val & 1 ? 0xff : 0x55;
|
||||
r = compareVal(val&1 == 1, 0xff, 0x55)
|
||||
g = compareVal(val&2 == 2, 0xff, 0x55)
|
||||
b = compareVal(val&4 == 4, 0xff, 0x55)
|
||||
} else if val < 232 { /* 6x6x6 colour cube. */
|
||||
r = (val - 16) / 36 * 85 / 2
|
||||
g = (val - 16) / 6 % 6 * 85 / 2
|
||||
b = (val - 16) % 6 * 85 / 2
|
||||
} else { /* Grayscale ramp. */
|
||||
nv := uint8(int(val)*10 - 2312)
|
||||
// set value
|
||||
r, g, b = nv, nv, nv
|
||||
}
|
||||
|
||||
return []uint8{r, g, b}
|
||||
}
|
285
vendor/github.com/gookit/color/style.go
generated
vendored
Normal file
285
vendor/github.com/gookit/color/style.go
generated
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*************************************************************
|
||||
* 16 color Style
|
||||
*************************************************************/
|
||||
|
||||
// Style a 16 color style. can add: fg color, bg color, color options
|
||||
//
|
||||
// Example:
|
||||
// color.Style{color.FgGreen}.Print("message")
|
||||
type Style []Color
|
||||
|
||||
// New create a custom style
|
||||
//
|
||||
// Usage:
|
||||
// color.New(color.FgGreen).Print("message")
|
||||
// equals to:
|
||||
// color.Style{color.FgGreen}.Print("message")
|
||||
func New(colors ...Color) Style {
|
||||
return colors
|
||||
}
|
||||
|
||||
// Save to styles map
|
||||
func (s Style) Save(name string) {
|
||||
AddStyle(name, s)
|
||||
}
|
||||
|
||||
// Render render text
|
||||
// Usage:
|
||||
// color.New(color.FgGreen).Render("text")
|
||||
// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text")
|
||||
func (s Style) Render(a ...interface{}) string {
|
||||
return RenderCode(s.String(), a...)
|
||||
}
|
||||
|
||||
// Renderln render text line.
|
||||
// like Println, will add spaces for each argument
|
||||
// Usage:
|
||||
// color.New(color.FgGreen).Renderln("text", "more")
|
||||
// color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text", "more")
|
||||
func (s Style) Renderln(a ...interface{}) string {
|
||||
return RenderWithSpaces(s.String(), a...)
|
||||
}
|
||||
|
||||
// Sprint is alias of the 'Render'
|
||||
func (s Style) Sprint(a ...interface{}) string {
|
||||
return RenderCode(s.String(), a...)
|
||||
}
|
||||
|
||||
// Sprintf format and render message.
|
||||
func (s Style) Sprintf(format string, a ...interface{}) string {
|
||||
return RenderString(s.String(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Print render and Print text
|
||||
func (s Style) Print(a ...interface{}) {
|
||||
doPrintV2(s.String(), fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Printf render and print text
|
||||
func (s Style) Printf(format string, a ...interface{}) {
|
||||
doPrintV2(s.Code(), fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Println render and print text line
|
||||
func (s Style) Println(a ...interface{}) {
|
||||
doPrintlnV2(s.String(), a)
|
||||
}
|
||||
|
||||
// Code convert to code string. returns like "32;45;3"
|
||||
func (s Style) Code() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// String convert to code string. returns like "32;45;3"
|
||||
func (s Style) String() string {
|
||||
return Colors2code(s...)
|
||||
}
|
||||
|
||||
// IsEmpty style
|
||||
func (s Style) IsEmpty() bool {
|
||||
return len(s) == 0
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Theme(extended Style)
|
||||
*************************************************************/
|
||||
|
||||
// Theme definition. extends from Style
|
||||
type Theme struct {
|
||||
// Name theme name
|
||||
Name string
|
||||
// Style for the theme
|
||||
Style
|
||||
}
|
||||
|
||||
// NewTheme instance
|
||||
func NewTheme(name string, style Style) *Theme {
|
||||
return &Theme{name, style}
|
||||
}
|
||||
|
||||
// Save to themes map
|
||||
func (t *Theme) Save() {
|
||||
AddTheme(t.Name, t.Style)
|
||||
}
|
||||
|
||||
// Tips use name as title, only apply style for name
|
||||
func (t *Theme) Tips(format string, a ...interface{}) {
|
||||
// only apply style for name
|
||||
t.Print(strings.ToUpper(t.Name) + ": ")
|
||||
Printf(format+"\n", a...)
|
||||
}
|
||||
|
||||
// Prompt use name as title, and apply style for message
|
||||
func (t *Theme) Prompt(format string, a ...interface{}) {
|
||||
title := strings.ToUpper(t.Name) + ":"
|
||||
t.Println(title, fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Block like Prompt, but will wrap a empty line
|
||||
func (t *Theme) Block(format string, a ...interface{}) {
|
||||
title := strings.ToUpper(t.Name) + ":\n"
|
||||
|
||||
t.Println(title, fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Theme: internal themes
|
||||
*************************************************************/
|
||||
|
||||
// internal themes(like bootstrap style)
|
||||
// Usage:
|
||||
// color.Info.Print("message")
|
||||
// color.Info.Printf("a %s message", "test")
|
||||
// color.Warn.Println("message")
|
||||
// color.Error.Println("message")
|
||||
var (
|
||||
// Info color style
|
||||
Info = &Theme{"info", Style{OpReset, FgGreen}}
|
||||
// Note color style
|
||||
Note = &Theme{"note", Style{OpBold, FgLightCyan}}
|
||||
// Warn color style
|
||||
Warn = &Theme{"warning", Style{OpBold, FgYellow}}
|
||||
// Light color style
|
||||
Light = &Theme{"light", Style{FgLightWhite, BgBlack}}
|
||||
// Error color style
|
||||
Error = &Theme{"error", Style{FgLightWhite, BgRed}}
|
||||
// Danger color style
|
||||
Danger = &Theme{"danger", Style{OpBold, FgRed}}
|
||||
// Debug color style
|
||||
Debug = &Theme{"debug", Style{OpReset, FgCyan}}
|
||||
// Notice color style
|
||||
Notice = &Theme{"notice", Style{OpBold, FgCyan}}
|
||||
// Comment color style
|
||||
Comment = &Theme{"comment", Style{OpReset, FgYellow}}
|
||||
// Success color style
|
||||
Success = &Theme{"success", Style{OpBold, FgGreen}}
|
||||
// Primary color style
|
||||
Primary = &Theme{"primary", Style{OpReset, FgBlue}}
|
||||
// Question color style
|
||||
Question = &Theme{"question", Style{OpReset, FgMagenta}}
|
||||
// Secondary color style
|
||||
Secondary = &Theme{"secondary", Style{FgDarkGray}}
|
||||
)
|
||||
|
||||
// Themes internal defined themes.
|
||||
// Usage:
|
||||
// color.Themes["info"].Println("message")
|
||||
var Themes = map[string]*Theme{
|
||||
"info": Info,
|
||||
"note": Note,
|
||||
"light": Light,
|
||||
"error": Error,
|
||||
|
||||
"debug": Debug,
|
||||
"danger": Danger,
|
||||
"notice": Notice,
|
||||
"success": Success,
|
||||
"comment": Comment,
|
||||
"primary": Primary,
|
||||
"warning": Warn,
|
||||
|
||||
"question": Question,
|
||||
"secondary": Secondary,
|
||||
}
|
||||
|
||||
// AddTheme add a theme and style
|
||||
func AddTheme(name string, style Style) {
|
||||
Themes[name] = NewTheme(name, style)
|
||||
Styles[name] = style
|
||||
}
|
||||
|
||||
// GetTheme get defined theme by name
|
||||
func GetTheme(name string) *Theme {
|
||||
return Themes[name]
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* internal styles
|
||||
*************************************************************/
|
||||
|
||||
// Styles internal defined styles, like bootstrap styles.
|
||||
// Usage:
|
||||
// color.Styles["info"].Println("message")
|
||||
var Styles = map[string]Style{
|
||||
"info": {OpReset, FgGreen},
|
||||
"note": {OpBold, FgLightCyan},
|
||||
"light": {FgLightWhite, BgRed},
|
||||
"error": {FgLightWhite, BgRed},
|
||||
|
||||
"danger": {OpBold, FgRed},
|
||||
"notice": {OpBold, FgCyan},
|
||||
"success": {OpBold, FgGreen},
|
||||
"comment": {OpReset, FgMagenta},
|
||||
"primary": {OpReset, FgBlue},
|
||||
"warning": {OpBold, FgYellow},
|
||||
|
||||
"question": {OpReset, FgMagenta},
|
||||
"secondary": {FgDarkGray},
|
||||
}
|
||||
|
||||
// some style name alias
|
||||
var styleAliases = map[string]string{
|
||||
"err": "error",
|
||||
"suc": "success",
|
||||
"warn": "warning",
|
||||
}
|
||||
|
||||
// AddStyle add a style
|
||||
func AddStyle(name string, s Style) {
|
||||
Styles[name] = s
|
||||
}
|
||||
|
||||
// GetStyle get defined style by name
|
||||
func GetStyle(name string) Style {
|
||||
if s, ok := Styles[name]; ok {
|
||||
return s
|
||||
}
|
||||
|
||||
if realName, ok := styleAliases[name]; ok {
|
||||
return Styles[realName]
|
||||
}
|
||||
|
||||
// empty style
|
||||
return New()
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* quick use style print message
|
||||
*************************************************************/
|
||||
|
||||
// Infof print message with Info style
|
||||
func Infof(format string, a ...interface{}) {
|
||||
Info.Printf(format, a...)
|
||||
}
|
||||
|
||||
// Infoln print message with Info style
|
||||
func Infoln(a ...interface{}) {
|
||||
Info.Println(a...)
|
||||
}
|
||||
|
||||
// Errorf print message with Error style
|
||||
func Errorf(format string, a ...interface{}) {
|
||||
Error.Printf(format, a...)
|
||||
}
|
||||
|
||||
// Errorln print message with Error style
|
||||
func Errorln(a ...interface{}) {
|
||||
Error.Println(a...)
|
||||
}
|
||||
|
||||
// Warnf print message with Warn style
|
||||
func Warnf(format string, a ...interface{}) {
|
||||
Warn.Printf(format, a...)
|
||||
}
|
||||
|
||||
// Warnln print message with Warn style
|
||||
func Warnln(a ...interface{}) {
|
||||
Warn.Println(a...)
|
||||
}
|
310
vendor/github.com/gookit/color/tag.go
generated
vendored
Normal file
310
vendor/github.com/gookit/color/tag.go
generated
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// output colored text like use html tag. (not support windows cmd)
|
||||
const (
|
||||
// MatchExpr regex to match color tags
|
||||
// Notice: golang 不支持反向引用. 即不支持使用 \1 引用第一个匹配 ([a-z=;]+)
|
||||
// MatchExpr = `<([a-z=;]+)>(.*?)<\/\1>`
|
||||
// 所以调整一下 统一使用 `</>` 来结束标签,例如 "<info>some text</>"
|
||||
// 支持自定义颜色属性的tag "<fg=white;bg=blue;op=bold>content</>"
|
||||
// (?s:...) s - 让 "." 匹配换行
|
||||
MatchExpr = `<([a-zA-Z_=,;]+)>(?s:(.*?))<\/>`
|
||||
|
||||
// AttrExpr regex to match color attributes
|
||||
AttrExpr = `(fg|bg|op)[\s]*=[\s]*([a-zA-Z,]+);?`
|
||||
|
||||
// StripExpr regex used for removing color tags
|
||||
// StripExpr = `<[\/]?[a-zA-Z=;]+>`
|
||||
// 随着上面的做一些调整
|
||||
StripExpr = `<[\/]?[a-zA-Z_=,;]*>`
|
||||
)
|
||||
|
||||
var (
|
||||
attrRegex = regexp.MustCompile(AttrExpr)
|
||||
matchRegex = regexp.MustCompile(MatchExpr)
|
||||
stripRegex = regexp.MustCompile(StripExpr)
|
||||
)
|
||||
|
||||
/*************************************************************
|
||||
* internal defined color tags
|
||||
*************************************************************/
|
||||
|
||||
// Some internal defined color tags
|
||||
// Usage: <tag>content text</>
|
||||
// @notice 加 0 在前面是为了防止之前的影响到现在的设置
|
||||
var colorTags = map[string]string{
|
||||
// basic tags,
|
||||
"red": "0;31",
|
||||
"blue": "0;34",
|
||||
"cyan": "0;36",
|
||||
"black": "0;30",
|
||||
"green": "0;32",
|
||||
"white": "1;37",
|
||||
"default": "0;39", // no color
|
||||
"normal": "0;39", // no color
|
||||
"brown": "0;33",
|
||||
"yellow": "1;33",
|
||||
"mga": "0;35", // short name
|
||||
"magenta": "0;35",
|
||||
"mgb": "1;35", // short name
|
||||
"magentaB": "1;35", // add bold
|
||||
|
||||
// alert tags, like bootstrap's alert
|
||||
"suc": "1;32", // same "green" and "bold"
|
||||
"success": "1;32",
|
||||
"info": "0;32", // same "green",
|
||||
"comment": "0;33", // same "brown"
|
||||
"note": "36;1",
|
||||
"notice": "36;4",
|
||||
"warn": "0;1;33",
|
||||
"warning": "0;30;43",
|
||||
"primary": "0;34",
|
||||
"danger": "1;31", // same "red" but add bold
|
||||
"err": "97;41",
|
||||
"error": "97;41", // fg light white; bg red
|
||||
|
||||
// more tags
|
||||
"lightRed": "1;31",
|
||||
"light_red": "1;31",
|
||||
"lightGreen": "1;32",
|
||||
"light_green": "1;32",
|
||||
"lightBlue": "1;34",
|
||||
"light_blue": "1;34",
|
||||
"lightCyan": "1;36",
|
||||
"light_cyan": "1;36",
|
||||
"lightDray": "0;37",
|
||||
"light_gray": "0;37",
|
||||
"gray": "0;90",
|
||||
"darkGray": "0;90",
|
||||
"dark_gray": "0;90",
|
||||
"lightYellow": "0;93",
|
||||
"light_yellow": "0;93",
|
||||
"lightMagenta": "0;95",
|
||||
"light_magenta": "0;95",
|
||||
|
||||
// extra
|
||||
"lightRedEx": "0;91",
|
||||
"light_red_ex": "0;91",
|
||||
"lightGreenEx": "0;92",
|
||||
"light_green_ex": "0;92",
|
||||
"lightBlueEx": "0;94",
|
||||
"light_blue_ex": "0;94",
|
||||
"lightCyanEx": "0;96",
|
||||
"light_cyan_ex": "0;96",
|
||||
"whiteEx": "0;97;40",
|
||||
"white_ex": "0;97;40",
|
||||
|
||||
// option
|
||||
"bold": "1",
|
||||
"underscore": "4",
|
||||
"reverse": "7",
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* parse color tags
|
||||
*************************************************************/
|
||||
|
||||
// ReplaceTag parse string, replace color tag and return rendered string
|
||||
func ReplaceTag(str string) string {
|
||||
// disable handler TAG OR not contains color tag
|
||||
if !RenderTag || !strings.Contains(str, "</>") {
|
||||
return str
|
||||
}
|
||||
|
||||
// disabled OR not support color
|
||||
if !Enable || !supportColor {
|
||||
return ClearTag(str)
|
||||
}
|
||||
|
||||
// find color tags by regex
|
||||
matched := matchRegex.FindAllStringSubmatch(str, -1)
|
||||
|
||||
// item: 0 full text 1 tag name 2 tag content
|
||||
for _, item := range matched {
|
||||
full, tag, content := item[0], item[1], item[2]
|
||||
|
||||
// custom color in tag: "<fg=white;bg=blue;op=bold>content</>"
|
||||
if code := ParseCodeFromAttr(tag); len(code) > 0 {
|
||||
now := RenderString(code, content)
|
||||
str = strings.Replace(str, full, now, 1)
|
||||
continue
|
||||
}
|
||||
|
||||
// use defined tag: "<tag>content</>"
|
||||
if code := GetTagCode(tag); len(code) > 0 {
|
||||
now := RenderString(code, content)
|
||||
// old := WrapTag(content, tag) is equals to var 'full'
|
||||
str = strings.Replace(str, full, now, 1)
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// ParseCodeFromAttr parse color attributes.
|
||||
// attr like:
|
||||
// "fg=VALUE;bg=VALUE;op=VALUE" // VALUE please see var: FgColors, BgColors, AllOptions
|
||||
// eg:
|
||||
// "fg=yellow"
|
||||
// "bg=red"
|
||||
// "op=bold,underscore" option is allow multi value
|
||||
// "fg=white;bg=blue;op=bold"
|
||||
// "fg=white;op=bold,underscore"
|
||||
func ParseCodeFromAttr(attr string) (code string) {
|
||||
if !strings.Contains(attr, "=") {
|
||||
return
|
||||
}
|
||||
|
||||
attr = strings.Trim(attr, ";=,")
|
||||
if len(attr) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var colors []Color
|
||||
|
||||
matched := attrRegex.FindAllStringSubmatch(attr, -1)
|
||||
for _, item := range matched {
|
||||
pos, val := item[1], item[2]
|
||||
switch pos {
|
||||
case "fg":
|
||||
if c, ok := FgColors[val]; ok { // basic fg
|
||||
colors = append(colors, c)
|
||||
} else if c, ok := ExFgColors[val]; ok { // extra fg
|
||||
colors = append(colors, c)
|
||||
}
|
||||
case "bg":
|
||||
if c, ok := BgColors[val]; ok { // basic bg
|
||||
colors = append(colors, c)
|
||||
} else if c, ok := ExBgColors[val]; ok { // extra bg
|
||||
colors = append(colors, c)
|
||||
}
|
||||
case "op": // options allow multi value
|
||||
if strings.Contains(val, ",") {
|
||||
ns := strings.Split(val, ",")
|
||||
for _, n := range ns {
|
||||
if c, ok := AllOptions[n]; ok {
|
||||
colors = append(colors, c)
|
||||
}
|
||||
}
|
||||
} else if c, ok := AllOptions[val]; ok {
|
||||
colors = append(colors, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Colors2code(colors...)
|
||||
}
|
||||
|
||||
// ClearTag clear all tag for a string
|
||||
func ClearTag(s string) string {
|
||||
if !strings.Contains(s, "</>") {
|
||||
return s
|
||||
}
|
||||
|
||||
return stripRegex.ReplaceAllString(s, "")
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* helper methods
|
||||
*************************************************************/
|
||||
|
||||
// GetTagCode get color code by tag name
|
||||
func GetTagCode(name string) string {
|
||||
if code, ok := colorTags[name]; ok {
|
||||
return code
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// ApplyTag for messages
|
||||
func ApplyTag(tag string, a ...interface{}) string {
|
||||
return RenderCode(GetTagCode(tag), a...)
|
||||
}
|
||||
|
||||
// WrapTag wrap a tag for a string "<tag>content</>"
|
||||
func WrapTag(s string, tag string) string {
|
||||
if s == "" || tag == "" {
|
||||
return s
|
||||
}
|
||||
|
||||
return fmt.Sprintf("<%s>%s</>", tag, s)
|
||||
}
|
||||
|
||||
// GetColorTags get all internal color tags
|
||||
func GetColorTags() map[string]string {
|
||||
return colorTags
|
||||
}
|
||||
|
||||
// IsDefinedTag is defined tag name
|
||||
func IsDefinedTag(name string) bool {
|
||||
_, ok := colorTags[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Tag extra
|
||||
*************************************************************/
|
||||
|
||||
// Tag value is a defined style name
|
||||
// Usage:
|
||||
// Tag("info").Println("message")
|
||||
type Tag string
|
||||
|
||||
// Print messages
|
||||
func (tg Tag) Print(a ...interface{}) {
|
||||
name := string(tg)
|
||||
str := fmt.Sprint(a...)
|
||||
|
||||
if stl := GetStyle(name); !stl.IsEmpty() {
|
||||
stl.Print(str)
|
||||
} else {
|
||||
doPrintV2(GetTagCode(name), str)
|
||||
}
|
||||
}
|
||||
|
||||
// Printf format and print messages
|
||||
func (tg Tag) Printf(format string, a ...interface{}) {
|
||||
name := string(tg)
|
||||
str := fmt.Sprintf(format, a...)
|
||||
|
||||
if stl := GetStyle(name); !stl.IsEmpty() {
|
||||
stl.Print(str)
|
||||
} else {
|
||||
doPrintV2(GetTagCode(name), str)
|
||||
}
|
||||
}
|
||||
|
||||
// Println messages line
|
||||
func (tg Tag) Println(a ...interface{}) {
|
||||
name := string(tg)
|
||||
if stl := GetStyle(name); !stl.IsEmpty() {
|
||||
stl.Println(a...)
|
||||
} else {
|
||||
doPrintlnV2(GetTagCode(name), a)
|
||||
}
|
||||
}
|
||||
|
||||
// Sprint render messages
|
||||
func (tg Tag) Sprint(a ...interface{}) string {
|
||||
name := string(tg)
|
||||
// if stl := GetStyle(name); !stl.IsEmpty() {
|
||||
// return stl.Render(args...)
|
||||
// }
|
||||
|
||||
return RenderCode(GetTagCode(name), a...)
|
||||
}
|
||||
|
||||
// Sprintf format and render messages
|
||||
func (tg Tag) Sprintf(format string, a ...interface{}) string {
|
||||
tag := string(tg)
|
||||
str := fmt.Sprintf(format, a...)
|
||||
|
||||
return RenderString(GetTagCode(tag), str)
|
||||
}
|
448
vendor/github.com/gookit/color/utils.go
generated
vendored
Normal file
448
vendor/github.com/gookit/color/utils.go
generated
vendored
Normal file
@ -0,0 +1,448 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Support color:
|
||||
// "TERM=xterm"
|
||||
// "TERM=xterm-vt220"
|
||||
// "TERM=xterm-256color"
|
||||
// "TERM=screen-256color"
|
||||
// "TERM=tmux-256color"
|
||||
// "TERM=rxvt-unicode-256color"
|
||||
// Don't support color:
|
||||
// "TERM=cygwin"
|
||||
var specialColorTerms = map[string]bool{
|
||||
"alacritty": true,
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* helper methods for check env
|
||||
*************************************************************/
|
||||
|
||||
// IsConsole Determine whether w is one of stderr, stdout, stdin
|
||||
func IsConsole(w io.Writer) bool {
|
||||
o, ok := w.(*os.File)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
fd := o.Fd()
|
||||
|
||||
// fix: cannot use 'o == os.Stdout' to compare
|
||||
return fd == uintptr(syscall.Stdout) || fd == uintptr(syscall.Stdin) || fd == uintptr(syscall.Stderr)
|
||||
}
|
||||
|
||||
// IsMSys msys(MINGW64) environment, does not necessarily support color
|
||||
func IsMSys() bool {
|
||||
// like "MSYSTEM=MINGW64"
|
||||
if len(os.Getenv("MSYSTEM")) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsSupportColor check current console is support color.
|
||||
//
|
||||
// Supported:
|
||||
// linux, mac, or windows's ConEmu, Cmder, putty, git-bash.exe
|
||||
// Not support:
|
||||
// windows cmd.exe, powerShell.exe
|
||||
func IsSupportColor() bool {
|
||||
envTerm := os.Getenv("TERM")
|
||||
if strings.Contains(envTerm, "term") {
|
||||
return true
|
||||
}
|
||||
|
||||
// it's special color term
|
||||
if _, ok := specialColorTerms[envTerm]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
// like on ConEmu software, e.g "ConEmuANSI=ON"
|
||||
if os.Getenv("ConEmuANSI") == "ON" {
|
||||
return true
|
||||
}
|
||||
|
||||
// like on ConEmu software, e.g "ANSICON=189x2000 (189x43)"
|
||||
if os.Getenv("ANSICON") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// up: if support 256-color, can also support basic color.
|
||||
return isSupport256Color(envTerm)
|
||||
}
|
||||
|
||||
// IsSupport256Color render
|
||||
func IsSupport256Color() bool {
|
||||
return isSupport256Color(os.Getenv("TERM"))
|
||||
}
|
||||
|
||||
func isSupport256Color(termVal string) bool {
|
||||
// "TERM=xterm-256color"
|
||||
// "TERM=screen-256color"
|
||||
// "TERM=tmux-256color"
|
||||
// "TERM=rxvt-unicode-256color"
|
||||
supported := strings.Contains(termVal, "256color")
|
||||
if !supported {
|
||||
// up: if support true-color, can also support 256-color.
|
||||
supported = IsSupportTrueColor()
|
||||
}
|
||||
|
||||
return supported
|
||||
}
|
||||
|
||||
// IsSupportTrueColor render. IsSupportRGBColor
|
||||
func IsSupportTrueColor() bool {
|
||||
val := os.Getenv("COLORTERM")
|
||||
// "COLORTERM=truecolor"
|
||||
// "COLORTERM=24bit"
|
||||
return strings.Contains(val, "truecolor") || strings.Contains(val, "24bit")
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* helper methods for converts
|
||||
*************************************************************/
|
||||
|
||||
// Colors2code convert colors to code. return like "32;45;3"
|
||||
func Colors2code(colors ...Color) string {
|
||||
if len(colors) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var codes []string
|
||||
for _, color := range colors {
|
||||
codes = append(codes, color.String())
|
||||
}
|
||||
|
||||
return strings.Join(codes, ";")
|
||||
}
|
||||
|
||||
// Hex2rgb alias of the HexToRgb()
|
||||
func Hex2rgb(hex string) []int { return HexToRgb(hex) }
|
||||
|
||||
// HexToRGB alias of the HexToRgb()
|
||||
func HexToRGB(hex string) []int { return HexToRgb(hex) }
|
||||
|
||||
// HexToRgb convert hex color string to RGB numbers
|
||||
// Usage:
|
||||
// rgb := HexToRgb("ccc") // rgb: [204 204 204]
|
||||
// rgb := HexToRgb("aabbcc") // rgb: [170 187 204]
|
||||
// rgb := HexToRgb("#aabbcc") // rgb: [170 187 204]
|
||||
// rgb := HexToRgb("0xad99c0") // rgb: [170 187 204]
|
||||
func HexToRgb(hex string) (rgb []int) {
|
||||
hex = strings.TrimSpace(hex)
|
||||
if hex == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// like from css. eg "#ccc" "#ad99c0"
|
||||
if hex[0] == '#' {
|
||||
hex = hex[1:]
|
||||
}
|
||||
|
||||
hex = strings.ToLower(hex)
|
||||
switch len(hex) {
|
||||
case 3: // "ccc"
|
||||
hex = string([]byte{hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]})
|
||||
case 8: // "0xad99c0"
|
||||
hex = strings.TrimPrefix(hex, "0x")
|
||||
}
|
||||
|
||||
// recheck
|
||||
if len(hex) != 6 {
|
||||
return
|
||||
}
|
||||
|
||||
// convert string to int64
|
||||
if i64, err := strconv.ParseInt(hex, 16, 32); err == nil {
|
||||
color := int(i64)
|
||||
// parse int
|
||||
rgb = make([]int, 3)
|
||||
rgb[0] = color >> 16
|
||||
rgb[1] = (color & 0x00FF00) >> 8
|
||||
rgb[2] = color & 0x0000FF
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Rgb2hex alias of the RgbToHex()
|
||||
func Rgb2hex(rgb []int) string { return RgbToHex(rgb) }
|
||||
|
||||
// RgbToHex convert RGB-code to hex-code
|
||||
// Usage:
|
||||
// hex := RgbToHex([]int{170, 187, 204}) // hex: "aabbcc"
|
||||
func RgbToHex(rgb []int) string {
|
||||
hexNodes := make([]string, len(rgb))
|
||||
for _, v := range rgb {
|
||||
hexNodes = append(hexNodes, strconv.FormatInt(int64(v), 16))
|
||||
}
|
||||
|
||||
return strings.Join(hexNodes, "")
|
||||
}
|
||||
|
||||
// Rgb2ansi alias of the RgbToAnsi()
|
||||
func Rgb2ansi(r, g, b uint8, isBg bool) uint8 {
|
||||
return RgbToAnsi(r, g, b, isBg)
|
||||
}
|
||||
|
||||
// RgbToAnsi convert RGB-code to 16-code
|
||||
// refer https://github.com/radareorg/radare2/blob/master/libr/cons/rgb.c#L249-L271
|
||||
func RgbToAnsi(r, g, b uint8, isBg bool) uint8 {
|
||||
var bright, c, k uint8
|
||||
|
||||
base := compareVal(isBg, BgBase, FgBase)
|
||||
|
||||
// eco bright-specific
|
||||
if r == 0x80 && g == 0x80 && b == 0x80 { // 0x80=128
|
||||
bright = 53
|
||||
} else if r == 0xff || g == 0xff || b == 0xff { // 0xff=255
|
||||
bright = 60
|
||||
} // else bright = 0
|
||||
|
||||
if r == g && g == b {
|
||||
// 0x7f=127
|
||||
// r = (r > 0x7f) ? 1 : 0;
|
||||
r = compareVal(r > 0x7f, 1, 0)
|
||||
g = compareVal(g > 0x7f, 1, 0)
|
||||
b = compareVal(b > 0x7f, 1, 0)
|
||||
} else {
|
||||
k = (r + g + b) / 3
|
||||
|
||||
// r = (r >= k) ? 1 : 0;
|
||||
r = compareVal(r >= k, 1, 0)
|
||||
g = compareVal(g >= k, 1, 0)
|
||||
b = compareVal(b >= k, 1, 0)
|
||||
}
|
||||
|
||||
// c = (r ? 1 : 0) + (g ? (b ? 6 : 2) : (b ? 4 : 0))
|
||||
c = compareVal(r > 0, 1, 0)
|
||||
|
||||
if g > 0 {
|
||||
c += compareVal(b > 0, 6, 2)
|
||||
} else {
|
||||
c += compareVal(b > 0, 4, 0)
|
||||
}
|
||||
|
||||
return base + bright + c
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* print methods(will auto parse color tags)
|
||||
*************************************************************/
|
||||
|
||||
// Print render color tag and print messages
|
||||
func Print(a ...interface{}) {
|
||||
Fprint(output, a...)
|
||||
}
|
||||
|
||||
// Printf format and print messages
|
||||
func Printf(format string, a ...interface{}) {
|
||||
Fprintf(output, format, a...)
|
||||
}
|
||||
|
||||
// Println messages with new line
|
||||
func Println(a ...interface{}) {
|
||||
Fprintln(output, a...)
|
||||
}
|
||||
|
||||
// Fprint print rendered messages to writer
|
||||
// Notice: will ignore print error
|
||||
func Fprint(w io.Writer, a ...interface{}) {
|
||||
_, err := fmt.Fprint(w, Render(a...))
|
||||
saveInternalError(err)
|
||||
|
||||
// if isLikeInCmd {
|
||||
// renderColorCodeOnCmd(func() {
|
||||
// _, _ = fmt.Fprint(w, Render(a...))
|
||||
// })
|
||||
// } else {
|
||||
// _, _ = fmt.Fprint(w, Render(a...))
|
||||
// }
|
||||
}
|
||||
|
||||
// Fprintf print format and rendered messages to writer.
|
||||
// Notice: will ignore print error
|
||||
func Fprintf(w io.Writer, format string, a ...interface{}) {
|
||||
str := fmt.Sprintf(format, a...)
|
||||
_, err := fmt.Fprint(w, ReplaceTag(str))
|
||||
saveInternalError(err)
|
||||
|
||||
// if isLikeInCmd {
|
||||
// renderColorCodeOnCmd(func() {
|
||||
// _, _ = fmt.Fprint(w, ReplaceTag(str))
|
||||
// })
|
||||
// } else {
|
||||
// _, _ = fmt.Fprint(w, ReplaceTag(str))
|
||||
// }
|
||||
}
|
||||
|
||||
// Fprintln print rendered messages line to writer
|
||||
// Notice: will ignore print error
|
||||
func Fprintln(w io.Writer, a ...interface{}) {
|
||||
str := formatArgsForPrintln(a)
|
||||
_, err := fmt.Fprintln(w, ReplaceTag(str))
|
||||
saveInternalError(err)
|
||||
}
|
||||
|
||||
// Lprint passes colored messages to a log.Logger for printing.
|
||||
// Notice: should be goroutine safe
|
||||
func Lprint(l *log.Logger, a ...interface{}) {
|
||||
l.Print(Render(a...))
|
||||
}
|
||||
|
||||
// Render parse color tags, return rendered string.
|
||||
// Usage:
|
||||
// text := Render("<info>hello</> <cyan>world</>!")
|
||||
// fmt.Println(text)
|
||||
func Render(a ...interface{}) string {
|
||||
if len(a) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return ReplaceTag(fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Sprint parse color tags, return rendered string
|
||||
func Sprint(a ...interface{}) string {
|
||||
if len(a) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return ReplaceTag(fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Sprintf format and return rendered string
|
||||
func Sprintf(format string, a ...interface{}) string {
|
||||
return ReplaceTag(fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// String alias of the ReplaceTag
|
||||
func String(s string) string {
|
||||
return ReplaceTag(s)
|
||||
}
|
||||
|
||||
// Text alias of the ReplaceTag
|
||||
func Text(s string) string {
|
||||
return ReplaceTag(s)
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* helper methods for print
|
||||
*************************************************************/
|
||||
|
||||
// new implementation, support render full color code on pwsh.exe, cmd.exe
|
||||
func doPrintV2(code, str string) {
|
||||
_, err := fmt.Fprint(output, RenderString(code, str))
|
||||
saveInternalError(err)
|
||||
|
||||
// if isLikeInCmd {
|
||||
// renderColorCodeOnCmd(func() {
|
||||
// _, _ = fmt.Fprint(output, RenderString(code, str))
|
||||
// })
|
||||
// } else {
|
||||
// _, _ = fmt.Fprint(output, RenderString(code, str))
|
||||
// }
|
||||
}
|
||||
|
||||
// new implementation, support render full color code on pwsh.exe, cmd.exe
|
||||
func doPrintlnV2(code string, args []interface{}) {
|
||||
str := formatArgsForPrintln(args)
|
||||
_, err := fmt.Fprintln(output, RenderString(code, str))
|
||||
saveInternalError(err)
|
||||
|
||||
// if isLikeInCmd {
|
||||
// renderColorCodeOnCmd(func() {
|
||||
// _, _ = fmt.Fprintln(output, RenderString(code, str))
|
||||
// })
|
||||
// } else {
|
||||
// _, _ = fmt.Fprintln(output, RenderString(code, str))
|
||||
// }
|
||||
}
|
||||
|
||||
// if use Println, will add spaces for each arg
|
||||
func formatArgsForPrintln(args []interface{}) (message string) {
|
||||
if ln := len(args); ln == 0 {
|
||||
message = ""
|
||||
} else if ln == 1 {
|
||||
message = fmt.Sprint(args[0])
|
||||
} else {
|
||||
message = fmt.Sprintln(args...)
|
||||
// clear last "\n"
|
||||
message = message[:len(message)-1]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* helper methods
|
||||
*************************************************************/
|
||||
|
||||
// its Win system. linux windows darwin
|
||||
// func isWindows() bool {
|
||||
// return runtime.GOOS == "windows"
|
||||
// }
|
||||
|
||||
// equals: return ok ? val1 : val2
|
||||
func compareVal(ok bool, val1, val2 uint8) uint8 {
|
||||
if ok {
|
||||
return val1
|
||||
}
|
||||
return val2
|
||||
}
|
||||
|
||||
func saveInternalError(err error) {
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
func stringToArr(str, sep string) (arr []string) {
|
||||
str = strings.TrimSpace(str)
|
||||
if str == "" {
|
||||
return
|
||||
}
|
||||
|
||||
ss := strings.Split(str, sep)
|
||||
for _, val := range ss {
|
||||
if val = strings.TrimSpace(val); val != "" {
|
||||
arr = append(arr, val)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// refer https://github.com/Delta456/box-cli-maker
|
||||
// func detectTerminalColor() terminfo.ColorLevel {
|
||||
// level, err := terminfo.ColorLevelFromEnv()
|
||||
// if err != nil {
|
||||
// saveInternalError(err)
|
||||
// return terminfo.ColorLevelNone
|
||||
// }
|
||||
//
|
||||
// // Detect WSL as it has True Color support
|
||||
// if level == terminfo.ColorLevelNone && runtime.GOOS == "windows" {
|
||||
// wsl, err := ioutil.ReadFile("/proc/sys/kernel/osrelease")
|
||||
// if err != nil {
|
||||
// saveInternalError(err)
|
||||
// return level
|
||||
// }
|
||||
//
|
||||
// // Microsoft for WSL and microsoft for WSL 2
|
||||
// content := strings.ToLower(string(wsl))
|
||||
// if strings.Contains(content, "microsoft") {
|
||||
// return terminfo.ColorLevelMillions
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return level
|
||||
// }
|
14
vendor/github.com/mattn/go-isatty/.travis.yml
generated
vendored
Normal file
14
vendor/github.com/mattn/go-isatty/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.13.x
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- ./go.test.sh
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
9
vendor/github.com/mattn/go-isatty/LICENSE
generated
vendored
Normal file
9
vendor/github.com/mattn/go-isatty/LICENSE
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
|
||||
|
||||
MIT License (Expat)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
50
vendor/github.com/mattn/go-isatty/README.md
generated
vendored
Normal file
50
vendor/github.com/mattn/go-isatty/README.md
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
# go-isatty
|
||||
|
||||
[](http://godoc.org/github.com/mattn/go-isatty)
|
||||
[](https://codecov.io/gh/mattn/go-isatty)
|
||||
[](https://coveralls.io/github/mattn/go-isatty?branch=master)
|
||||
[](https://goreportcard.com/report/mattn/go-isatty)
|
||||
|
||||
isatty for golang
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mattn/go-isatty"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Println("Is Terminal")
|
||||
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
||||
fmt.Println("Is Cygwin/MSYS2 Terminal")
|
||||
} else {
|
||||
fmt.Println("Is Not Terminal")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ go get github.com/mattn/go-isatty
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
||||
|
||||
## Thanks
|
||||
|
||||
* k-takata: base idea for IsCygwinTerminal
|
||||
|
||||
https://github.com/k-takata/go-iscygpty
|
2
vendor/github.com/mattn/go-isatty/doc.go
generated
vendored
Normal file
2
vendor/github.com/mattn/go-isatty/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package isatty implements interface to isatty
|
||||
package isatty
|
5
vendor/github.com/mattn/go-isatty/go.mod
generated
vendored
Normal file
5
vendor/github.com/mattn/go-isatty/go.mod
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/mattn/go-isatty
|
||||
|
||||
go 1.12
|
||||
|
||||
require golang.org/x/sys v0.0.0-20200116001909-b77594299b42
|
2
vendor/github.com/mattn/go-isatty/go.sum
generated
vendored
Normal file
2
vendor/github.com/mattn/go-isatty/go.sum
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
12
vendor/github.com/mattn/go-isatty/go.test.sh
generated
vendored
Normal file
12
vendor/github.com/mattn/go-isatty/go.test.sh
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
echo "" > coverage.txt
|
||||
|
||||
for d in $(go list ./... | grep -v vendor); do
|
||||
go test -race -coverprofile=profile.out -covermode=atomic "$d"
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out >> coverage.txt
|
||||
rm profile.out
|
||||
fi
|
||||
done
|
18
vendor/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
Normal file
18
vendor/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
_, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
15
vendor/github.com/mattn/go-isatty/isatty_others.go
generated
vendored
Normal file
15
vendor/github.com/mattn/go-isatty/isatty_others.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// +build appengine js nacl
|
||||
|
||||
package isatty
|
||||
|
||||
// IsTerminal returns true if the file descriptor is terminal which
|
||||
// is always false on js and appengine classic which is a sandboxed PaaS.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
22
vendor/github.com/mattn/go-isatty/isatty_plan9.go
generated
vendored
Normal file
22
vendor/github.com/mattn/go-isatty/isatty_plan9.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// +build plan9
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
path, err := syscall.Fd2path(int(fd))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return path == "/dev/cons" || path == "/mnt/term/dev/cons"
|
||||
}
|
||||
|
||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
22
vendor/github.com/mattn/go-isatty/isatty_solaris.go
generated
vendored
Normal file
22
vendor/github.com/mattn/go-isatty/isatty_solaris.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// +build solaris
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termio unix.Termio
|
||||
err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
18
vendor/github.com/mattn/go-isatty/isatty_tcgets.go
generated
vendored
Normal file
18
vendor/github.com/mattn/go-isatty/isatty_tcgets.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// +build linux aix
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
_, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
125
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
Normal file
125
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
// +build windows
|
||||
// +build !appengine
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
objectNameInfo uintptr = 1
|
||||
fileNameInfo = 2
|
||||
fileTypePipe = 3
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
ntdll = syscall.NewLazyDLL("ntdll.dll")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
||||
procGetFileType = kernel32.NewProc("GetFileType")
|
||||
procNtQueryObject = ntdll.NewProc("NtQueryObject")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Check if GetFileInformationByHandleEx is available.
|
||||
if procGetFileInformationByHandleEx.Find() != nil {
|
||||
procGetFileInformationByHandleEx = nil
|
||||
}
|
||||
}
|
||||
|
||||
// IsTerminal return true if the file descriptor is terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
}
|
||||
|
||||
// Check pipe name is used for cygwin/msys2 pty.
|
||||
// Cygwin/MSYS2 PTY has a name like:
|
||||
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
|
||||
func isCygwinPipeName(name string) bool {
|
||||
token := strings.Split(name, "-")
|
||||
if len(token) < 5 {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[0] != `\msys` &&
|
||||
token[0] != `\cygwin` &&
|
||||
token[0] != `\Device\NamedPipe\msys` &&
|
||||
token[0] != `\Device\NamedPipe\cygwin` {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[1] == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(token[2], "pty") {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[3] != `from` && token[3] != `to` {
|
||||
return false
|
||||
}
|
||||
|
||||
if token[4] != "master" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
|
||||
// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion
|
||||
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
|
||||
// Windows vista to 10
|
||||
// see https://stackoverflow.com/a/18792477 for details
|
||||
func getFileNameByHandle(fd uintptr) (string, error) {
|
||||
if procNtQueryObject == nil {
|
||||
return "", errors.New("ntdll.dll: NtQueryObject not supported")
|
||||
}
|
||||
|
||||
var buf [4 + syscall.MAX_PATH]uint16
|
||||
var result int
|
||||
r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
|
||||
fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
|
||||
if r != 0 {
|
||||
return "", e
|
||||
}
|
||||
return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
|
||||
}
|
||||
|
||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||
// terminal.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
if procGetFileInformationByHandleEx == nil {
|
||||
name, err := getFileNameByHandle(fd)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return isCygwinPipeName(name)
|
||||
}
|
||||
|
||||
// Cygwin/msys's pty is a pipe.
|
||||
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
|
||||
if ft != fileTypePipe || e != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var buf [2 + syscall.MAX_PATH]uint16
|
||||
r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
|
||||
4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
|
||||
uintptr(len(buf)*2), 0, 0)
|
||||
if r == 0 || e != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
l := *(*uint32)(unsafe.Pointer(&buf))
|
||||
return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
|
||||
}
|
8
vendor/github.com/mattn/go-isatty/renovate.json
generated
vendored
Normal file
8
vendor/github.com/mattn/go-isatty/renovate.json
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"postUpdateOptions": [
|
||||
"gomodTidy"
|
||||
]
|
||||
}
|
16
vendor/github.com/mattn/go-runewidth/.travis.yml
generated
vendored
Normal file
16
vendor/github.com/mattn/go-runewidth/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.13.x
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- go generate
|
||||
- git diff --cached --exit-code
|
||||
- ./go.test.sh
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
21
vendor/github.com/mattn/go-runewidth/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mattn/go-runewidth/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Yasuhiro Matsumoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
27
vendor/github.com/mattn/go-runewidth/README.md
generated
vendored
Normal file
27
vendor/github.com/mattn/go-runewidth/README.md
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
go-runewidth
|
||||
============
|
||||
|
||||
[](https://travis-ci.org/mattn/go-runewidth)
|
||||
[](https://codecov.io/gh/mattn/go-runewidth)
|
||||
[](http://godoc.org/github.com/mattn/go-runewidth)
|
||||
[](https://goreportcard.com/report/github.com/mattn/go-runewidth)
|
||||
|
||||
Provides functions to get fixed width of the character or string.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
```go
|
||||
runewidth.StringWidth("つのだ☆HIRO") == 12
|
||||
```
|
||||
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
Yasuhiro Matsumoto
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
under the MIT License: http://mattn.mit-license.org/2013
|
5
vendor/github.com/mattn/go-runewidth/go.mod
generated
vendored
Normal file
5
vendor/github.com/mattn/go-runewidth/go.mod
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/mattn/go-runewidth
|
||||
|
||||
go 1.9
|
||||
|
||||
require github.com/rivo/uniseg v0.1.0
|
2
vendor/github.com/mattn/go-runewidth/go.sum
generated
vendored
Normal file
2
vendor/github.com/mattn/go-runewidth/go.sum
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
12
vendor/github.com/mattn/go-runewidth/go.test.sh
generated
vendored
Normal file
12
vendor/github.com/mattn/go-runewidth/go.test.sh
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
echo "" > coverage.txt
|
||||
|
||||
for d in $(go list ./... | grep -v vendor); do
|
||||
go test -race -coverprofile=profile.out -covermode=atomic "$d"
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out >> coverage.txt
|
||||
rm profile.out
|
||||
fi
|
||||
done
|
241
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
Normal file
241
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
package runewidth
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
//go:generate go run script/generate.go
|
||||
|
||||
var (
|
||||
// EastAsianWidth will be set true if the current locale is CJK
|
||||
EastAsianWidth bool
|
||||
|
||||
// DefaultCondition is a condition in current locale
|
||||
DefaultCondition = &Condition{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
handleEnv()
|
||||
}
|
||||
|
||||
func handleEnv() {
|
||||
env := os.Getenv("RUNEWIDTH_EASTASIAN")
|
||||
if env == "" {
|
||||
EastAsianWidth = IsEastAsian()
|
||||
} else {
|
||||
EastAsianWidth = env == "1"
|
||||
}
|
||||
// update DefaultCondition
|
||||
DefaultCondition.EastAsianWidth = EastAsianWidth
|
||||
}
|
||||
|
||||
type interval struct {
|
||||
first rune
|
||||
last rune
|
||||
}
|
||||
|
||||
type table []interval
|
||||
|
||||
func inTables(r rune, ts ...table) bool {
|
||||
for _, t := range ts {
|
||||
if inTable(r, t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func inTable(r rune, t table) bool {
|
||||
if r < t[0].first {
|
||||
return false
|
||||
}
|
||||
|
||||
bot := 0
|
||||
top := len(t) - 1
|
||||
for top >= bot {
|
||||
mid := (bot + top) >> 1
|
||||
|
||||
switch {
|
||||
case t[mid].last < r:
|
||||
bot = mid + 1
|
||||
case t[mid].first > r:
|
||||
top = mid - 1
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var private = table{
|
||||
{0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},
|
||||
}
|
||||
|
||||
var nonprint = table{
|
||||
{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
|
||||
{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
|
||||
{0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
|
||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
|
||||
}
|
||||
|
||||
// Condition have flag EastAsianWidth whether the current locale is CJK or not.
|
||||
type Condition struct {
|
||||
EastAsianWidth bool
|
||||
}
|
||||
|
||||
// NewCondition return new instance of Condition which is current locale.
|
||||
func NewCondition() *Condition {
|
||||
return &Condition{
|
||||
EastAsianWidth: EastAsianWidth,
|
||||
}
|
||||
}
|
||||
|
||||
// RuneWidth returns the number of cells in r.
|
||||
// See http://www.unicode.org/reports/tr11/
|
||||
func (c *Condition) RuneWidth(r rune) int {
|
||||
switch {
|
||||
case r < 0 || r > 0x10FFFF || inTables(r, nonprint, combining, notassigned):
|
||||
return 0
|
||||
case (c.EastAsianWidth && IsAmbiguousWidth(r)) || inTables(r, doublewidth):
|
||||
return 2
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// StringWidth return width as you can see
|
||||
func (c *Condition) StringWidth(s string) (width int) {
|
||||
g := uniseg.NewGraphemes(s)
|
||||
for g.Next() {
|
||||
var chWidth int
|
||||
for _, r := range g.Runes() {
|
||||
chWidth = c.RuneWidth(r)
|
||||
if chWidth > 0 {
|
||||
break // Our best guess at this point is to use the width of the first non-zero-width rune.
|
||||
}
|
||||
}
|
||||
width += chWidth
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Truncate return string truncated with w cells
|
||||
func (c *Condition) Truncate(s string, w int, tail string) string {
|
||||
if c.StringWidth(s) <= w {
|
||||
return s
|
||||
}
|
||||
w -= c.StringWidth(tail)
|
||||
var width int
|
||||
pos := len(s)
|
||||
g := uniseg.NewGraphemes(s)
|
||||
for g.Next() {
|
||||
var chWidth int
|
||||
for _, r := range g.Runes() {
|
||||
chWidth = c.RuneWidth(r)
|
||||
if chWidth > 0 {
|
||||
break // See StringWidth() for details.
|
||||
}
|
||||
}
|
||||
if width+chWidth > w {
|
||||
pos, _ = g.Positions()
|
||||
break
|
||||
}
|
||||
width += chWidth
|
||||
}
|
||||
return s[:pos] + tail
|
||||
}
|
||||
|
||||
// Wrap return string wrapped with w cells
|
||||
func (c *Condition) Wrap(s string, w int) string {
|
||||
width := 0
|
||||
out := ""
|
||||
for _, r := range []rune(s) {
|
||||
cw := c.RuneWidth(r)
|
||||
if r == '\n' {
|
||||
out += string(r)
|
||||
width = 0
|
||||
continue
|
||||
} else if width+cw > w {
|
||||
out += "\n"
|
||||
width = 0
|
||||
out += string(r)
|
||||
width += cw
|
||||
continue
|
||||
}
|
||||
out += string(r)
|
||||
width += cw
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// FillLeft return string filled in left by spaces in w cells
|
||||
func (c *Condition) FillLeft(s string, w int) string {
|
||||
width := c.StringWidth(s)
|
||||
count := w - width
|
||||
if count > 0 {
|
||||
b := make([]byte, count)
|
||||
for i := range b {
|
||||
b[i] = ' '
|
||||
}
|
||||
return string(b) + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FillRight return string filled in left by spaces in w cells
|
||||
func (c *Condition) FillRight(s string, w int) string {
|
||||
width := c.StringWidth(s)
|
||||
count := w - width
|
||||
if count > 0 {
|
||||
b := make([]byte, count)
|
||||
for i := range b {
|
||||
b[i] = ' '
|
||||
}
|
||||
return s + string(b)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// RuneWidth returns the number of cells in r.
|
||||
// See http://www.unicode.org/reports/tr11/
|
||||
func RuneWidth(r rune) int {
|
||||
return DefaultCondition.RuneWidth(r)
|
||||
}
|
||||
|
||||
// IsAmbiguousWidth returns whether is ambiguous width or not.
|
||||
func IsAmbiguousWidth(r rune) bool {
|
||||
return inTables(r, private, ambiguous)
|
||||
}
|
||||
|
||||
// IsNeutralWidth returns whether is neutral width or not.
|
||||
func IsNeutralWidth(r rune) bool {
|
||||
return inTable(r, neutral)
|
||||
}
|
||||
|
||||
// StringWidth return width as you can see
|
||||
func StringWidth(s string) (width int) {
|
||||
return DefaultCondition.StringWidth(s)
|
||||
}
|
||||
|
||||
// Truncate return string truncated with w cells
|
||||
func Truncate(s string, w int, tail string) string {
|
||||
return DefaultCondition.Truncate(s, w, tail)
|
||||
}
|
||||
|
||||
// Wrap return string wrapped with w cells
|
||||
func Wrap(s string, w int) string {
|
||||
return DefaultCondition.Wrap(s, w)
|
||||
}
|
||||
|
||||
// FillLeft return string filled in left by spaces in w cells
|
||||
func FillLeft(s string, w int) string {
|
||||
return DefaultCondition.FillLeft(s, w)
|
||||
}
|
||||
|
||||
// FillRight return string filled in left by spaces in w cells
|
||||
func FillRight(s string, w int) string {
|
||||
return DefaultCondition.FillRight(s, w)
|
||||
}
|
8
vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
generated
vendored
Normal file
8
vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// +build appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
// IsEastAsian return true if the current locale is CJK
|
||||
func IsEastAsian() bool {
|
||||
return false
|
||||
}
|
9
vendor/github.com/mattn/go-runewidth/runewidth_js.go
generated
vendored
Normal file
9
vendor/github.com/mattn/go-runewidth/runewidth_js.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// +build js
|
||||
// +build !appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
func IsEastAsian() bool {
|
||||
// TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
|
||||
return false
|
||||
}
|
82
vendor/github.com/mattn/go-runewidth/runewidth_posix.go
generated
vendored
Normal file
82
vendor/github.com/mattn/go-runewidth/runewidth_posix.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
// +build !windows
|
||||
// +build !js
|
||||
// +build !appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
|
||||
|
||||
var mblenTable = map[string]int{
|
||||
"utf-8": 6,
|
||||
"utf8": 6,
|
||||
"jis": 8,
|
||||
"eucjp": 3,
|
||||
"euckr": 2,
|
||||
"euccn": 2,
|
||||
"sjis": 2,
|
||||
"cp932": 2,
|
||||
"cp51932": 2,
|
||||
"cp936": 2,
|
||||
"cp949": 2,
|
||||
"cp950": 2,
|
||||
"big5": 2,
|
||||
"gbk": 2,
|
||||
"gb2312": 2,
|
||||
}
|
||||
|
||||
func isEastAsian(locale string) bool {
|
||||
charset := strings.ToLower(locale)
|
||||
r := reLoc.FindStringSubmatch(locale)
|
||||
if len(r) == 2 {
|
||||
charset = strings.ToLower(r[1])
|
||||
}
|
||||
|
||||
if strings.HasSuffix(charset, "@cjk_narrow") {
|
||||
return false
|
||||
}
|
||||
|
||||
for pos, b := range []byte(charset) {
|
||||
if b == '@' {
|
||||
charset = charset[:pos]
|
||||
break
|
||||
}
|
||||
}
|
||||
max := 1
|
||||
if m, ok := mblenTable[charset]; ok {
|
||||
max = m
|
||||
}
|
||||
if max > 1 && (charset[0] != 'u' ||
|
||||
strings.HasPrefix(locale, "ja") ||
|
||||
strings.HasPrefix(locale, "ko") ||
|
||||
strings.HasPrefix(locale, "zh")) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsEastAsian return true if the current locale is CJK
|
||||
func IsEastAsian() bool {
|
||||
locale := os.Getenv("LC_ALL")
|
||||
if locale == "" {
|
||||
locale = os.Getenv("LC_CTYPE")
|
||||
}
|
||||
if locale == "" {
|
||||
locale = os.Getenv("LANG")
|
||||
}
|
||||
|
||||
// ignore C locale
|
||||
if locale == "POSIX" || locale == "C" {
|
||||
return false
|
||||
}
|
||||
if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
|
||||
return false
|
||||
}
|
||||
|
||||
return isEastAsian(locale)
|
||||
}
|
437
vendor/github.com/mattn/go-runewidth/runewidth_table.go
generated
vendored
Normal file
437
vendor/github.com/mattn/go-runewidth/runewidth_table.go
generated
vendored
Normal file
@ -0,0 +1,437 @@
|
||||
// Code generated by script/generate.go. DO NOT EDIT.
|
||||
|
||||
package runewidth
|
||||
|
||||
var combining = table{
|
||||
{0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3},
|
||||
{0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0D00, 0x0D01},
|
||||
{0x135D, 0x135F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1AC0},
|
||||
{0x1B6B, 0x1B73}, {0x1DC0, 0x1DF9}, {0x1DFB, 0x1DFF},
|
||||
{0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF},
|
||||
{0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D},
|
||||
{0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1},
|
||||
{0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A},
|
||||
{0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x11300, 0x11301},
|
||||
{0x1133B, 0x1133C}, {0x11366, 0x1136C}, {0x11370, 0x11374},
|
||||
{0x16AF0, 0x16AF4}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},
|
||||
{0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
|
||||
{0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},
|
||||
{0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},
|
||||
{0x1E8D0, 0x1E8D6},
|
||||
}
|
||||
|
||||
var doublewidth = table{
|
||||
{0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},
|
||||
{0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},
|
||||
{0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},
|
||||
{0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},
|
||||
{0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
|
||||
{0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},
|
||||
{0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},
|
||||
{0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},
|
||||
{0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},
|
||||
{0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
|
||||
{0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
|
||||
{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
|
||||
{0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},
|
||||
{0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF},
|
||||
{0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3},
|
||||
{0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x4DBF},
|
||||
{0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
|
||||
{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19},
|
||||
{0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B},
|
||||
{0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4},
|
||||
{0x16FF0, 0x16FF1}, {0x17000, 0x187F7}, {0x18800, 0x18CD5},
|
||||
{0x18D00, 0x18D08}, {0x1B000, 0x1B11E}, {0x1B150, 0x1B152},
|
||||
{0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1F004, 0x1F004},
|
||||
{0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
|
||||
{0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
|
||||
{0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F320},
|
||||
{0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393},
|
||||
{0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0},
|
||||
{0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440},
|
||||
{0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E},
|
||||
{0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596},
|
||||
{0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5},
|
||||
{0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D7},
|
||||
{0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB},
|
||||
{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F978},
|
||||
{0x1F97A, 0x1F9CB}, {0x1F9CD, 0x1F9FF}, {0x1FA70, 0x1FA74},
|
||||
{0x1FA78, 0x1FA7A}, {0x1FA80, 0x1FA86}, {0x1FA90, 0x1FAA8},
|
||||
{0x1FAB0, 0x1FAB6}, {0x1FAC0, 0x1FAC2}, {0x1FAD0, 0x1FAD6},
|
||||
{0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
|
||||
}
|
||||
|
||||
var ambiguous = table{
|
||||
{0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
|
||||
{0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4},
|
||||
{0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
|
||||
{0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
|
||||
{0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
|
||||
{0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
|
||||
{0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
|
||||
{0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
|
||||
{0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
|
||||
{0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
|
||||
{0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
|
||||
{0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
|
||||
{0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
|
||||
{0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
|
||||
{0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
|
||||
{0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
|
||||
{0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
|
||||
{0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F},
|
||||
{0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1},
|
||||
{0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},
|
||||
{0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016},
|
||||
{0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022},
|
||||
{0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033},
|
||||
{0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},
|
||||
{0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084},
|
||||
{0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105},
|
||||
{0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116},
|
||||
{0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},
|
||||
{0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B},
|
||||
{0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199},
|
||||
{0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},
|
||||
{0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203},
|
||||
{0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F},
|
||||
{0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A},
|
||||
{0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},
|
||||
{0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237},
|
||||
{0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C},
|
||||
{0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267},
|
||||
{0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},
|
||||
{0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299},
|
||||
{0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312},
|
||||
{0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573},
|
||||
{0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},
|
||||
{0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7},
|
||||
{0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8},
|
||||
{0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5},
|
||||
{0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},
|
||||
{0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E},
|
||||
{0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661},
|
||||
{0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D},
|
||||
{0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF},
|
||||
{0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1},
|
||||
{0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1},
|
||||
{0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},
|
||||
{0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},
|
||||
{0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},
|
||||
{0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},
|
||||
{0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},
|
||||
{0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},
|
||||
{0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
|
||||
}
|
||||
var notassigned = table{
|
||||
{0x27E6, 0x27ED}, {0x2985, 0x2986},
|
||||
}
|
||||
|
||||
var neutral = table{
|
||||
{0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9},
|
||||
{0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB},
|
||||
{0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6},
|
||||
{0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7},
|
||||
{0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1},
|
||||
{0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD},
|
||||
{0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
|
||||
{0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},
|
||||
{0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},
|
||||
{0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},
|
||||
{0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},
|
||||
{0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1},
|
||||
{0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7},
|
||||
{0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250},
|
||||
{0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6},
|
||||
{0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF},
|
||||
{0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
|
||||
{0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F},
|
||||
{0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390},
|
||||
{0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400},
|
||||
{0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},
|
||||
{0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F},
|
||||
{0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4},
|
||||
{0x0600, 0x061C}, {0x061E, 0x070D}, {0x070F, 0x074A},
|
||||
{0x074D, 0x07B1}, {0x07C0, 0x07FA}, {0x07FD, 0x082D},
|
||||
{0x0830, 0x083E}, {0x0840, 0x085B}, {0x085E, 0x085E},
|
||||
{0x0860, 0x086A}, {0x08A0, 0x08B4}, {0x08B6, 0x08C7},
|
||||
{0x08D3, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990},
|
||||
{0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2},
|
||||
{0x09B6, 0x09B9}, {0x09BC, 0x09C4}, {0x09C7, 0x09C8},
|
||||
{0x09CB, 0x09CE}, {0x09D7, 0x09D7}, {0x09DC, 0x09DD},
|
||||
{0x09DF, 0x09E3}, {0x09E6, 0x09FE}, {0x0A01, 0x0A03},
|
||||
{0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28},
|
||||
{0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36},
|
||||
{0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42},
|
||||
{0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
|
||||
{0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76},
|
||||
{0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91},
|
||||
{0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3},
|
||||
{0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9},
|
||||
{0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3},
|
||||
{0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03},
|
||||
{0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28},
|
||||
{0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B35, 0x0B39},
|
||||
{0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D},
|
||||
{0x0B55, 0x0B57}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63},
|
||||
{0x0B66, 0x0B77}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A},
|
||||
{0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A},
|
||||
{0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4},
|
||||
{0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2},
|
||||
{0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0},
|
||||
{0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C},
|
||||
{0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C39},
|
||||
{0x0C3D, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
|
||||
{0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C63},
|
||||
{0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90},
|
||||
{0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
|
||||
{0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
|
||||
{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3},
|
||||
{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D00, 0x0D0C},
|
||||
{0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48},
|
||||
{0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F},
|
||||
{0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1},
|
||||
{0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6},
|
||||
{0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6},
|
||||
{0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4},
|
||||
{0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82},
|
||||
{0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3},
|
||||
{0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4},
|
||||
{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9},
|
||||
{0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
|
||||
{0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
|
||||
{0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
|
||||
{0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},
|
||||
{0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},
|
||||
{0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},
|
||||
{0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},
|
||||
{0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},
|
||||
{0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
|
||||
{0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
|
||||
{0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
|
||||
{0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736},
|
||||
{0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
|
||||
{0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9},
|
||||
{0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819},
|
||||
{0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5},
|
||||
{0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B},
|
||||
{0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974},
|
||||
{0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA},
|
||||
{0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C},
|
||||
{0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD},
|
||||
{0x1AB0, 0x1AC0}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C},
|
||||
{0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49},
|
||||
{0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7},
|
||||
{0x1CD0, 0x1CFA}, {0x1D00, 0x1DF9}, {0x1DFB, 0x1F15},
|
||||
{0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
|
||||
{0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
|
||||
{0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
|
||||
{0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
|
||||
{0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},
|
||||
{0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},
|
||||
{0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},
|
||||
{0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
|
||||
{0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
|
||||
{0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
|
||||
{0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
|
||||
{0x20AA, 0x20AB}, {0x20AD, 0x20BF}, {0x20D0, 0x20F0},
|
||||
{0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
|
||||
{0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
|
||||
{0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
|
||||
{0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
|
||||
{0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},
|
||||
{0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},
|
||||
{0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},
|
||||
{0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},
|
||||
{0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},
|
||||
{0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},
|
||||
{0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},
|
||||
{0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},
|
||||
{0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},
|
||||
{0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},
|
||||
{0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},
|
||||
{0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},
|
||||
{0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},
|
||||
{0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A},
|
||||
{0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F},
|
||||
{0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2},
|
||||
{0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB},
|
||||
{0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA},
|
||||
{0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE},
|
||||
{0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608},
|
||||
{0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B},
|
||||
{0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641},
|
||||
{0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662},
|
||||
{0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E},
|
||||
{0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D},
|
||||
{0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC},
|
||||
{0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7},
|
||||
{0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727},
|
||||
{0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D},
|
||||
{0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775},
|
||||
{0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE},
|
||||
{0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A},
|
||||
{0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73},
|
||||
{0x2B76, 0x2B95}, {0x2B97, 0x2C2E}, {0x2C30, 0x2C5E},
|
||||
{0x2C60, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27},
|
||||
{0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70},
|
||||
{0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE},
|
||||
{0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6},
|
||||
{0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE},
|
||||
{0x2DE0, 0x2E52}, {0x303F, 0x303F}, {0x4DC0, 0x4DFF},
|
||||
{0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7BF},
|
||||
{0xA7C2, 0xA7CA}, {0xA7F5, 0xA82C}, {0xA830, 0xA839},
|
||||
{0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9},
|
||||
{0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
|
||||
{0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
|
||||
{0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},
|
||||
{0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
|
||||
{0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
|
||||
{0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},
|
||||
{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
|
||||
{0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
|
||||
{0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
|
||||
{0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F},
|
||||
{0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD},
|
||||
{0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
|
||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
|
||||
{0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
|
||||
{0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
|
||||
{0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
|
||||
{0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
|
||||
{0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
|
||||
{0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A},
|
||||
{0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
|
||||
{0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
|
||||
{0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},
|
||||
{0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
|
||||
{0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},
|
||||
{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},
|
||||
{0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7},
|
||||
{0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},
|
||||
{0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35},
|
||||
{0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58},
|
||||
{0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},
|
||||
{0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},
|
||||
{0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
|
||||
{0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
|
||||
{0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10E60, 0x10E7E},
|
||||
{0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1},
|
||||
{0x10F00, 0x10F27}, {0x10F30, 0x10F59}, {0x10FB0, 0x10FCB},
|
||||
{0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x1106F},
|
||||
{0x1107F, 0x110C1}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8},
|
||||
{0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147},
|
||||
{0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1123E}, {0x11280, 0x11286},
|
||||
{0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D},
|
||||
{0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9},
|
||||
{0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},
|
||||
{0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},
|
||||
{0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348},
|
||||
{0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357},
|
||||
{0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
|
||||
{0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7},
|
||||
{0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD},
|
||||
{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},
|
||||
{0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x11700, 0x1171A},
|
||||
{0x1171D, 0x1172B}, {0x11730, 0x1173F}, {0x11800, 0x1183B},
|
||||
{0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909},
|
||||
{0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935},
|
||||
{0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959},
|
||||
{0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4},
|
||||
{0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AC0, 0x11AF8},
|
||||
{0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},
|
||||
{0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},
|
||||
{0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
|
||||
{0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D},
|
||||
{0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},
|
||||
{0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},
|
||||
{0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8},
|
||||
{0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},
|
||||
{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342E}, {0x13430, 0x13438}, {0x14400, 0x14646},
|
||||
{0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},
|
||||
{0x16A6E, 0x16A6F}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5},
|
||||
{0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
|
||||
{0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A},
|
||||
{0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F},
|
||||
{0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88},
|
||||
{0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1D000, 0x1D0F5},
|
||||
{0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, {0x1D200, 0x1D245},
|
||||
{0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378},
|
||||
{0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F},
|
||||
{0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC},
|
||||
{0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3},
|
||||
{0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514},
|
||||
{0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E},
|
||||
{0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550},
|
||||
{0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B},
|
||||
{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
|
||||
{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
|
||||
{0x1E026, 0x1E02A}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
|
||||
{0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E2C0, 0x1E2F9},
|
||||
{0x1E2FF, 0x1E2FF}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
|
||||
{0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
|
||||
{0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03},
|
||||
{0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24},
|
||||
{0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37},
|
||||
{0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42},
|
||||
{0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B},
|
||||
{0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54},
|
||||
{0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B},
|
||||
{0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62},
|
||||
{0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72},
|
||||
{0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E},
|
||||
{0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3},
|
||||
{0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1},
|
||||
{0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093},
|
||||
{0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE},
|
||||
{0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F},
|
||||
{0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF},
|
||||
{0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},
|
||||
{0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},
|
||||
{0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},
|
||||
{0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},
|
||||
{0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
|
||||
{0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
|
||||
{0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4},
|
||||
{0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773},
|
||||
{0x1F780, 0x1F7D8}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
|
||||
{0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
|
||||
{0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B},
|
||||
{0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D},
|
||||
{0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9},
|
||||
{0xE0001, 0xE0001}, {0xE0020, 0xE007F},
|
||||
}
|
||||
|
||||
var emoji = table{
|
||||
{0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},
|
||||
{0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},
|
||||
{0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388},
|
||||
{0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA},
|
||||
{0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6},
|
||||
{0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605},
|
||||
{0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705},
|
||||
{0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},
|
||||
{0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},
|
||||
{0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},
|
||||
{0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
|
||||
{0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797},
|
||||
{0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},
|
||||
{0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},
|
||||
{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},
|
||||
{0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},
|
||||
{0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F},
|
||||
{0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E},
|
||||
{0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F},
|
||||
{0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A},
|
||||
{0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D},
|
||||
{0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F},
|
||||
{0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F},
|
||||
{0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF},
|
||||
{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF},
|
||||
{0x1FC00, 0x1FFFD},
|
||||
}
|
28
vendor/github.com/mattn/go-runewidth/runewidth_windows.go
generated
vendored
Normal file
28
vendor/github.com/mattn/go-runewidth/runewidth_windows.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// +build windows
|
||||
// +build !appengine
|
||||
|
||||
package runewidth
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32")
|
||||
procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
|
||||
)
|
||||
|
||||
// IsEastAsian return true if the current locale is CJK
|
||||
func IsEastAsian() bool {
|
||||
r1, _, _ := procGetConsoleOutputCP.Call()
|
||||
if r1 == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch int(r1) {
|
||||
case 932, 51932, 936, 949, 950:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
18
vendor/github.com/pterm/pterm/.gitignore
generated
vendored
Normal file
18
vendor/github.com/pterm/pterm/.gitignore
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
vendor/
|
||||
|
||||
# This is where we test stuff
|
||||
/experimenting/
|
92
vendor/github.com/pterm/pterm/.golangci.yml
generated
vendored
Normal file
92
vendor/github.com/pterm/pterm/.golangci.yml
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
linters-settings:
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
- experimental
|
||||
- opinionated
|
||||
- performance
|
||||
- style
|
||||
disabled-checks:
|
||||
- dupImport
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
- whyNoLint
|
||||
- wrapperFunc
|
||||
- exitAfterDefer
|
||||
- hugeParam
|
||||
- ptrToRefParam
|
||||
- paramTypeCombine
|
||||
- unnamedResult
|
||||
# maligned:
|
||||
# suggest-new: true
|
||||
misspell:
|
||||
locale: US
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- gocritic
|
||||
- gosec
|
||||
- govet
|
||||
- ineffassign
|
||||
- interfacer
|
||||
- unconvert
|
||||
- gosimple
|
||||
- godox
|
||||
- whitespace
|
||||
- staticcheck
|
||||
# - bodyclose
|
||||
# - maligned
|
||||
# - godot
|
||||
# - deadcode
|
||||
# - depguard
|
||||
# - dogsled
|
||||
# - dupl
|
||||
# - errcheck
|
||||
# - exhaustive
|
||||
# - funlen
|
||||
# - gochecknoinits
|
||||
# - goconst
|
||||
# - gocyclo
|
||||
# - gofmt
|
||||
# - goimports
|
||||
# - golint
|
||||
# - gomnd
|
||||
# - goprintffuncname
|
||||
# - lll
|
||||
# - misspell
|
||||
# - nakedret
|
||||
# - noctx
|
||||
# - nolintlint
|
||||
# - rowserrcheck
|
||||
# - scopelint
|
||||
# - structcheck
|
||||
# - stylecheck
|
||||
# - typecheck
|
||||
# - unparam
|
||||
# - unused
|
||||
# - varcheck
|
||||
# - whitespace
|
||||
# - asciicheck
|
||||
# - gochecknoglobals
|
||||
# - gocognit
|
||||
# - goerr113
|
||||
# - nestif
|
||||
# - prealloc
|
||||
# - testpackage
|
||||
# - wsl
|
||||
issues:
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gocyclo
|
||||
- errcheck
|
||||
- dupl
|
||||
- gosec
|
||||
- gocritic
|
||||
# https://github.com/go-critic/go-critic/issues/926
|
||||
- linters:
|
||||
- gocritic
|
||||
text: "unnecessaryDefer:"
|
||||
service:
|
||||
golangci-lint-version: 1.31.x # use the fixed version to not introduce new linters unexpectedly
|
1083
vendor/github.com/pterm/pterm/CHANGELOG.md
generated
vendored
Normal file
1083
vendor/github.com/pterm/pterm/CHANGELOG.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
76
vendor/github.com/pterm/pterm/CODE_OF_CONDUCT.md
generated
vendored
Normal file
76
vendor/github.com/pterm/pterm/CODE_OF_CONDUCT.md
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at pterm@marvinjwendt.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
217
vendor/github.com/pterm/pterm/CONTRIBUTING.md
generated
vendored
Normal file
217
vendor/github.com/pterm/pterm/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
# Contributing to PTerm
|
||||
|
||||
> This document explains how to participate in the development of PTerm.\
|
||||
If your goal is to report a bug instead of programming PTerm, you can do so [here](https://github.com/pterm/pterm/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
|
||||
## Creating a new printer
|
||||
|
||||
> In this chapter we will show you how to create a new printer.
|
||||
|
||||
### `TextPrinter` Template
|
||||
```go
|
||||
package pterm
|
||||
|
||||
type TemplatePrinter struct{
|
||||
// TODO: Add printer settings here
|
||||
}
|
||||
|
||||
// Sprint formats using the default formats for its operands and returns the resulting string.
|
||||
// Spaces are added between operands when neither is a string.
|
||||
func (p TemplatePrinter) Sprint(a ...interface{}) string {
|
||||
panic("write printer code here")
|
||||
}
|
||||
|
||||
// Sprintln formats using the default formats for its operands and returns the resulting string.
|
||||
// Spaces are always added between operands and a newline is appended.
|
||||
func (p TemplatePrinter) Sprintln(a ...interface{}) string {
|
||||
return Sprintln(p.Sprint(a...))
|
||||
}
|
||||
|
||||
// Sprintf formats according to a format specifier and returns the resulting string.
|
||||
func (p TemplatePrinter) Sprintf(format string, a ...interface{}) string {
|
||||
return p.Sprint(Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// Print formats using the default formats for its operands and writes to standard output.
|
||||
// Spaces are added between operands when neither is a string.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
func (p TemplatePrinter) Print(a ...interface{}) *TextPrinter {
|
||||
Print(p.Sprint(a...))
|
||||
tp := TextPrinter(p)
|
||||
return &tp
|
||||
}
|
||||
|
||||
// Println formats using the default formats for its operands and writes to standard output.
|
||||
// Spaces are always added between operands and a newline is appended.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
func (p TemplatePrinter) Println(a ...interface{}) *TextPrinter {
|
||||
Println(p.Sprint(a...))
|
||||
tp := TextPrinter(p)
|
||||
return &tp
|
||||
}
|
||||
|
||||
// Printf formats according to a format specifier and writes to standard output.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
func (p TemplatePrinter) Printf(format string, a ...interface{}) *TextPrinter {
|
||||
Print(p.Sprintf(format, a...))
|
||||
tp := TextPrinter(p)
|
||||
return &tp
|
||||
}
|
||||
```
|
||||
|
||||
### `RenderablePrinter` Template
|
||||
|
||||
```go
|
||||
package pterm
|
||||
|
||||
type TemplatePrinter struct{
|
||||
// TODO: Add printer settings here
|
||||
}
|
||||
|
||||
// Srender renders the Template as a string.
|
||||
func (p TemplatePrinter) Srender() (string, error) {
|
||||
var ret string
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Render prints the Template to the terminal.
|
||||
func (p TemplatePrinter) Render() error {
|
||||
s, err := p.Srender()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Println(s)
|
||||
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### `LivePrinter` Template
|
||||
|
||||
```go
|
||||
// Start the TemplatePrinter.
|
||||
package pterm
|
||||
import "github.com/pterm/pterm"
|
||||
|
||||
type TemplatePrinter struct{
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (s TemplatePrinter) Start(text...interface{}) (*TemplatePrinter, error) { // TODO: Replace Template with actual printer.
|
||||
// TODO: start logic
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
// Stop terminates the TemplatePrinter immediately.
|
||||
// The TemplatePrinter will not resolve into anything.
|
||||
func (s *TemplatePrinter) Stop() error {
|
||||
// TODO: stop logic
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenericStart runs Start, but returns a LivePrinter.
|
||||
// This is used for the interface LivePrinter.
|
||||
// You most likely want to use Start instead of this in your program.
|
||||
func (s *TemplatePrinter) GenericStart() (*LivePrinter, error) {
|
||||
_, err := s.Start()
|
||||
lp := LivePrinter(s)
|
||||
return &lp, err
|
||||
}
|
||||
|
||||
// GenericStop runs Stop, but returns a LivePrinter.
|
||||
// This is used for the interface LivePrinter.
|
||||
// You most likely want to use Stop instead of this in your program.
|
||||
func (s *TemplatePrinter) GenericStop() (*LivePrinter, error) {
|
||||
err := s.Stop()
|
||||
lp := LivePrinter(s)
|
||||
return &lp, err
|
||||
}
|
||||
```
|
||||
|
||||
## Writing Tests
|
||||
|
||||
> Each method of PTerm must be tested.
|
||||
|
||||
### Required tests for every printer
|
||||
|
||||
#### Nil Check
|
||||
|
||||
> This ensures that a printer without set values will not produce errors.
|
||||
|
||||
```go
|
||||
func TestTemplatePrinterNilPrint(t *testing.T) { // TODO: Replace "Template" with actual printer name.
|
||||
p := TemplatePrinter{} // TODO: Replace "Template" with actual printer name.
|
||||
p.Println("Hello, World!")
|
||||
}
|
||||
```
|
||||
|
||||
#### `WithXxx()` Methods
|
||||
|
||||
> Each method, which starts with `With` can be tested by checking if it actually creates a new printer and sets the value.
|
||||
|
||||
Example from `SectionPrinter`:
|
||||
|
||||
```go
|
||||
func TestSectionPrinter_WithStyle(t *testing.T) {
|
||||
p := SectionPrinter{}
|
||||
s := NewStyle(FgRed, BgRed, Bold)
|
||||
p2 := p.WithStyle(s)
|
||||
|
||||
assert.Equal(t, s, p2.Style)
|
||||
assert.Empty(t, p.Style)
|
||||
}
|
||||
|
||||
func TestSectionPrinter_WithTopPadding(t *testing.T) {
|
||||
p := SectionPrinter{}
|
||||
p2 := p.WithTopPadding(1337)
|
||||
|
||||
assert.Equal(t, 1337, p2.TopPadding)
|
||||
assert.Empty(t, p.TopPadding)
|
||||
}
|
||||
```
|
||||
|
||||
### `TextPrinter` Tests Template
|
||||
|
||||
```go
|
||||
func TestTemplatePrinterPrintMethods(t *testing.T) { // TODO: Replace "Template" with actual printer name.
|
||||
p := DefaultTemplate // TODO: Replace "Template" with actual printer name.
|
||||
|
||||
t.Run("Print", func(t *testing.T) {
|
||||
internal.TestPrintContains(t, func(w io.Writer, a interface{}) {
|
||||
p.Print(a)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Printf", func(t *testing.T) {
|
||||
internal.TestPrintfContains(t, func(w io.Writer, format string, a interface{}) {
|
||||
p.Printf(format, a)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Println", func(t *testing.T) {
|
||||
internal.TestPrintlnContains(t, func(w io.Writer, a interface{}) {
|
||||
p.Println(a)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Sprint", func(t *testing.T) {
|
||||
internal.TestSprintContains(t, func(a interface{}) string {
|
||||
return p.Sprint(a)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Sprintf", func(t *testing.T) {
|
||||
internal.TestSprintfContains(t, func(format string, a interface{}) string {
|
||||
return p.Sprintf(format, a)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Sprintln", func(t *testing.T) {
|
||||
internal.TestSprintlnContains(t, func(a interface{}) string {
|
||||
return p.Sprintln(a)
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
21
vendor/github.com/pterm/pterm/LICENSE
generated
vendored
Normal file
21
vendor/github.com/pterm/pterm/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 pterm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
1493
vendor/github.com/pterm/pterm/README.md
generated
vendored
Normal file
1493
vendor/github.com/pterm/pterm/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
36
vendor/github.com/pterm/pterm/atoms.go
generated
vendored
Normal file
36
vendor/github.com/pterm/pterm/atoms.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package pterm
|
||||
|
||||
// Bars is used to display multiple Bar.
|
||||
type Bars []Bar
|
||||
|
||||
// Bar is used in bar charts.
|
||||
type Bar struct {
|
||||
Label string
|
||||
Value int
|
||||
Style *Style
|
||||
LabelStyle *Style
|
||||
}
|
||||
|
||||
// WithLabel returns a new Bar with a specific option.
|
||||
func (p Bar) WithLabel(s string) *Bar {
|
||||
p.Label = s
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithLabelStyle returns a new Bar with a specific option.
|
||||
func (p Bar) WithLabelStyle(style *Style) *Bar {
|
||||
p.LabelStyle = style
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithValue returns a new Bar with a specific option.
|
||||
func (p Bar) WithValue(value int) *Bar {
|
||||
p.Value = value
|
||||
return &p
|
||||
}
|
||||
|
||||
// WithStyle returns a new Bar with a specific option.
|
||||
func (p Bar) WithStyle(style *Style) *Bar {
|
||||
p.Style = style
|
||||
return &p
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user