go: update modules
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
ebfd8ac60d
commit
a6dff28c54
508 changed files with 70392 additions and 109592 deletions
14
go.mod
14
go.mod
|
@ -4,8 +4,22 @@ go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/PuerkitoBio/goquery v1.6.1
|
github.com/PuerkitoBio/goquery v1.6.1
|
||||||
|
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||||
|
github.com/andybalholm/cascadia v1.2.0 // indirect
|
||||||
|
github.com/cheggaaa/pb/v3 v3.0.8
|
||||||
|
github.com/fatih/color v1.11.0 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.5 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||||
|
github.com/pelletier/go-toml v1.9.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
|
github.com/spf13/afero v1.6.0 // indirect
|
||||||
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
github.com/spf13/cobra v1.1.3
|
github.com/spf13/cobra v1.1.3
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
|
golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
58
go.sum
58
go.sum
|
@ -17,10 +17,16 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFGCWpk=
|
github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFGCWpk=
|
||||||
github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
|
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||||
|
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||||
|
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||||
|
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
||||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
|
github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE=
|
||||||
|
github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
@ -29,6 +35,8 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA=
|
||||||
|
github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
@ -42,8 +50,14 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||||
|
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||||
|
github.com/fatih/color v1.11.0 h1:l4iX0RqNnx/pU7rY2DB/I+znuYY0K3x6Ywac6EIr0PA=
|
||||||
|
github.com/fatih/color v1.11.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
@ -108,6 +122,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
@ -116,8 +131,16 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||||
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
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.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
|
||||||
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
|
@ -130,6 +153,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
@ -137,8 +162,11 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pelletier/go-toml v1.9.1 h1:a6qW1EVNZWH9WGI6CsYdD8WAylkoXBS5yv0XHlh17Tc=
|
||||||
|
github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
|
@ -151,6 +179,9 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
@ -168,12 +199,18 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||||
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||||
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
||||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
@ -185,6 +222,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
|
@ -200,6 +238,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -235,6 +274,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
||||||
|
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -256,12 +297,24 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
|
||||||
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
||||||
|
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
@ -310,9 +363,12 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
|
3
vendor/github.com/VividCortex/ewma/.gitignore
generated
vendored
Normal file
3
vendor/github.com/VividCortex/ewma/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.DS_Store
|
||||||
|
.*.sw?
|
||||||
|
/coverage.txt
|
3
vendor/github.com/VividCortex/ewma/.whitesource
generated
vendored
Normal file
3
vendor/github.com/VividCortex/ewma/.whitesource
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"settingsInheritedFrom": "VividCortex/whitesource-config@master"
|
||||||
|
}
|
21
vendor/github.com/VividCortex/ewma/LICENSE
generated
vendored
Normal file
21
vendor/github.com/VividCortex/ewma/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2013 VividCortex
|
||||||
|
|
||||||
|
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.
|
145
vendor/github.com/VividCortex/ewma/README.md
generated
vendored
Normal file
145
vendor/github.com/VividCortex/ewma/README.md
generated
vendored
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
# EWMA
|
||||||
|
|
||||||
|
[![GoDoc](https://godoc.org/github.com/VividCortex/ewma?status.svg)](https://godoc.org/github.com/VividCortex/ewma)
|
||||||
|
![build](https://github.com/VividCortex/ewma/workflows/build/badge.svg)
|
||||||
|
[![codecov](https://codecov.io/gh/VividCortex/ewma/branch/master/graph/badge.svg)](https://codecov.io/gh/VividCortex/ewma)
|
||||||
|
|
||||||
|
This repo provides Exponentially Weighted Moving Average algorithms, or EWMAs for short, [based on our
|
||||||
|
Quantifying Abnormal Behavior talk](https://vividcortex.com/blog/2013/07/23/a-fast-go-library-for-exponential-moving-averages/).
|
||||||
|
|
||||||
|
### Exponentially Weighted Moving Average
|
||||||
|
|
||||||
|
An exponentially weighted moving average is a way to continuously compute a type of
|
||||||
|
average for a series of numbers, as the numbers arrive. After a value in the series is
|
||||||
|
added to the average, its weight in the average decreases exponentially over time. This
|
||||||
|
biases the average towards more recent data. EWMAs are useful for several reasons, chiefly
|
||||||
|
their inexpensive computational and memory cost, as well as the fact that they represent
|
||||||
|
the recent central tendency of the series of values.
|
||||||
|
|
||||||
|
The EWMA algorithm requires a decay factor, alpha. The larger the alpha, the more the average
|
||||||
|
is biased towards recent history. The alpha must be between 0 and 1, and is typically
|
||||||
|
a fairly small number, such as 0.04. We will discuss the choice of alpha later.
|
||||||
|
|
||||||
|
The algorithm works thus, in pseudocode:
|
||||||
|
|
||||||
|
1. Multiply the next number in the series by alpha.
|
||||||
|
2. Multiply the current value of the average by 1 minus alpha.
|
||||||
|
3. Add the result of steps 1 and 2, and store it as the new current value of the average.
|
||||||
|
4. Repeat for each number in the series.
|
||||||
|
|
||||||
|
There are special-case behaviors for how to initialize the current value, and these vary
|
||||||
|
between implementations. One approach is to start with the first value in the series;
|
||||||
|
another is to average the first 10 or so values in the series using an arithmetic average,
|
||||||
|
and then begin the incremental updating of the average. Each method has pros and cons.
|
||||||
|
|
||||||
|
It may help to look at it pictorially. Suppose the series has five numbers, and we choose
|
||||||
|
alpha to be 0.50 for simplicity. Here's the series, with numbers in the neighborhood of 300.
|
||||||
|
|
||||||
|
![Data Series](https://user-images.githubusercontent.com/279875/28242350-463289a2-6977-11e7-88ca-fd778ccef1f0.png)
|
||||||
|
|
||||||
|
Now let's take the moving average of those numbers. First we set the average to the value
|
||||||
|
of the first number.
|
||||||
|
|
||||||
|
![EWMA Step 1](https://user-images.githubusercontent.com/279875/28242353-464c96bc-6977-11e7-9981-dc4e0789c7ba.png)
|
||||||
|
|
||||||
|
Next we multiply the next number by alpha, multiply the current value by 1-alpha, and add
|
||||||
|
them to generate a new value.
|
||||||
|
|
||||||
|
![EWMA Step 2](https://user-images.githubusercontent.com/279875/28242351-464abefa-6977-11e7-95d0-43900f29bef2.png)
|
||||||
|
|
||||||
|
This continues until we are done.
|
||||||
|
|
||||||
|
![EWMA Step N](https://user-images.githubusercontent.com/279875/28242352-464c58f0-6977-11e7-8cd0-e01e4efaac7f.png)
|
||||||
|
|
||||||
|
Notice how each of the values in the series decays by half each time a new value
|
||||||
|
is added, and the top of the bars in the lower portion of the image represents the
|
||||||
|
size of the moving average. It is a smoothed, or low-pass, average of the original
|
||||||
|
series.
|
||||||
|
|
||||||
|
For further reading, see [Exponentially weighted moving average](http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average) on wikipedia.
|
||||||
|
|
||||||
|
### Choosing Alpha
|
||||||
|
|
||||||
|
Consider a fixed-size sliding-window moving average (not an exponentially weighted moving average)
|
||||||
|
that averages over the previous N samples. What is the average age of each sample? It is N/2.
|
||||||
|
|
||||||
|
Now suppose that you wish to construct a EWMA whose samples have the same average age. The formula
|
||||||
|
to compute the alpha required for this is: alpha = 2/(N+1). Proof is in the book
|
||||||
|
"Production and Operations Analysis" by Steven Nahmias.
|
||||||
|
|
||||||
|
So, for example, if you have a time-series with samples once per second, and you want to get the
|
||||||
|
moving average over the previous minute, you should use an alpha of .032786885. This, by the way,
|
||||||
|
is the constant alpha used for this repository's SimpleEWMA.
|
||||||
|
|
||||||
|
### Implementations
|
||||||
|
|
||||||
|
This repository contains two implementations of the EWMA algorithm, with different properties.
|
||||||
|
|
||||||
|
The implementations all conform to the MovingAverage interface, and the constructor returns
|
||||||
|
that type.
|
||||||
|
|
||||||
|
Current implementations assume an implicit time interval of 1.0 between every sample added.
|
||||||
|
That is, the passage of time is treated as though it's the same as the arrival of samples.
|
||||||
|
If you need time-based decay when samples are not arriving precisely at set intervals, then
|
||||||
|
this package will not support your needs at present.
|
||||||
|
|
||||||
|
#### SimpleEWMA
|
||||||
|
|
||||||
|
A SimpleEWMA is designed for low CPU and memory consumption. It **will** have different behavior than the VariableEWMA
|
||||||
|
for multiple reasons. It has no warm-up period and it uses a constant
|
||||||
|
decay. These properties let it use less memory. It will also behave
|
||||||
|
differently when it's equal to zero, which is assumed to mean
|
||||||
|
uninitialized, so if a value is likely to actually become zero over time,
|
||||||
|
then any non-zero value will cause a sharp jump instead of a small change.
|
||||||
|
|
||||||
|
#### VariableEWMA
|
||||||
|
|
||||||
|
Unlike SimpleEWMA, this supports a custom age which must be stored, and thus uses more memory.
|
||||||
|
It also has a "warmup" time when you start adding values to it. It will report a value of 0.0
|
||||||
|
until you have added the required number of samples to it. It uses some memory to store the
|
||||||
|
number of samples added to it. As a result it uses a little over twice the memory of SimpleEWMA.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### API Documentation
|
||||||
|
|
||||||
|
View the GoDoc generated documentation [here](http://godoc.org/github.com/VividCortex/ewma).
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/VividCortex/ewma"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
samples := [100]float64{
|
||||||
|
4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149,
|
||||||
|
}
|
||||||
|
|
||||||
|
e := ewma.NewMovingAverage() //=> Returns a SimpleEWMA if called without params
|
||||||
|
a := ewma.NewMovingAverage(5) //=> returns a VariableEWMA with a decay of 2 / (5 + 1)
|
||||||
|
|
||||||
|
for _, f := range samples {
|
||||||
|
e.Add(f)
|
||||||
|
a.Add(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Value() //=> 13.577404704631077
|
||||||
|
a.Value() //=> 1.5806140565521463e-12
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
We only accept pull requests for minor fixes or improvements. This includes:
|
||||||
|
|
||||||
|
* Small bug fixes
|
||||||
|
* Typos
|
||||||
|
* Documentation or comments
|
||||||
|
|
||||||
|
Please open issues to discuss new features. Pull requests for new features will be rejected,
|
||||||
|
so we recommend forking the repository and making changes in your fork for your use case.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This repository is Copyright (c) 2013 VividCortex, Inc. All rights reserved.
|
||||||
|
It is licensed under the MIT license. Please see the LICENSE file for applicable license terms.
|
6
vendor/github.com/VividCortex/ewma/codecov.yml
generated
vendored
Normal file
6
vendor/github.com/VividCortex/ewma/codecov.yml
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
threshold: 15%
|
||||||
|
patch: off
|
126
vendor/github.com/VividCortex/ewma/ewma.go
generated
vendored
Normal file
126
vendor/github.com/VividCortex/ewma/ewma.go
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
// Package ewma implements exponentially weighted moving averages.
|
||||||
|
package ewma
|
||||||
|
|
||||||
|
// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
|
||||||
|
// Please see the LICENSE file for applicable license terms.
|
||||||
|
|
||||||
|
const (
|
||||||
|
// By default, we average over a one-minute period, which means the average
|
||||||
|
// age of the metrics in the period is 30 seconds.
|
||||||
|
AVG_METRIC_AGE float64 = 30.0
|
||||||
|
|
||||||
|
// The formula for computing the decay factor from the average age comes
|
||||||
|
// from "Production and Operations Analysis" by Steven Nahmias.
|
||||||
|
DECAY float64 = 2 / (float64(AVG_METRIC_AGE) + 1)
|
||||||
|
|
||||||
|
// For best results, the moving average should not be initialized to the
|
||||||
|
// samples it sees immediately. The book "Production and Operations
|
||||||
|
// Analysis" by Steven Nahmias suggests initializing the moving average to
|
||||||
|
// the mean of the first 10 samples. Until the VariableEwma has seen this
|
||||||
|
// many samples, it is not "ready" to be queried for the value of the
|
||||||
|
// moving average. This adds some memory cost.
|
||||||
|
WARMUP_SAMPLES uint8 = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
// MovingAverage is the interface that computes a moving average over a time-
|
||||||
|
// series stream of numbers. The average may be over a window or exponentially
|
||||||
|
// decaying.
|
||||||
|
type MovingAverage interface {
|
||||||
|
Add(float64)
|
||||||
|
Value() float64
|
||||||
|
Set(float64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMovingAverage constructs a MovingAverage that computes an average with the
|
||||||
|
// desired characteristics in the moving window or exponential decay. If no
|
||||||
|
// age is given, it constructs a default exponentially weighted implementation
|
||||||
|
// that consumes minimal memory. The age is related to the decay factor alpha
|
||||||
|
// by the formula given for the DECAY constant. It signifies the average age
|
||||||
|
// of the samples as time goes to infinity.
|
||||||
|
func NewMovingAverage(age ...float64) MovingAverage {
|
||||||
|
if len(age) == 0 || age[0] == AVG_METRIC_AGE {
|
||||||
|
return new(SimpleEWMA)
|
||||||
|
}
|
||||||
|
return &VariableEWMA{
|
||||||
|
decay: 2 / (age[0] + 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A SimpleEWMA represents the exponentially weighted moving average of a
|
||||||
|
// series of numbers. It WILL have different behavior than the VariableEWMA
|
||||||
|
// for multiple reasons. It has no warm-up period and it uses a constant
|
||||||
|
// decay. These properties let it use less memory. It will also behave
|
||||||
|
// differently when it's equal to zero, which is assumed to mean
|
||||||
|
// uninitialized, so if a value is likely to actually become zero over time,
|
||||||
|
// then any non-zero value will cause a sharp jump instead of a small change.
|
||||||
|
// However, note that this takes a long time, and the value may just
|
||||||
|
// decays to a stable value that's close to zero, but which won't be mistaken
|
||||||
|
// for uninitialized. See http://play.golang.org/p/litxBDr_RC for example.
|
||||||
|
type SimpleEWMA struct {
|
||||||
|
// The current value of the average. After adding with Add(), this is
|
||||||
|
// updated to reflect the average of all values seen thus far.
|
||||||
|
value float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds a value to the series and updates the moving average.
|
||||||
|
func (e *SimpleEWMA) Add(value float64) {
|
||||||
|
if e.value == 0 { // this is a proxy for "uninitialized"
|
||||||
|
e.value = value
|
||||||
|
} else {
|
||||||
|
e.value = (value * DECAY) + (e.value * (1 - DECAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the current value of the moving average.
|
||||||
|
func (e *SimpleEWMA) Value() float64 {
|
||||||
|
return e.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the EWMA's value.
|
||||||
|
func (e *SimpleEWMA) Set(value float64) {
|
||||||
|
e.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// VariableEWMA represents the exponentially weighted moving average of a series of
|
||||||
|
// numbers. Unlike SimpleEWMA, it supports a custom age, and thus uses more memory.
|
||||||
|
type VariableEWMA struct {
|
||||||
|
// The multiplier factor by which the previous samples decay.
|
||||||
|
decay float64
|
||||||
|
// The current value of the average.
|
||||||
|
value float64
|
||||||
|
// The number of samples added to this instance.
|
||||||
|
count uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds a value to the series and updates the moving average.
|
||||||
|
func (e *VariableEWMA) Add(value float64) {
|
||||||
|
switch {
|
||||||
|
case e.count < WARMUP_SAMPLES:
|
||||||
|
e.count++
|
||||||
|
e.value += value
|
||||||
|
case e.count == WARMUP_SAMPLES:
|
||||||
|
e.count++
|
||||||
|
e.value = e.value / float64(WARMUP_SAMPLES)
|
||||||
|
e.value = (value * e.decay) + (e.value * (1 - e.decay))
|
||||||
|
default:
|
||||||
|
e.value = (value * e.decay) + (e.value * (1 - e.decay))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the current value of the average, or 0.0 if the series hasn't
|
||||||
|
// warmed up yet.
|
||||||
|
func (e *VariableEWMA) Value() float64 {
|
||||||
|
if e.count <= WARMUP_SAMPLES {
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the EWMA's value.
|
||||||
|
func (e *VariableEWMA) Set(value float64) {
|
||||||
|
e.value = value
|
||||||
|
if e.count <= WARMUP_SAMPLES {
|
||||||
|
e.count = WARMUP_SAMPLES + 1
|
||||||
|
}
|
||||||
|
}
|
3
vendor/github.com/VividCortex/ewma/go.mod
generated
vendored
Normal file
3
vendor/github.com/VividCortex/ewma/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module github.com/VividCortex/ewma
|
||||||
|
|
||||||
|
go 1.12
|
6
vendor/github.com/andybalholm/cascadia/go.mod
generated
vendored
6
vendor/github.com/andybalholm/cascadia/go.mod
generated
vendored
|
@ -1,3 +1,5 @@
|
||||||
module "github.com/andybalholm/cascadia"
|
module github.com/andybalholm/cascadia
|
||||||
|
|
||||||
require "golang.org/x/net" v0.0.0-20180218175443-cbe0f9307d01
|
require golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
93
vendor/github.com/andybalholm/cascadia/parser.go
generated
vendored
93
vendor/github.com/andybalholm/cascadia/parser.go
generated
vendored
|
@ -13,6 +13,10 @@ import (
|
||||||
type parser struct {
|
type parser struct {
|
||||||
s string // the source text
|
s string // the source text
|
||||||
i int // the current position
|
i int // the current position
|
||||||
|
|
||||||
|
// if `false`, parsing a pseudo-element
|
||||||
|
// returns an error.
|
||||||
|
acceptPseudoElements bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseEscape parses a backslash escape.
|
// parseEscape parses a backslash escape.
|
||||||
|
@ -29,7 +33,7 @@ func (p *parser) parseEscape() (result string, err error) {
|
||||||
case hexDigit(c):
|
case hexDigit(c):
|
||||||
// unicode escape (hex)
|
// unicode escape (hex)
|
||||||
var i int
|
var i int
|
||||||
for i = start; i < p.i+6 && i < len(p.s) && hexDigit(p.s[i]); i++ {
|
for i = start; i < start+6 && i < len(p.s) && hexDigit(p.s[i]); i++ {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
v, _ := strconv.ParseUint(p.s[start:i], 16, 21)
|
v, _ := strconv.ParseUint(p.s[start:i], 16, 21)
|
||||||
|
@ -422,17 +426,25 @@ var errExpectedParenthesis = errors.New("expected '(' but didn't find it")
|
||||||
var errExpectedClosingParenthesis = errors.New("expected ')' but didn't find it")
|
var errExpectedClosingParenthesis = errors.New("expected ')' but didn't find it")
|
||||||
var errUnmatchedParenthesis = errors.New("unmatched '('")
|
var errUnmatchedParenthesis = errors.New("unmatched '('")
|
||||||
|
|
||||||
// parsePseudoclassSelector parses a pseudoclass selector like :not(p)
|
// parsePseudoclassSelector parses a pseudoclass selector like :not(p) or a pseudo-element
|
||||||
func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
|
// For backwards compatibility, both ':' and '::' prefix are allowed for pseudo-elements.
|
||||||
|
// https://drafts.csswg.org/selectors-3/#pseudo-elements
|
||||||
|
// Returning a nil `Sel` (and a nil `error`) means we found a pseudo-element.
|
||||||
|
func (p *parser) parsePseudoclassSelector() (out Sel, pseudoElement string, err error) {
|
||||||
if p.i >= len(p.s) {
|
if p.i >= len(p.s) {
|
||||||
return nil, fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead")
|
return nil, "", fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead")
|
||||||
}
|
}
|
||||||
if p.s[p.i] != ':' {
|
if p.s[p.i] != ':' {
|
||||||
return nil, fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i])
|
return nil, "", fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i])
|
||||||
}
|
}
|
||||||
|
|
||||||
p.i++
|
p.i++
|
||||||
|
var mustBePseudoElement bool
|
||||||
|
if p.i >= len(p.s) {
|
||||||
|
return nil, "", fmt.Errorf("got empty pseudoclass (or pseudoelement)")
|
||||||
|
}
|
||||||
if p.s[p.i] == ':' { // we found a pseudo-element
|
if p.s[p.i] == ':' { // we found a pseudo-element
|
||||||
|
mustBePseudoElement = true
|
||||||
p.i++
|
p.i++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,27 +453,33 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
name = toLowerASCII(name)
|
name = toLowerASCII(name)
|
||||||
|
if mustBePseudoElement && (name != "after" && name != "backdrop" && name != "before" &&
|
||||||
|
name != "cue" && name != "first-letter" && name != "first-line" && name != "grammar-error" &&
|
||||||
|
name != "marker" && name != "placeholder" && name != "selection" && name != "spelling-error") {
|
||||||
|
return out, "", fmt.Errorf("unknown pseudoelement :%s", name)
|
||||||
|
}
|
||||||
|
|
||||||
switch name {
|
switch name {
|
||||||
case "not", "has", "haschild":
|
case "not", "has", "haschild":
|
||||||
if !p.consumeParenthesis() {
|
if !p.consumeParenthesis() {
|
||||||
return out, errExpectedParenthesis
|
return out, "", errExpectedParenthesis
|
||||||
}
|
}
|
||||||
sel, parseErr := p.parseSelectorGroup()
|
sel, parseErr := p.parseSelectorGroup()
|
||||||
if parseErr != nil {
|
if parseErr != nil {
|
||||||
return out, parseErr
|
return out, "", parseErr
|
||||||
}
|
}
|
||||||
if !p.consumeClosingParenthesis() {
|
if !p.consumeClosingParenthesis() {
|
||||||
return out, errExpectedClosingParenthesis
|
return out, "", errExpectedClosingParenthesis
|
||||||
}
|
}
|
||||||
|
|
||||||
out = relativePseudoClassSelector{name: name, match: sel}
|
out = relativePseudoClassSelector{name: name, match: sel}
|
||||||
|
|
||||||
case "contains", "containsown":
|
case "contains", "containsown":
|
||||||
if !p.consumeParenthesis() {
|
if !p.consumeParenthesis() {
|
||||||
return out, errExpectedParenthesis
|
return out, "", errExpectedParenthesis
|
||||||
}
|
}
|
||||||
if p.i == len(p.s) {
|
if p.i == len(p.s) {
|
||||||
return out, errUnmatchedParenthesis
|
return out, "", errUnmatchedParenthesis
|
||||||
}
|
}
|
||||||
var val string
|
var val string
|
||||||
switch p.s[p.i] {
|
switch p.s[p.i] {
|
||||||
|
@ -471,46 +489,46 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
|
||||||
val, err = p.parseIdentifier()
|
val, err = p.parseIdentifier()
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, "", err
|
||||||
}
|
}
|
||||||
val = strings.ToLower(val)
|
val = strings.ToLower(val)
|
||||||
p.skipWhitespace()
|
p.skipWhitespace()
|
||||||
if p.i >= len(p.s) {
|
if p.i >= len(p.s) {
|
||||||
return out, errors.New("unexpected EOF in pseudo selector")
|
return out, "", errors.New("unexpected EOF in pseudo selector")
|
||||||
}
|
}
|
||||||
if !p.consumeClosingParenthesis() {
|
if !p.consumeClosingParenthesis() {
|
||||||
return out, errExpectedClosingParenthesis
|
return out, "", errExpectedClosingParenthesis
|
||||||
}
|
}
|
||||||
|
|
||||||
out = containsPseudoClassSelector{own: name == "containsown", value: val}
|
out = containsPseudoClassSelector{own: name == "containsown", value: val}
|
||||||
|
|
||||||
case "matches", "matchesown":
|
case "matches", "matchesown":
|
||||||
if !p.consumeParenthesis() {
|
if !p.consumeParenthesis() {
|
||||||
return out, errExpectedParenthesis
|
return out, "", errExpectedParenthesis
|
||||||
}
|
}
|
||||||
rx, err := p.parseRegex()
|
rx, err := p.parseRegex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, "", err
|
||||||
}
|
}
|
||||||
if p.i >= len(p.s) {
|
if p.i >= len(p.s) {
|
||||||
return out, errors.New("unexpected EOF in pseudo selector")
|
return out, "", errors.New("unexpected EOF in pseudo selector")
|
||||||
}
|
}
|
||||||
if !p.consumeClosingParenthesis() {
|
if !p.consumeClosingParenthesis() {
|
||||||
return out, errExpectedClosingParenthesis
|
return out, "", errExpectedClosingParenthesis
|
||||||
}
|
}
|
||||||
|
|
||||||
out = regexpPseudoClassSelector{own: name == "matchesown", regexp: rx}
|
out = regexpPseudoClassSelector{own: name == "matchesown", regexp: rx}
|
||||||
|
|
||||||
case "nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type":
|
case "nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type":
|
||||||
if !p.consumeParenthesis() {
|
if !p.consumeParenthesis() {
|
||||||
return out, errExpectedParenthesis
|
return out, "", errExpectedParenthesis
|
||||||
}
|
}
|
||||||
a, b, err := p.parseNth()
|
a, b, err := p.parseNth()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, "", err
|
||||||
}
|
}
|
||||||
if !p.consumeClosingParenthesis() {
|
if !p.consumeClosingParenthesis() {
|
||||||
return out, errExpectedClosingParenthesis
|
return out, "", errExpectedClosingParenthesis
|
||||||
}
|
}
|
||||||
last := name == "nth-last-child" || name == "nth-last-of-type"
|
last := name == "nth-last-child" || name == "nth-last-of-type"
|
||||||
ofType := name == "nth-of-type" || name == "nth-last-of-type"
|
ofType := name == "nth-of-type" || name == "nth-last-of-type"
|
||||||
|
@ -535,9 +553,9 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
|
||||||
case "root":
|
case "root":
|
||||||
out = rootPseudoClassSelector{}
|
out = rootPseudoClassSelector{}
|
||||||
case "after", "backdrop", "before", "cue", "first-letter", "first-line", "grammar-error", "marker", "placeholder", "selection", "spelling-error":
|
case "after", "backdrop", "before", "cue", "first-letter", "first-line", "grammar-error", "marker", "placeholder", "selection", "spelling-error":
|
||||||
return out, errors.New("pseudo-elements are not yet supported")
|
return nil, name, nil
|
||||||
default:
|
default:
|
||||||
return out, fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name)
|
return out, "", fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -706,11 +724,13 @@ func (p *parser) parseSimpleSelectorSequence() (Sel, error) {
|
||||||
selectors = append(selectors, r)
|
selectors = append(selectors, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pseudoElement string
|
||||||
loop:
|
loop:
|
||||||
for p.i < len(p.s) {
|
for p.i < len(p.s) {
|
||||||
var (
|
var (
|
||||||
ns Sel
|
ns Sel
|
||||||
err error
|
newPseudoElement string
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
switch p.s[p.i] {
|
switch p.s[p.i] {
|
||||||
case '#':
|
case '#':
|
||||||
|
@ -720,20 +740,37 @@ loop:
|
||||||
case '[':
|
case '[':
|
||||||
ns, err = p.parseAttributeSelector()
|
ns, err = p.parseAttributeSelector()
|
||||||
case ':':
|
case ':':
|
||||||
ns, err = p.parsePseudoclassSelector()
|
ns, newPseudoElement, err = p.parsePseudoclassSelector()
|
||||||
default:
|
default:
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// From https://drafts.csswg.org/selectors-3/#pseudo-elements :
|
||||||
|
// "Only one pseudo-element may appear per selector, and if present
|
||||||
|
// it must appear after the sequence of simple selectors that
|
||||||
|
// represents the subjects of the selector.""
|
||||||
|
if ns == nil { // we found a pseudo-element
|
||||||
|
if pseudoElement != "" {
|
||||||
|
return nil, fmt.Errorf("only one pseudo-element is accepted per selector, got %s and %s", pseudoElement, newPseudoElement)
|
||||||
|
}
|
||||||
|
if !p.acceptPseudoElements {
|
||||||
|
return nil, fmt.Errorf("pseudo-element %s found, but pseudo-elements support is disabled", newPseudoElement)
|
||||||
|
}
|
||||||
|
pseudoElement = newPseudoElement
|
||||||
|
} else {
|
||||||
|
if pseudoElement != "" {
|
||||||
|
return nil, fmt.Errorf("pseudo-element %s must be at the end of selector", pseudoElement)
|
||||||
|
}
|
||||||
|
selectors = append(selectors, ns)
|
||||||
|
}
|
||||||
|
|
||||||
selectors = append(selectors, ns)
|
|
||||||
}
|
}
|
||||||
if len(selectors) == 1 { // no need wrap the selectors in compoundSelector
|
if len(selectors) == 1 && pseudoElement == "" { // no need wrap the selectors in compoundSelector
|
||||||
return selectors[0], nil
|
return selectors[0], nil
|
||||||
}
|
}
|
||||||
return compoundSelector{selectors: selectors}, nil
|
return compoundSelector{selectors: selectors, pseudoElement: pseudoElement}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseSelector parses a selector that may include combinators.
|
// parseSelector parses a selector that may include combinators.
|
||||||
|
|
113
vendor/github.com/andybalholm/cascadia/selector.go
generated
vendored
113
vendor/github.com/andybalholm/cascadia/selector.go
generated
vendored
|
@ -16,14 +16,19 @@ type Matcher interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sel is the interface for all the functionality provided by selectors.
|
// Sel is the interface for all the functionality provided by selectors.
|
||||||
// It is currently the same as Matcher, but other methods may be added in the
|
|
||||||
// future.
|
|
||||||
type Sel interface {
|
type Sel interface {
|
||||||
Matcher
|
Matcher
|
||||||
Specificity() Specificity
|
Specificity() Specificity
|
||||||
|
|
||||||
|
// Returns a CSS input compiling to this selector.
|
||||||
|
String() string
|
||||||
|
|
||||||
|
// Returns a pseudo-element, or an empty string.
|
||||||
|
PseudoElement() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses a selector.
|
// Parse parses a selector. Use `ParseWithPseudoElement`
|
||||||
|
// if you need support for pseudo-elements.
|
||||||
func Parse(sel string) (Sel, error) {
|
func Parse(sel string) (Sel, error) {
|
||||||
p := &parser{s: sel}
|
p := &parser{s: sel}
|
||||||
compiled, err := p.parseSelector()
|
compiled, err := p.parseSelector()
|
||||||
|
@ -38,7 +43,25 @@ func Parse(sel string) (Sel, error) {
|
||||||
return compiled, nil
|
return compiled, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseWithPseudoElement parses a single selector,
|
||||||
|
// with support for pseudo-element.
|
||||||
|
func ParseWithPseudoElement(sel string) (Sel, error) {
|
||||||
|
p := &parser{s: sel, acceptPseudoElements: true}
|
||||||
|
compiled, err := p.parseSelector()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.i < len(sel) {
|
||||||
|
return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return compiled, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ParseGroup parses a selector, or a group of selectors separated by commas.
|
// ParseGroup parses a selector, or a group of selectors separated by commas.
|
||||||
|
// Use `ParseGroupWithPseudoElements`
|
||||||
|
// if you need support for pseudo-elements.
|
||||||
func ParseGroup(sel string) (SelectorGroup, error) {
|
func ParseGroup(sel string) (SelectorGroup, error) {
|
||||||
p := &parser{s: sel}
|
p := &parser{s: sel}
|
||||||
compiled, err := p.parseSelectorGroup()
|
compiled, err := p.parseSelectorGroup()
|
||||||
|
@ -53,6 +76,22 @@ func ParseGroup(sel string) (SelectorGroup, error) {
|
||||||
return compiled, nil
|
return compiled, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseGroupWithPseudoElements parses a selector, or a group of selectors separated by commas.
|
||||||
|
// It supports pseudo-elements.
|
||||||
|
func ParseGroupWithPseudoElements(sel string) (SelectorGroup, error) {
|
||||||
|
p := &parser{s: sel, acceptPseudoElements: true}
|
||||||
|
compiled, err := p.parseSelectorGroup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.i < len(sel) {
|
||||||
|
return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return compiled, nil
|
||||||
|
}
|
||||||
|
|
||||||
// A Selector is a function which tells whether a node matches or not.
|
// A Selector is a function which tells whether a node matches or not.
|
||||||
//
|
//
|
||||||
// This type is maintained for compatibility; I recommend using the newer and
|
// This type is maintained for compatibility; I recommend using the newer and
|
||||||
|
@ -182,6 +221,10 @@ func (c tagSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 0, 1}
|
return Specificity{0, 0, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c tagSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type classSelector struct {
|
type classSelector struct {
|
||||||
class string
|
class string
|
||||||
}
|
}
|
||||||
|
@ -197,6 +240,10 @@ func (c classSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c classSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type idSelector struct {
|
type idSelector struct {
|
||||||
id string
|
id string
|
||||||
}
|
}
|
||||||
|
@ -212,6 +259,10 @@ func (c idSelector) Specificity() Specificity {
|
||||||
return Specificity{1, 0, 0}
|
return Specificity{1, 0, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c idSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type attrSelector struct {
|
type attrSelector struct {
|
||||||
key, val, operation string
|
key, val, operation string
|
||||||
regexp *regexp.Regexp
|
regexp *regexp.Regexp
|
||||||
|
@ -352,6 +403,10 @@ func (c attrSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c attrSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------- Pseudo class selectors ----------------
|
// ---------------- Pseudo class selectors ----------------
|
||||||
// we use severals concrete types of pseudo-class selectors
|
// we use severals concrete types of pseudo-class selectors
|
||||||
|
|
||||||
|
@ -415,6 +470,10 @@ func (s relativePseudoClassSelector) Specificity() Specificity {
|
||||||
return max
|
return max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c relativePseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type containsPseudoClassSelector struct {
|
type containsPseudoClassSelector struct {
|
||||||
own bool
|
own bool
|
||||||
value string
|
value string
|
||||||
|
@ -436,6 +495,10 @@ func (s containsPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c containsPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type regexpPseudoClassSelector struct {
|
type regexpPseudoClassSelector struct {
|
||||||
own bool
|
own bool
|
||||||
regexp *regexp.Regexp
|
regexp *regexp.Regexp
|
||||||
|
@ -488,6 +551,10 @@ func (s regexpPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c regexpPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type nthPseudoClassSelector struct {
|
type nthPseudoClassSelector struct {
|
||||||
a, b int
|
a, b int
|
||||||
last, ofType bool
|
last, ofType bool
|
||||||
|
@ -623,6 +690,10 @@ func (s nthPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c nthPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type onlyChildPseudoClassSelector struct {
|
type onlyChildPseudoClassSelector struct {
|
||||||
ofType bool
|
ofType bool
|
||||||
}
|
}
|
||||||
|
@ -661,6 +732,10 @@ func (s onlyChildPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c onlyChildPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type inputPseudoClassSelector struct{}
|
type inputPseudoClassSelector struct{}
|
||||||
|
|
||||||
// Matches input, select, textarea and button elements.
|
// Matches input, select, textarea and button elements.
|
||||||
|
@ -672,6 +747,10 @@ func (s inputPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c inputPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type emptyElementPseudoClassSelector struct{}
|
type emptyElementPseudoClassSelector struct{}
|
||||||
|
|
||||||
// Matches empty elements.
|
// Matches empty elements.
|
||||||
|
@ -694,6 +773,10 @@ func (s emptyElementPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c emptyElementPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type rootPseudoClassSelector struct{}
|
type rootPseudoClassSelector struct{}
|
||||||
|
|
||||||
// Match implements :root
|
// Match implements :root
|
||||||
|
@ -711,8 +794,13 @@ func (s rootPseudoClassSelector) Specificity() Specificity {
|
||||||
return Specificity{0, 1, 0}
|
return Specificity{0, 1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c rootPseudoClassSelector) PseudoElement() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type compoundSelector struct {
|
type compoundSelector struct {
|
||||||
selectors []Sel
|
selectors []Sel
|
||||||
|
pseudoElement string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matches elements if each sub-selectors matches.
|
// Matches elements if each sub-selectors matches.
|
||||||
|
@ -734,9 +822,17 @@ func (s compoundSelector) Specificity() Specificity {
|
||||||
for _, sel := range s.selectors {
|
for _, sel := range s.selectors {
|
||||||
out = out.Add(sel.Specificity())
|
out = out.Add(sel.Specificity())
|
||||||
}
|
}
|
||||||
|
if s.pseudoElement != "" {
|
||||||
|
// https://drafts.csswg.org/selectors-3/#specificity
|
||||||
|
out = out.Add(Specificity{0, 0, 1})
|
||||||
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c compoundSelector) PseudoElement() string {
|
||||||
|
return c.pseudoElement
|
||||||
|
}
|
||||||
|
|
||||||
type combinedSelector struct {
|
type combinedSelector struct {
|
||||||
first Sel
|
first Sel
|
||||||
combinator byte
|
combinator byte
|
||||||
|
@ -818,6 +914,15 @@ func (s combinedSelector) Specificity() Specificity {
|
||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// on combinedSelector, a pseudo-element only makes sens on the last
|
||||||
|
// selector, although others increase specificity.
|
||||||
|
func (c combinedSelector) PseudoElement() string {
|
||||||
|
if c.second == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return c.second.PseudoElement()
|
||||||
|
}
|
||||||
|
|
||||||
// A SelectorGroup is a list of selectors, which matches if any of the
|
// A SelectorGroup is a list of selectors, which matches if any of the
|
||||||
// individual selectors matches.
|
// individual selectors matches.
|
||||||
type SelectorGroup []Sel
|
type SelectorGroup []Sel
|
||||||
|
|
120
vendor/github.com/andybalholm/cascadia/serialize.go
generated
vendored
Normal file
120
vendor/github.com/andybalholm/cascadia/serialize.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
package cascadia
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// implements the reverse operation Sel -> string
|
||||||
|
|
||||||
|
func (c tagSelector) String() string {
|
||||||
|
return c.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c idSelector) String() string {
|
||||||
|
return "#" + c.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c classSelector) String() string {
|
||||||
|
return "." + c.class
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c attrSelector) String() string {
|
||||||
|
val := c.val
|
||||||
|
if c.operation == "#=" {
|
||||||
|
val = c.regexp.String()
|
||||||
|
} else if c.operation != "" {
|
||||||
|
val = fmt.Sprintf(`"%s"`, val)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`[%s%s%s]`, c.key, c.operation, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c relativePseudoClassSelector) String() string {
|
||||||
|
return fmt.Sprintf(":%s(%s)", c.name, c.match.String())
|
||||||
|
}
|
||||||
|
func (c containsPseudoClassSelector) String() string {
|
||||||
|
s := "contains"
|
||||||
|
if c.own {
|
||||||
|
s += "Own"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`:%s("%s")`, s, c.value)
|
||||||
|
}
|
||||||
|
func (c regexpPseudoClassSelector) String() string {
|
||||||
|
s := "matches"
|
||||||
|
if c.own {
|
||||||
|
s += "Own"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(":%s(%s)", s, c.regexp.String())
|
||||||
|
}
|
||||||
|
func (c nthPseudoClassSelector) String() string {
|
||||||
|
if c.a == 0 && c.b == 1 { // special cases
|
||||||
|
s := ":first-"
|
||||||
|
if c.last {
|
||||||
|
s = ":last-"
|
||||||
|
}
|
||||||
|
if c.ofType {
|
||||||
|
s += "of-type"
|
||||||
|
} else {
|
||||||
|
s += "child"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
var name string
|
||||||
|
switch [2]bool{c.last, c.ofType} {
|
||||||
|
case [2]bool{true, true}:
|
||||||
|
name = "nth-last-of-type"
|
||||||
|
case [2]bool{true, false}:
|
||||||
|
name = "nth-last-child"
|
||||||
|
case [2]bool{false, true}:
|
||||||
|
name = "nth-of-type"
|
||||||
|
case [2]bool{false, false}:
|
||||||
|
name = "nth-child"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(":%s(%dn+%d)", name, c.a, c.b)
|
||||||
|
}
|
||||||
|
func (c onlyChildPseudoClassSelector) String() string {
|
||||||
|
if c.ofType {
|
||||||
|
return ":only-of-type"
|
||||||
|
}
|
||||||
|
return ":only-child"
|
||||||
|
}
|
||||||
|
func (c inputPseudoClassSelector) String() string {
|
||||||
|
return ":input"
|
||||||
|
}
|
||||||
|
func (c emptyElementPseudoClassSelector) String() string {
|
||||||
|
return ":empty"
|
||||||
|
}
|
||||||
|
func (c rootPseudoClassSelector) String() string {
|
||||||
|
return ":root"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c compoundSelector) String() string {
|
||||||
|
if len(c.selectors) == 0 && c.pseudoElement == "" {
|
||||||
|
return "*"
|
||||||
|
}
|
||||||
|
chunks := make([]string, len(c.selectors))
|
||||||
|
for i, sel := range c.selectors {
|
||||||
|
chunks[i] = sel.String()
|
||||||
|
}
|
||||||
|
s := strings.Join(chunks, "")
|
||||||
|
if c.pseudoElement != "" {
|
||||||
|
s += "::" + c.pseudoElement
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c combinedSelector) String() string {
|
||||||
|
start := c.first.String()
|
||||||
|
if c.second != nil {
|
||||||
|
start += fmt.Sprintf(" %s %s", string(c.combinator), c.second.String())
|
||||||
|
}
|
||||||
|
return start
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c SelectorGroup) String() string {
|
||||||
|
ck := make([]string, len(c))
|
||||||
|
for i, s := range c {
|
||||||
|
ck[i] = s.String()
|
||||||
|
}
|
||||||
|
return strings.Join(ck, ", ")
|
||||||
|
}
|
12
vendor/github.com/cheggaaa/pb/v3/LICENSE
generated
vendored
Normal file
12
vendor/github.com/cheggaaa/pb/v3/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Copyright (c) 2012-2015, Sergey Cherepanov
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
330
vendor/github.com/cheggaaa/pb/v3/element.go
generated
vendored
Normal file
330
vendor/github.com/cheggaaa/pb/v3/element.go
generated
vendored
Normal file
|
@ -0,0 +1,330 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
adElPlaceholder = "%_ad_el_%"
|
||||||
|
adElPlaceholderLen = len(adElPlaceholder)
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultBarEls = [5]string{"[", "-", ">", "_", "]"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Element is an interface for bar elements
|
||||||
|
type Element interface {
|
||||||
|
ProgressElement(state *State, args ...string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementFunc type implements Element interface and created for simplify elements
|
||||||
|
type ElementFunc func(state *State, args ...string) string
|
||||||
|
|
||||||
|
// ProgressElement just call self func
|
||||||
|
func (e ElementFunc) ProgressElement(state *State, args ...string) string {
|
||||||
|
return e(state, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var elementsM sync.Mutex
|
||||||
|
|
||||||
|
var elements = map[string]Element{
|
||||||
|
"percent": ElementPercent,
|
||||||
|
"counters": ElementCounters,
|
||||||
|
"bar": adaptiveWrap(ElementBar),
|
||||||
|
"speed": ElementSpeed,
|
||||||
|
"rtime": ElementRemainingTime,
|
||||||
|
"etime": ElementElapsedTime,
|
||||||
|
"string": ElementString,
|
||||||
|
"cycle": ElementCycle,
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterElement give you a chance to use custom elements
|
||||||
|
func RegisterElement(name string, el Element, adaptive bool) {
|
||||||
|
if adaptive {
|
||||||
|
el = adaptiveWrap(el)
|
||||||
|
}
|
||||||
|
elementsM.Lock()
|
||||||
|
elements[name] = el
|
||||||
|
elementsM.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
type argsHelper []string
|
||||||
|
|
||||||
|
func (args argsHelper) getOr(n int, value string) string {
|
||||||
|
if len(args) > n {
|
||||||
|
return args[n]
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args argsHelper) getNotEmptyOr(n int, value string) (v string) {
|
||||||
|
if v = args.getOr(n, value); v == "" {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func adaptiveWrap(el Element) Element {
|
||||||
|
return ElementFunc(func(state *State, args ...string) string {
|
||||||
|
state.recalc = append(state.recalc, ElementFunc(func(s *State, _ ...string) (result string) {
|
||||||
|
s.adaptive = true
|
||||||
|
result = el.ProgressElement(s, args...)
|
||||||
|
s.adaptive = false
|
||||||
|
return
|
||||||
|
}))
|
||||||
|
return adElPlaceholder
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementPercent shows current percent of progress.
|
||||||
|
// Optionally can take one or two string arguments.
|
||||||
|
// First string will be used as value for format float64, default is "%.02f%%".
|
||||||
|
// Second string will be used when percent can't be calculated, default is "?%"
|
||||||
|
// In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}}
|
||||||
|
var ElementPercent ElementFunc = func(state *State, args ...string) string {
|
||||||
|
argsh := argsHelper(args)
|
||||||
|
if state.Total() > 0 {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
argsh.getNotEmptyOr(0, "%.02f%%"),
|
||||||
|
float64(state.Value())/(float64(state.Total())/float64(100)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return argsh.getOr(1, "?%")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementCounters shows current and total values.
|
||||||
|
// Optionally can take one or two string arguments.
|
||||||
|
// First string will be used as format value when Total is present (>0). Default is "%s / %s"
|
||||||
|
// Second string will be used when total <= 0. Default is "%[1]s"
|
||||||
|
// In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}}
|
||||||
|
var ElementCounters ElementFunc = func(state *State, args ...string) string {
|
||||||
|
var f string
|
||||||
|
if state.Total() > 0 {
|
||||||
|
f = argsHelper(args).getNotEmptyOr(0, "%s / %s")
|
||||||
|
} else {
|
||||||
|
f = argsHelper(args).getNotEmptyOr(1, "%[1]s")
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total()))
|
||||||
|
}
|
||||||
|
|
||||||
|
type elementKey int
|
||||||
|
|
||||||
|
const (
|
||||||
|
barObj elementKey = iota
|
||||||
|
speedObj
|
||||||
|
cycleObj
|
||||||
|
)
|
||||||
|
|
||||||
|
type bar struct {
|
||||||
|
eb [5][]byte // elements in bytes
|
||||||
|
cc [5]int // cell counts
|
||||||
|
buf *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *bar) write(state *State, eln, width int) int {
|
||||||
|
repeat := width / p.cc[eln]
|
||||||
|
remainder := width % p.cc[eln]
|
||||||
|
for i := 0; i < repeat; i++ {
|
||||||
|
p.buf.Write(p.eb[eln])
|
||||||
|
}
|
||||||
|
if remainder > 0 {
|
||||||
|
StripStringToBuffer(string(p.eb[eln]), remainder, p.buf)
|
||||||
|
}
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProgressObj(state *State, args ...string) (p *bar) {
|
||||||
|
var ok bool
|
||||||
|
if p, ok = state.Get(barObj).(*bar); !ok {
|
||||||
|
p = &bar{
|
||||||
|
buf: bytes.NewBuffer(nil),
|
||||||
|
}
|
||||||
|
state.Set(barObj, p)
|
||||||
|
}
|
||||||
|
argsH := argsHelper(args)
|
||||||
|
for i := range p.eb {
|
||||||
|
arg := argsH.getNotEmptyOr(i, defaultBarEls[i])
|
||||||
|
if string(p.eb[i]) != arg {
|
||||||
|
p.cc[i] = CellCount(arg)
|
||||||
|
p.eb[i] = []byte(arg)
|
||||||
|
if p.cc[i] == 0 {
|
||||||
|
p.cc[i] = 1
|
||||||
|
p.eb[i] = []byte(" ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementBar make progress bar view [-->__]
|
||||||
|
// Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]"
|
||||||
|
// In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}}
|
||||||
|
// Color args: {{bar . (red "[") (green "-") ...
|
||||||
|
var ElementBar ElementFunc = func(state *State, args ...string) string {
|
||||||
|
// init
|
||||||
|
var p = getProgressObj(state, args...)
|
||||||
|
|
||||||
|
total, value := state.Total(), state.Value()
|
||||||
|
if total < 0 {
|
||||||
|
total = -total
|
||||||
|
}
|
||||||
|
if value < 0 {
|
||||||
|
value = -value
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for overflow
|
||||||
|
if total != 0 && value > total {
|
||||||
|
total = value
|
||||||
|
}
|
||||||
|
|
||||||
|
p.buf.Reset()
|
||||||
|
|
||||||
|
var widthLeft = state.AdaptiveElWidth()
|
||||||
|
if widthLeft <= 0 || !state.IsAdaptiveWidth() {
|
||||||
|
widthLeft = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
// write left border
|
||||||
|
if p.cc[0] < widthLeft {
|
||||||
|
widthLeft -= p.write(state, 0, p.cc[0])
|
||||||
|
} else {
|
||||||
|
p.write(state, 0, widthLeft)
|
||||||
|
return p.buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// check right border size
|
||||||
|
if p.cc[4] < widthLeft {
|
||||||
|
// write later
|
||||||
|
widthLeft -= p.cc[4]
|
||||||
|
} else {
|
||||||
|
p.write(state, 4, widthLeft)
|
||||||
|
return p.buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
var curCount int
|
||||||
|
|
||||||
|
if total > 0 {
|
||||||
|
// calculate count of currenct space
|
||||||
|
curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// write bar
|
||||||
|
if total == value && state.IsFinished() {
|
||||||
|
widthLeft -= p.write(state, 1, curCount)
|
||||||
|
} else if toWrite := curCount - p.cc[2]; toWrite > 0 {
|
||||||
|
widthLeft -= p.write(state, 1, toWrite)
|
||||||
|
widthLeft -= p.write(state, 2, p.cc[2])
|
||||||
|
} else if curCount > 0 {
|
||||||
|
widthLeft -= p.write(state, 2, curCount)
|
||||||
|
}
|
||||||
|
if widthLeft > 0 {
|
||||||
|
widthLeft -= p.write(state, 3, widthLeft)
|
||||||
|
}
|
||||||
|
// write right border
|
||||||
|
p.write(state, 4, p.cc[4])
|
||||||
|
// cut result and return string
|
||||||
|
return p.buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func elapsedTime(state *State) string {
|
||||||
|
elapsed := state.Time().Sub(state.StartTime())
|
||||||
|
var precision time.Duration
|
||||||
|
var ok bool
|
||||||
|
if precision, ok = state.Get(TimeRound).(time.Duration); !ok {
|
||||||
|
// default behavior: round to nearest .1s when elapsed < 10s
|
||||||
|
//
|
||||||
|
// we compare with 9.95s as opposed to 10s to avoid an annoying
|
||||||
|
// interaction with the fixed precision display code below,
|
||||||
|
// where 9.9s would be rounded to 10s but printed as 10.0s, and
|
||||||
|
// then 10.0s would be rounded to 10s and printed as 10s
|
||||||
|
if elapsed < 9950*time.Millisecond {
|
||||||
|
precision = 100 * time.Millisecond
|
||||||
|
} else {
|
||||||
|
precision = time.Second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rounded := elapsed.Round(precision)
|
||||||
|
if precision < time.Second && rounded >= time.Second {
|
||||||
|
// special handling to ensure string is shown with the given
|
||||||
|
// precision, with trailing zeros after the decimal point if
|
||||||
|
// necessary
|
||||||
|
reference := (2*time.Second - time.Nanosecond).Truncate(precision).String()
|
||||||
|
// reference looks like "1.9[...]9s", telling us how many
|
||||||
|
// decimal digits we need
|
||||||
|
neededDecimals := len(reference) - 3
|
||||||
|
s := rounded.String()
|
||||||
|
dotIndex := strings.LastIndex(s, ".")
|
||||||
|
if dotIndex != -1 {
|
||||||
|
// s has the form "[stuff].[decimals]s"
|
||||||
|
decimals := len(s) - dotIndex - 2
|
||||||
|
extraZeros := neededDecimals - decimals
|
||||||
|
return fmt.Sprintf("%s%ss", s[:len(s)-1], strings.Repeat("0", extraZeros))
|
||||||
|
} else {
|
||||||
|
// s has the form "[stuff]s"
|
||||||
|
return fmt.Sprintf("%s.%ss", s[:len(s)-1], strings.Repeat("0", neededDecimals))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return rounded.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementRemainingTime calculates remaining time based on speed (EWMA)
|
||||||
|
// Optionally can take one or two string arguments.
|
||||||
|
// First string will be used as value for format time duration string, default is "%s".
|
||||||
|
// Second string will be used when bar finished and value indicates elapsed time, default is "%s"
|
||||||
|
// Third string will be used when value not available, default is "?"
|
||||||
|
// In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}}
|
||||||
|
var ElementRemainingTime ElementFunc = func(state *State, args ...string) string {
|
||||||
|
if state.IsFinished() {
|
||||||
|
return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), elapsedTime(state))
|
||||||
|
}
|
||||||
|
sp := getSpeedObj(state).value(state)
|
||||||
|
if sp > 0 {
|
||||||
|
remain := float64(state.Total() - state.Value())
|
||||||
|
remainDur := time.Duration(remain/sp) * time.Second
|
||||||
|
return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), remainDur)
|
||||||
|
}
|
||||||
|
return argsHelper(args).getOr(2, "?")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementElapsedTime shows elapsed time
|
||||||
|
// Optionally can take one argument - it's format for time string.
|
||||||
|
// In template use as follows: {{etime .}} or {{etime . "%s elapsed"}}
|
||||||
|
var ElementElapsedTime ElementFunc = func(state *State, args ...string) string {
|
||||||
|
return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), elapsedTime(state))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementString get value from bar by given key and print them
|
||||||
|
// bar.Set("myKey", "string to print")
|
||||||
|
// In template use as follows: {{string . "myKey"}}
|
||||||
|
var ElementString ElementFunc = func(state *State, args ...string) string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
v := state.Get(args[0])
|
||||||
|
if v == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprint(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementCycle return next argument for every call
|
||||||
|
// In template use as follows: {{cycle . "1" "2" "3"}}
|
||||||
|
// Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}}
|
||||||
|
var ElementCycle ElementFunc = func(state *State, args ...string) string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
n, _ := state.Get(cycleObj).(int)
|
||||||
|
if n >= len(args) {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
state.Set(cycleObj, n+1)
|
||||||
|
return args[n]
|
||||||
|
}
|
13
vendor/github.com/cheggaaa/pb/v3/go.mod
generated
vendored
Normal file
13
vendor/github.com/cheggaaa/pb/v3/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
module github.com/cheggaaa/pb/v3
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/VividCortex/ewma v1.1.1
|
||||||
|
github.com/fatih/color v1.10.0
|
||||||
|
github.com/mattn/go-colorable v0.1.8
|
||||||
|
github.com/mattn/go-isatty v0.0.12
|
||||||
|
github.com/mattn/go-runewidth v0.0.12
|
||||||
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
go 1.12
|
17
vendor/github.com/cheggaaa/pb/v3/go.sum
generated
vendored
Normal file
17
vendor/github.com/cheggaaa/pb/v3/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||||
|
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||||
|
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||||
|
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||||
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
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.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
|
||||||
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
|
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=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
|
||||||
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
49
vendor/github.com/cheggaaa/pb/v3/io.go
generated
vendored
Normal file
49
vendor/github.com/cheggaaa/pb/v3/io.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reader it's a wrapper for given reader, but with progress handle
|
||||||
|
type Reader struct {
|
||||||
|
io.Reader
|
||||||
|
bar *ProgressBar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads bytes from wrapped reader and add amount of bytes to progress bar
|
||||||
|
func (r *Reader) Read(p []byte) (n int, err error) {
|
||||||
|
n, err = r.Reader.Read(p)
|
||||||
|
r.bar.Add(n)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the wrapped reader when it implements io.Closer
|
||||||
|
func (r *Reader) Close() (err error) {
|
||||||
|
r.bar.Finish()
|
||||||
|
if closer, ok := r.Reader.(io.Closer); ok {
|
||||||
|
return closer.Close()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writer it's a wrapper for given writer, but with progress handle
|
||||||
|
type Writer struct {
|
||||||
|
io.Writer
|
||||||
|
bar *ProgressBar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes bytes to wrapped writer and add amount of bytes to progress bar
|
||||||
|
func (r *Writer) Write(p []byte) (n int, err error) {
|
||||||
|
n, err = r.Writer.Write(p)
|
||||||
|
r.bar.Add(n)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the wrapped reader when it implements io.Closer
|
||||||
|
func (r *Writer) Close() (err error) {
|
||||||
|
r.bar.Finish()
|
||||||
|
if closer, ok := r.Writer.(io.Closer); ok {
|
||||||
|
return closer.Close()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
588
vendor/github.com/cheggaaa/pb/v3/pb.go
generated
vendored
Normal file
588
vendor/github.com/cheggaaa/pb/v3/pb.go
generated
vendored
Normal file
|
@ -0,0 +1,588 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
|
||||||
|
"github.com/mattn/go-colorable"
|
||||||
|
"github.com/mattn/go-isatty"
|
||||||
|
|
||||||
|
"github.com/cheggaaa/pb/v3/termutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Version of ProgressBar library
|
||||||
|
const Version = "3.0.8"
|
||||||
|
|
||||||
|
type key int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc
|
||||||
|
// bar.Set(pb.Bytes, true)
|
||||||
|
Bytes key = 1 << iota
|
||||||
|
|
||||||
|
// Use SI bytes prefix names (kB, MB, etc) instead of IEC prefix names (KiB, MiB, etc)
|
||||||
|
SIBytesPrefix
|
||||||
|
|
||||||
|
// Terminal means we're will print to terminal and can use ascii sequences
|
||||||
|
// Also we're will try to use terminal width
|
||||||
|
Terminal
|
||||||
|
|
||||||
|
// Static means progress bar will not update automaticly
|
||||||
|
Static
|
||||||
|
|
||||||
|
// ReturnSymbol - by default in terminal mode it's '\r'
|
||||||
|
ReturnSymbol
|
||||||
|
|
||||||
|
// Color by default is true when output is tty, but you can set to false for disabling colors
|
||||||
|
Color
|
||||||
|
|
||||||
|
// Hide the progress bar when finished, rather than leaving it up. By default it's false.
|
||||||
|
CleanOnFinish
|
||||||
|
|
||||||
|
// Round elapsed time to this precision. Defaults to time.Second.
|
||||||
|
TimeRound
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultBarWidth = 100
|
||||||
|
defaultRefreshRate = time.Millisecond * 200
|
||||||
|
)
|
||||||
|
|
||||||
|
// New creates new ProgressBar object
|
||||||
|
func New(total int) *ProgressBar {
|
||||||
|
return New64(int64(total))
|
||||||
|
}
|
||||||
|
|
||||||
|
// New64 creates new ProgressBar object using int64 as total
|
||||||
|
func New64(total int64) *ProgressBar {
|
||||||
|
pb := new(ProgressBar)
|
||||||
|
return pb.SetTotal(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartNew starts new ProgressBar with Default template
|
||||||
|
func StartNew(total int) *ProgressBar {
|
||||||
|
return New(total).Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start64 starts new ProgressBar with Default template. Using int64 as total.
|
||||||
|
func Start64(total int64) *ProgressBar {
|
||||||
|
return New64(total).Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
terminalWidth = termutil.TerminalWidth
|
||||||
|
isTerminal = isatty.IsTerminal
|
||||||
|
isCygwinTerminal = isatty.IsCygwinTerminal
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProgressBar is the main object of bar
|
||||||
|
type ProgressBar struct {
|
||||||
|
current, total int64
|
||||||
|
width int
|
||||||
|
maxWidth int
|
||||||
|
mu sync.RWMutex
|
||||||
|
rm sync.Mutex
|
||||||
|
vars map[interface{}]interface{}
|
||||||
|
elements map[string]Element
|
||||||
|
output io.Writer
|
||||||
|
coutput io.Writer
|
||||||
|
nocoutput io.Writer
|
||||||
|
startTime time.Time
|
||||||
|
refreshRate time.Duration
|
||||||
|
tmpl *template.Template
|
||||||
|
state *State
|
||||||
|
buf *bytes.Buffer
|
||||||
|
ticker *time.Ticker
|
||||||
|
finish chan struct{}
|
||||||
|
finished bool
|
||||||
|
configured bool
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *ProgressBar) configure() {
|
||||||
|
if pb.configured {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pb.configured = true
|
||||||
|
|
||||||
|
if pb.vars == nil {
|
||||||
|
pb.vars = make(map[interface{}]interface{})
|
||||||
|
}
|
||||||
|
if pb.output == nil {
|
||||||
|
pb.output = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
if pb.tmpl == nil {
|
||||||
|
pb.tmpl, pb.err = getTemplate(string(Default))
|
||||||
|
if pb.err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pb.vars[Terminal] == nil {
|
||||||
|
if f, ok := pb.output.(*os.File); ok {
|
||||||
|
if isTerminal(f.Fd()) || isCygwinTerminal(f.Fd()) {
|
||||||
|
pb.vars[Terminal] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pb.vars[ReturnSymbol] == nil {
|
||||||
|
if tm, ok := pb.vars[Terminal].(bool); ok && tm {
|
||||||
|
pb.vars[ReturnSymbol] = "\r"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pb.vars[Color] == nil {
|
||||||
|
if tm, ok := pb.vars[Terminal].(bool); ok && tm {
|
||||||
|
pb.vars[Color] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pb.refreshRate == 0 {
|
||||||
|
pb.refreshRate = defaultRefreshRate
|
||||||
|
}
|
||||||
|
if pb.vars[CleanOnFinish] == nil {
|
||||||
|
pb.vars[CleanOnFinish] = false
|
||||||
|
}
|
||||||
|
if f, ok := pb.output.(*os.File); ok {
|
||||||
|
pb.coutput = colorable.NewColorable(f)
|
||||||
|
} else {
|
||||||
|
pb.coutput = pb.output
|
||||||
|
}
|
||||||
|
pb.nocoutput = colorable.NewNonColorable(pb.output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts the bar
|
||||||
|
func (pb *ProgressBar) Start() *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
defer pb.mu.Unlock()
|
||||||
|
if pb.finish != nil {
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
pb.configure()
|
||||||
|
pb.finished = false
|
||||||
|
pb.state = nil
|
||||||
|
pb.startTime = time.Now()
|
||||||
|
if st, ok := pb.vars[Static].(bool); ok && st {
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
pb.finish = make(chan struct{})
|
||||||
|
pb.ticker = time.NewTicker(pb.refreshRate)
|
||||||
|
go pb.writer(pb.finish)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *ProgressBar) writer(finish chan struct{}) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-pb.ticker.C:
|
||||||
|
pb.write(false)
|
||||||
|
case <-finish:
|
||||||
|
pb.ticker.Stop()
|
||||||
|
pb.write(true)
|
||||||
|
finish <- struct{}{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write performs write to the output
|
||||||
|
func (pb *ProgressBar) Write() *ProgressBar {
|
||||||
|
pb.mu.RLock()
|
||||||
|
finished := pb.finished
|
||||||
|
pb.mu.RUnlock()
|
||||||
|
pb.write(finished)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *ProgressBar) write(finish bool) {
|
||||||
|
result, width := pb.render()
|
||||||
|
if pb.Err() != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if pb.GetBool(Terminal) {
|
||||||
|
if r := (width - CellCount(result)); r > 0 {
|
||||||
|
result += strings.Repeat(" ", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ret, ok := pb.Get(ReturnSymbol).(string); ok {
|
||||||
|
result = ret + result
|
||||||
|
if finish && ret == "\r" {
|
||||||
|
if pb.GetBool(CleanOnFinish) {
|
||||||
|
// "Wipe out" progress bar by overwriting one line with blanks
|
||||||
|
result = "\r" + color.New(color.Reset).Sprintf(strings.Repeat(" ", width)) + "\r"
|
||||||
|
} else {
|
||||||
|
result += "\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pb.GetBool(Color) {
|
||||||
|
pb.coutput.Write([]byte(result))
|
||||||
|
} else {
|
||||||
|
pb.nocoutput.Write([]byte(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total return current total bar value
|
||||||
|
func (pb *ProgressBar) Total() int64 {
|
||||||
|
return atomic.LoadInt64(&pb.total)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTotal sets the total bar value
|
||||||
|
func (pb *ProgressBar) SetTotal(value int64) *ProgressBar {
|
||||||
|
atomic.StoreInt64(&pb.total, value)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotal adds to the total bar value
|
||||||
|
func (pb *ProgressBar) AddTotal(value int64) *ProgressBar {
|
||||||
|
atomic.AddInt64(&pb.total, value)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCurrent sets the current bar value
|
||||||
|
func (pb *ProgressBar) SetCurrent(value int64) *ProgressBar {
|
||||||
|
atomic.StoreInt64(&pb.current, value)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current return current bar value
|
||||||
|
func (pb *ProgressBar) Current() int64 {
|
||||||
|
return atomic.LoadInt64(&pb.current)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adding given int64 value to bar value
|
||||||
|
func (pb *ProgressBar) Add64(value int64) *ProgressBar {
|
||||||
|
atomic.AddInt64(&pb.current, value)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adding given int value to bar value
|
||||||
|
func (pb *ProgressBar) Add(value int) *ProgressBar {
|
||||||
|
return pb.Add64(int64(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment atomically increments the progress
|
||||||
|
func (pb *ProgressBar) Increment() *ProgressBar {
|
||||||
|
return pb.Add64(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets any value by any key
|
||||||
|
func (pb *ProgressBar) Set(key, value interface{}) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
defer pb.mu.Unlock()
|
||||||
|
if pb.vars == nil {
|
||||||
|
pb.vars = make(map[interface{}]interface{})
|
||||||
|
}
|
||||||
|
pb.vars[key] = value
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get return value by key
|
||||||
|
func (pb *ProgressBar) Get(key interface{}) interface{} {
|
||||||
|
pb.mu.RLock()
|
||||||
|
defer pb.mu.RUnlock()
|
||||||
|
if pb.vars == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return pb.vars[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBool return value by key and try to convert there to boolean
|
||||||
|
// If value doesn't set or not boolean - return false
|
||||||
|
func (pb *ProgressBar) GetBool(key interface{}) bool {
|
||||||
|
if v, ok := pb.Get(key).(bool); ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWidth sets the bar width
|
||||||
|
// When given value <= 0 would be using the terminal width (if possible) or default value.
|
||||||
|
func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.width = width
|
||||||
|
pb.mu.Unlock()
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMaxWidth sets the bar maximum width
|
||||||
|
// When given value <= 0 would be using the terminal width (if possible) or default value.
|
||||||
|
func (pb *ProgressBar) SetMaxWidth(maxWidth int) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.maxWidth = maxWidth
|
||||||
|
pb.mu.Unlock()
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width return the bar width
|
||||||
|
// It's current terminal width or settled over 'SetWidth' value.
|
||||||
|
func (pb *ProgressBar) Width() (width int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
width = defaultBarWidth
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
pb.mu.RLock()
|
||||||
|
width = pb.width
|
||||||
|
maxWidth := pb.maxWidth
|
||||||
|
pb.mu.RUnlock()
|
||||||
|
if width <= 0 {
|
||||||
|
var err error
|
||||||
|
if width, err = terminalWidth(); err != nil {
|
||||||
|
return defaultBarWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if maxWidth > 0 && width > maxWidth {
|
||||||
|
width = maxWidth
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *ProgressBar) SetRefreshRate(dur time.Duration) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
if dur > 0 {
|
||||||
|
pb.refreshRate = dur
|
||||||
|
}
|
||||||
|
pb.mu.Unlock()
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriter sets the io.Writer. Bar will write in this writer
|
||||||
|
// By default this is os.Stderr
|
||||||
|
func (pb *ProgressBar) SetWriter(w io.Writer) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.output = w
|
||||||
|
pb.configured = false
|
||||||
|
pb.configure()
|
||||||
|
pb.mu.Unlock()
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartTime return the time when bar started
|
||||||
|
func (pb *ProgressBar) StartTime() time.Time {
|
||||||
|
pb.mu.RLock()
|
||||||
|
defer pb.mu.RUnlock()
|
||||||
|
return pb.startTime
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format convert int64 to string according to the current settings
|
||||||
|
func (pb *ProgressBar) Format(v int64) string {
|
||||||
|
if pb.GetBool(Bytes) {
|
||||||
|
return formatBytes(v, pb.GetBool(SIBytesPrefix))
|
||||||
|
}
|
||||||
|
return strconv.FormatInt(v, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish stops the bar
|
||||||
|
func (pb *ProgressBar) Finish() *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
if pb.finished {
|
||||||
|
pb.mu.Unlock()
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
finishChan := pb.finish
|
||||||
|
pb.finished = true
|
||||||
|
pb.mu.Unlock()
|
||||||
|
if finishChan != nil {
|
||||||
|
finishChan <- struct{}{}
|
||||||
|
<-finishChan
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.finish = nil
|
||||||
|
pb.mu.Unlock()
|
||||||
|
}
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStarted indicates progress bar state
|
||||||
|
func (pb *ProgressBar) IsStarted() bool {
|
||||||
|
pb.mu.RLock()
|
||||||
|
defer pb.mu.RUnlock()
|
||||||
|
return pb.finish != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTemplateString sets ProgressBar tempate string and parse it
|
||||||
|
func (pb *ProgressBar) SetTemplateString(tmpl string) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
defer pb.mu.Unlock()
|
||||||
|
pb.tmpl, pb.err = getTemplate(tmpl)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTemplateString sets ProgressBarTempate and parse it
|
||||||
|
func (pb *ProgressBar) SetTemplate(tmpl ProgressBarTemplate) *ProgressBar {
|
||||||
|
return pb.SetTemplateString(string(tmpl))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProxyReader creates a wrapper for given reader, but with progress handle
|
||||||
|
// Takes io.Reader or io.ReadCloser
|
||||||
|
// Also, it automatically switches progress bar to handle units as bytes
|
||||||
|
func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
|
||||||
|
pb.Set(Bytes, true)
|
||||||
|
return &Reader{r, pb}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProxyWriter creates a wrapper for given writer, but with progress handle
|
||||||
|
// Takes io.Writer or io.WriteCloser
|
||||||
|
// Also, it automatically switches progress bar to handle units as bytes
|
||||||
|
func (pb *ProgressBar) NewProxyWriter(r io.Writer) *Writer {
|
||||||
|
pb.Set(Bytes, true)
|
||||||
|
return &Writer{r, pb}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *ProgressBar) render() (result string, width int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
pb.SetErr(fmt.Errorf("render panic: %v", r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
pb.rm.Lock()
|
||||||
|
defer pb.rm.Unlock()
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.configure()
|
||||||
|
if pb.state == nil {
|
||||||
|
pb.state = &State{ProgressBar: pb}
|
||||||
|
pb.buf = bytes.NewBuffer(nil)
|
||||||
|
}
|
||||||
|
if pb.startTime.IsZero() {
|
||||||
|
pb.startTime = time.Now()
|
||||||
|
}
|
||||||
|
pb.state.id++
|
||||||
|
pb.state.finished = pb.finished
|
||||||
|
pb.state.time = time.Now()
|
||||||
|
pb.mu.Unlock()
|
||||||
|
|
||||||
|
pb.state.width = pb.Width()
|
||||||
|
width = pb.state.width
|
||||||
|
pb.state.total = pb.Total()
|
||||||
|
pb.state.current = pb.Current()
|
||||||
|
pb.buf.Reset()
|
||||||
|
|
||||||
|
if e := pb.tmpl.Execute(pb.buf, pb.state); e != nil {
|
||||||
|
pb.SetErr(e)
|
||||||
|
return "", 0
|
||||||
|
}
|
||||||
|
|
||||||
|
result = pb.buf.String()
|
||||||
|
|
||||||
|
aec := len(pb.state.recalc)
|
||||||
|
if aec == 0 {
|
||||||
|
// no adaptive elements
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
staticWidth := CellCount(result) - (aec * adElPlaceholderLen)
|
||||||
|
|
||||||
|
if pb.state.Width()-staticWidth <= 0 {
|
||||||
|
result = strings.Replace(result, adElPlaceholder, "", -1)
|
||||||
|
result = StripString(result, pb.state.Width())
|
||||||
|
} else {
|
||||||
|
pb.state.adaptiveElWidth = (width - staticWidth) / aec
|
||||||
|
for _, el := range pb.state.recalc {
|
||||||
|
result = strings.Replace(result, adElPlaceholder, el.ProgressElement(pb.state), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pb.state.recalc = pb.state.recalc[:0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetErr sets error to the ProgressBar
|
||||||
|
// Error will be available over Err()
|
||||||
|
func (pb *ProgressBar) SetErr(err error) *ProgressBar {
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.err = err
|
||||||
|
pb.mu.Unlock()
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err return possible error
|
||||||
|
// When all ok - will be nil
|
||||||
|
// May contain template.Execute errors
|
||||||
|
func (pb *ProgressBar) Err() error {
|
||||||
|
pb.mu.RLock()
|
||||||
|
defer pb.mu.RUnlock()
|
||||||
|
return pb.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// String return currrent string representation of ProgressBar
|
||||||
|
func (pb *ProgressBar) String() string {
|
||||||
|
res, _ := pb.render()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProgressElement implements Element interface
|
||||||
|
func (pb *ProgressBar) ProgressElement(s *State, args ...string) string {
|
||||||
|
if s.IsAdaptiveWidth() {
|
||||||
|
pb.SetWidth(s.AdaptiveElWidth())
|
||||||
|
}
|
||||||
|
return pb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// State represents the current state of bar
|
||||||
|
// Need for bar elements
|
||||||
|
type State struct {
|
||||||
|
*ProgressBar
|
||||||
|
|
||||||
|
id uint64
|
||||||
|
total, current int64
|
||||||
|
width, adaptiveElWidth int
|
||||||
|
finished, adaptive bool
|
||||||
|
time time.Time
|
||||||
|
|
||||||
|
recalc []Element
|
||||||
|
}
|
||||||
|
|
||||||
|
// Id it's the current state identifier
|
||||||
|
// - incremental
|
||||||
|
// - starts with 1
|
||||||
|
// - resets after finish/start
|
||||||
|
func (s *State) Id() uint64 {
|
||||||
|
return s.id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total it's bar int64 total
|
||||||
|
func (s *State) Total() int64 {
|
||||||
|
return s.total
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value it's current value
|
||||||
|
func (s *State) Value() int64 {
|
||||||
|
return s.current
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width of bar
|
||||||
|
func (s *State) Width() int {
|
||||||
|
return s.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0)
|
||||||
|
func (s *State) AdaptiveElWidth() int {
|
||||||
|
return s.adaptiveElWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAdaptiveWidth returns true when element must be shown as adaptive
|
||||||
|
func (s *State) IsAdaptiveWidth() bool {
|
||||||
|
return s.adaptive
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFinished return true when bar is finished
|
||||||
|
func (s *State) IsFinished() bool {
|
||||||
|
return s.finished
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFirst return true only in first render
|
||||||
|
func (s *State) IsFirst() bool {
|
||||||
|
return s.id == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time when state was created
|
||||||
|
func (s *State) Time() time.Time {
|
||||||
|
return s.time
|
||||||
|
}
|
15
vendor/github.com/cheggaaa/pb/v3/preset.go
generated
vendored
Normal file
15
vendor/github.com/cheggaaa/pb/v3/preset.go
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Full - preset with all default available elements
|
||||||
|
// Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix'
|
||||||
|
Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}`
|
||||||
|
|
||||||
|
// Default - preset like Full but without elapsed time
|
||||||
|
// Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix'
|
||||||
|
Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}`
|
||||||
|
|
||||||
|
// Simple - preset without speed and any timers. Only counters, bar and percents
|
||||||
|
// Example: 'Prefix 20/100 [-->______] 20% Suffix'
|
||||||
|
Simple ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }}{{string . "suffix"}}`
|
||||||
|
)
|
83
vendor/github.com/cheggaaa/pb/v3/speed.go
generated
vendored
Normal file
83
vendor/github.com/cheggaaa/pb/v3/speed.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/VividCortex/ewma"
|
||||||
|
)
|
||||||
|
|
||||||
|
var speedAddLimit = time.Second / 2
|
||||||
|
|
||||||
|
type speed struct {
|
||||||
|
ewma ewma.MovingAverage
|
||||||
|
lastStateId uint64
|
||||||
|
prevValue, startValue int64
|
||||||
|
prevTime, startTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *speed) value(state *State) float64 {
|
||||||
|
if s.ewma == nil {
|
||||||
|
s.ewma = ewma.NewMovingAverage()
|
||||||
|
}
|
||||||
|
if state.IsFirst() || state.Id() < s.lastStateId {
|
||||||
|
s.reset(state)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if state.Id() == s.lastStateId {
|
||||||
|
return s.ewma.Value()
|
||||||
|
}
|
||||||
|
if state.IsFinished() {
|
||||||
|
return s.absValue(state)
|
||||||
|
}
|
||||||
|
dur := state.Time().Sub(s.prevTime)
|
||||||
|
if dur < speedAddLimit {
|
||||||
|
return s.ewma.Value()
|
||||||
|
}
|
||||||
|
diff := math.Abs(float64(state.Value() - s.prevValue))
|
||||||
|
lastSpeed := diff / dur.Seconds()
|
||||||
|
s.prevTime = state.Time()
|
||||||
|
s.prevValue = state.Value()
|
||||||
|
s.lastStateId = state.Id()
|
||||||
|
s.ewma.Add(lastSpeed)
|
||||||
|
return s.ewma.Value()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *speed) reset(state *State) {
|
||||||
|
s.lastStateId = state.Id()
|
||||||
|
s.startTime = state.Time()
|
||||||
|
s.prevTime = state.Time()
|
||||||
|
s.startValue = state.Value()
|
||||||
|
s.prevValue = state.Value()
|
||||||
|
s.ewma = ewma.NewMovingAverage()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *speed) absValue(state *State) float64 {
|
||||||
|
if dur := state.Time().Sub(s.startTime); dur > 0 {
|
||||||
|
return float64(state.Value()) / dur.Seconds()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSpeedObj(state *State) (s *speed) {
|
||||||
|
if sObj, ok := state.Get(speedObj).(*speed); ok {
|
||||||
|
return sObj
|
||||||
|
}
|
||||||
|
s = new(speed)
|
||||||
|
state.Set(speedObj, s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElementSpeed calculates current speed by EWMA
|
||||||
|
// Optionally can take one or two string arguments.
|
||||||
|
// First string will be used as value for format speed, default is "%s p/s".
|
||||||
|
// Second string will be used when speed not available, default is "? p/s"
|
||||||
|
// In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."}
|
||||||
|
var ElementSpeed ElementFunc = func(state *State, args ...string) string {
|
||||||
|
sp := getSpeedObj(state).value(state)
|
||||||
|
if sp == 0 {
|
||||||
|
return argsHelper(args).getNotEmptyOr(1, "? p/s")
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp))))
|
||||||
|
}
|
89
vendor/github.com/cheggaaa/pb/v3/template.go
generated
vendored
Normal file
89
vendor/github.com/cheggaaa/pb/v3/template.go
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProgressBarTemplate that template string
|
||||||
|
type ProgressBarTemplate string
|
||||||
|
|
||||||
|
// New creates new bar from template
|
||||||
|
func (pbt ProgressBarTemplate) New(total int) *ProgressBar {
|
||||||
|
return New(total).SetTemplate(pbt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start64 create and start new bar with given int64 total value
|
||||||
|
func (pbt ProgressBarTemplate) Start64(total int64) *ProgressBar {
|
||||||
|
return New64(total).SetTemplate(pbt).Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start create and start new bar with given int total value
|
||||||
|
func (pbt ProgressBarTemplate) Start(total int) *ProgressBar {
|
||||||
|
return pbt.Start64(int64(total))
|
||||||
|
}
|
||||||
|
|
||||||
|
var templateCacheMu sync.Mutex
|
||||||
|
var templateCache = make(map[string]*template.Template)
|
||||||
|
|
||||||
|
var defaultTemplateFuncs = template.FuncMap{
|
||||||
|
// colors
|
||||||
|
"black": color.New(color.FgBlack).SprintFunc(),
|
||||||
|
"red": color.New(color.FgRed).SprintFunc(),
|
||||||
|
"green": color.New(color.FgGreen).SprintFunc(),
|
||||||
|
"yellow": color.New(color.FgYellow).SprintFunc(),
|
||||||
|
"blue": color.New(color.FgBlue).SprintFunc(),
|
||||||
|
"magenta": color.New(color.FgMagenta).SprintFunc(),
|
||||||
|
"cyan": color.New(color.FgCyan).SprintFunc(),
|
||||||
|
"white": color.New(color.FgWhite).SprintFunc(),
|
||||||
|
"resetcolor": color.New(color.Reset).SprintFunc(),
|
||||||
|
"rndcolor": rndcolor,
|
||||||
|
"rnd": rnd,
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTemplate(tmpl string) (t *template.Template, err error) {
|
||||||
|
templateCacheMu.Lock()
|
||||||
|
defer templateCacheMu.Unlock()
|
||||||
|
t = templateCache[tmpl]
|
||||||
|
if t != nil {
|
||||||
|
// found in cache
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t = template.New("")
|
||||||
|
fillTemplateFuncs(t)
|
||||||
|
_, err = t.Parse(tmpl)
|
||||||
|
if err != nil {
|
||||||
|
t = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
templateCache[tmpl] = t
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func fillTemplateFuncs(t *template.Template) {
|
||||||
|
t.Funcs(defaultTemplateFuncs)
|
||||||
|
emf := make(template.FuncMap)
|
||||||
|
elementsM.Lock()
|
||||||
|
for k, v := range elements {
|
||||||
|
element := v
|
||||||
|
emf[k] = func(state *State, args ...string) string { return element.ProgressElement(state, args...) }
|
||||||
|
}
|
||||||
|
elementsM.Unlock()
|
||||||
|
t.Funcs(emf)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rndcolor(s string) string {
|
||||||
|
c := rand.Intn(int(color.FgWhite-color.FgBlack)) + int(color.FgBlack)
|
||||||
|
return color.New(color.Attribute(c)).Sprint(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rnd(args ...string) string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return args[rand.Intn(len(args))]
|
||||||
|
}
|
56
vendor/github.com/cheggaaa/pb/v3/termutil/term.go
generated
vendored
Normal file
56
vendor/github.com/cheggaaa/pb/v3/termutil/term.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var echoLocked bool
|
||||||
|
var echoLockMutex sync.Mutex
|
||||||
|
var errLocked = errors.New("terminal locked")
|
||||||
|
|
||||||
|
// RawModeOn switches terminal to raw mode
|
||||||
|
func RawModeOn() (quit chan struct{}, err error) {
|
||||||
|
echoLockMutex.Lock()
|
||||||
|
defer echoLockMutex.Unlock()
|
||||||
|
if echoLocked {
|
||||||
|
err = errLocked
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = lockEcho(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
echoLocked = true
|
||||||
|
quit = make(chan struct{}, 1)
|
||||||
|
go catchTerminate(quit)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// RawModeOff restore previous terminal state
|
||||||
|
func RawModeOff() (err error) {
|
||||||
|
echoLockMutex.Lock()
|
||||||
|
defer echoLockMutex.Unlock()
|
||||||
|
if !echoLocked {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = unlockEcho(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
echoLocked = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// listen exit signals and restore terminal state
|
||||||
|
func catchTerminate(quit chan struct{}) {
|
||||||
|
sig := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sig, unlockSignals...)
|
||||||
|
defer signal.Stop(sig)
|
||||||
|
select {
|
||||||
|
case <-quit:
|
||||||
|
RawModeOff()
|
||||||
|
case <-sig:
|
||||||
|
RawModeOff()
|
||||||
|
}
|
||||||
|
}
|
11
vendor/github.com/cheggaaa/pb/v3/termutil/term_appengine.go
generated
vendored
Normal file
11
vendor/github.com/cheggaaa/pb/v3/termutil/term_appengine.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build appengine
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// terminalWidth returns width of the terminal, which is not supported
|
||||||
|
// and should always failed on appengine classic which is a sandboxed PaaS.
|
||||||
|
func TerminalWidth() (int, error) {
|
||||||
|
return 0, errors.New("Not supported")
|
||||||
|
}
|
9
vendor/github.com/cheggaaa/pb/v3/termutil/term_bsd.go
generated
vendored
Normal file
9
vendor/github.com/cheggaaa/pb/v3/termutil/term_bsd.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build darwin freebsd netbsd openbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
const ioctlReadTermios = syscall.TIOCGETA
|
||||||
|
const ioctlWriteTermios = syscall.TIOCSETA
|
7
vendor/github.com/cheggaaa/pb/v3/termutil/term_linux.go
generated
vendored
Normal file
7
vendor/github.com/cheggaaa/pb/v3/termutil/term_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// +build linux
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
const ioctlReadTermios = 0x5401 // syscall.TCGETS
|
||||||
|
const ioctlWriteTermios = 0x5402 // syscall.TCSETS
|
8
vendor/github.com/cheggaaa/pb/v3/termutil/term_nix.go
generated
vendored
Normal file
8
vendor/github.com/cheggaaa/pb/v3/termutil/term_nix.go
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// +build linux darwin freebsd netbsd openbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
const sysIoctl = syscall.SYS_IOCTL
|
50
vendor/github.com/cheggaaa/pb/v3/termutil/term_plan9.go
generated
vendored
Normal file
50
vendor/github.com/cheggaaa/pb/v3/termutil/term_plan9.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
consctl *os.File
|
||||||
|
|
||||||
|
// Plan 9 doesn't have syscall.SIGQUIT
|
||||||
|
unlockSignals = []os.Signal{
|
||||||
|
os.Interrupt, syscall.SIGTERM, syscall.SIGKILL,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// TerminalWidth returns width of the terminal.
|
||||||
|
func TerminalWidth() (int, error) {
|
||||||
|
return 0, errors.New("Not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
func lockEcho() error {
|
||||||
|
if consctl != nil {
|
||||||
|
return errors.New("consctl already open")
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
consctl, err = os.OpenFile("/dev/consctl", os.O_WRONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = consctl.WriteString("rawon")
|
||||||
|
if err != nil {
|
||||||
|
consctl.Close()
|
||||||
|
consctl = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unlockEcho() error {
|
||||||
|
if consctl == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := consctl.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
consctl = nil
|
||||||
|
return nil
|
||||||
|
}
|
8
vendor/github.com/cheggaaa/pb/v3/termutil/term_solaris.go
generated
vendored
Normal file
8
vendor/github.com/cheggaaa/pb/v3/termutil/term_solaris.go
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// +build solaris
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
const ioctlReadTermios = 0x5401 // syscall.TCGETS
|
||||||
|
const ioctlWriteTermios = 0x5402 // syscall.TCSETS
|
||||||
|
const sysIoctl = 54
|
155
vendor/github.com/cheggaaa/pb/v3/termutil/term_win.go
generated
vendored
Normal file
155
vendor/github.com/cheggaaa/pb/v3/termutil/term_win.go
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tty = os.Stdin
|
||||||
|
|
||||||
|
unlockSignals = []os.Signal{
|
||||||
|
os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
|
// GetConsoleScreenBufferInfo retrieves information about the
|
||||||
|
// specified console screen buffer.
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
|
||||||
|
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||||
|
|
||||||
|
// GetConsoleMode retrieves the current input mode of a console's
|
||||||
|
// input buffer or the current output mode of a console screen buffer.
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
|
||||||
|
getConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||||
|
|
||||||
|
// SetConsoleMode sets the input mode of a console's input buffer
|
||||||
|
// or the output mode of a console screen buffer.
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
||||||
|
setConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||||
|
|
||||||
|
// SetConsoleCursorPosition sets the cursor position in the
|
||||||
|
// specified console screen buffer.
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx
|
||||||
|
setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
||||||
|
|
||||||
|
mingw = isMingw()
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Defines the coordinates of the upper left and lower right corners
|
||||||
|
// of a rectangle.
|
||||||
|
// See
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx
|
||||||
|
smallRect struct {
|
||||||
|
Left, Top, Right, Bottom int16
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defines the coordinates of a character cell in a console screen
|
||||||
|
// buffer. The origin of the coordinate system (0,0) is at the top, left cell
|
||||||
|
// of the buffer.
|
||||||
|
// See
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx
|
||||||
|
coordinates struct {
|
||||||
|
X, Y int16
|
||||||
|
}
|
||||||
|
|
||||||
|
word int16
|
||||||
|
|
||||||
|
// Contains information about a console screen buffer.
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
|
||||||
|
consoleScreenBufferInfo struct {
|
||||||
|
dwSize coordinates
|
||||||
|
dwCursorPosition coordinates
|
||||||
|
wAttributes word
|
||||||
|
srWindow smallRect
|
||||||
|
dwMaximumWindowSize coordinates
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// TerminalWidth returns width of the terminal.
|
||||||
|
func TerminalWidth() (width int, err error) {
|
||||||
|
if mingw {
|
||||||
|
return termWidthTPut()
|
||||||
|
}
|
||||||
|
return termWidthCmd()
|
||||||
|
}
|
||||||
|
|
||||||
|
func termWidthCmd() (width int, err error) {
|
||||||
|
var info consoleScreenBufferInfo
|
||||||
|
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
|
||||||
|
if e != 0 {
|
||||||
|
return 0, error(e)
|
||||||
|
}
|
||||||
|
return int(info.dwSize.X) - 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isMingw() bool {
|
||||||
|
return os.Getenv("MINGW_PREFIX") != "" || os.Getenv("MSYSTEM") == "MINGW64"
|
||||||
|
}
|
||||||
|
|
||||||
|
func termWidthTPut() (width int, err error) {
|
||||||
|
// TODO: maybe anybody knows a better way to get it on mintty...
|
||||||
|
var res []byte
|
||||||
|
cmd := exec.Command("tput", "cols")
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
if res, err = cmd.CombinedOutput(); err != nil {
|
||||||
|
return 0, fmt.Errorf("%s: %v", string(res), err)
|
||||||
|
}
|
||||||
|
if len(res) > 1 {
|
||||||
|
res = res[:len(res)-1]
|
||||||
|
}
|
||||||
|
return strconv.Atoi(string(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCursorPos() (pos coordinates, err error) {
|
||||||
|
var info consoleScreenBufferInfo
|
||||||
|
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
|
||||||
|
if e != 0 {
|
||||||
|
return info.dwCursorPosition, error(e)
|
||||||
|
}
|
||||||
|
return info.dwCursorPosition, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCursorPos(pos coordinates) error {
|
||||||
|
_, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0)
|
||||||
|
if e != 0 {
|
||||||
|
return error(e)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldState word
|
||||||
|
|
||||||
|
func lockEcho() (err error) {
|
||||||
|
if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 {
|
||||||
|
err = fmt.Errorf("Can't get terminal settings: %v", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState
|
||||||
|
const ENABLE_ECHO_INPUT = 0x0004
|
||||||
|
const ENABLE_LINE_INPUT = 0x0002
|
||||||
|
newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))
|
||||||
|
if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 {
|
||||||
|
err = fmt.Errorf("Can't set terminal settings: %v", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func unlockEcho() (err error) {
|
||||||
|
if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 {
|
||||||
|
err = fmt.Errorf("Can't set terminal settings")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
76
vendor/github.com/cheggaaa/pb/v3/termutil/term_x.go
generated
vendored
Normal file
76
vendor/github.com/cheggaaa/pb/v3/termutil/term_x.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package termutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tty *os.File
|
||||||
|
|
||||||
|
unlockSignals = []os.Signal{
|
||||||
|
os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type window struct {
|
||||||
|
Row uint16
|
||||||
|
Col uint16
|
||||||
|
Xpixel uint16
|
||||||
|
Ypixel uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
tty, err = os.Open("/dev/tty")
|
||||||
|
if err != nil {
|
||||||
|
tty = os.Stdin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TerminalWidth returns width of the terminal.
|
||||||
|
func TerminalWidth() (int, error) {
|
||||||
|
w := new(window)
|
||||||
|
res, _, err := syscall.Syscall(sysIoctl,
|
||||||
|
tty.Fd(),
|
||||||
|
uintptr(syscall.TIOCGWINSZ),
|
||||||
|
uintptr(unsafe.Pointer(w)),
|
||||||
|
)
|
||||||
|
if int(res) == -1 {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return int(w.Col), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldState syscall.Termios
|
||||||
|
|
||||||
|
func lockEcho() (err error) {
|
||||||
|
fd := tty.Fd()
|
||||||
|
if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 {
|
||||||
|
err = fmt.Errorf("Can't get terminal settings: %v", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState
|
||||||
|
newState.Lflag &^= syscall.ECHO
|
||||||
|
newState.Lflag |= syscall.ICANON | syscall.ISIG
|
||||||
|
newState.Iflag |= syscall.ICRNL
|
||||||
|
if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 {
|
||||||
|
err = fmt.Errorf("Can't set terminal settings: %v", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func unlockEcho() (err error) {
|
||||||
|
fd := tty.Fd()
|
||||||
|
if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 {
|
||||||
|
err = fmt.Errorf("Can't set terminal settings")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
116
vendor/github.com/cheggaaa/pb/v3/util.go
generated
vendored
Normal file
116
vendor/github.com/cheggaaa/pb/v3/util.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"github.com/mattn/go-runewidth"
|
||||||
|
"math"
|
||||||
|
"regexp"
|
||||||
|
//"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_KiB = 1024
|
||||||
|
_MiB = 1048576
|
||||||
|
_GiB = 1073741824
|
||||||
|
_TiB = 1099511627776
|
||||||
|
|
||||||
|
_kB = 1e3
|
||||||
|
_MB = 1e6
|
||||||
|
_GB = 1e9
|
||||||
|
_TB = 1e12
|
||||||
|
)
|
||||||
|
|
||||||
|
var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9;]+\x6d")
|
||||||
|
|
||||||
|
func CellCount(s string) int {
|
||||||
|
n := runewidth.StringWidth(s)
|
||||||
|
for _, sm := range ctrlFinder.FindAllString(s, -1) {
|
||||||
|
n -= runewidth.StringWidth(sm)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func StripString(s string, w int) string {
|
||||||
|
l := CellCount(s)
|
||||||
|
if l <= w {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
var buf = bytes.NewBuffer(make([]byte, 0, len(s)))
|
||||||
|
StripStringToBuffer(s, w, buf)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StripStringToBuffer(s string, w int, buf *bytes.Buffer) {
|
||||||
|
var seqs = ctrlFinder.FindAllStringIndex(s, -1)
|
||||||
|
var maxWidthReached bool
|
||||||
|
mainloop:
|
||||||
|
for i, r := range s {
|
||||||
|
for _, seq := range seqs {
|
||||||
|
if i >= seq[0] && i < seq[1] {
|
||||||
|
buf.WriteRune(r)
|
||||||
|
continue mainloop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rw := CellCount(string(r)); rw <= w && !maxWidthReached {
|
||||||
|
w -= rw
|
||||||
|
buf.WriteRune(r)
|
||||||
|
} else {
|
||||||
|
maxWidthReached = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for w > 0 {
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
w--
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func round(val float64) (newVal float64) {
|
||||||
|
roundOn := 0.5
|
||||||
|
places := 0
|
||||||
|
var round float64
|
||||||
|
pow := math.Pow(10, float64(places))
|
||||||
|
digit := pow * val
|
||||||
|
_, div := math.Modf(digit)
|
||||||
|
if div >= roundOn {
|
||||||
|
round = math.Ceil(digit)
|
||||||
|
} else {
|
||||||
|
round = math.Floor(digit)
|
||||||
|
}
|
||||||
|
newVal = round / pow
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, or 2 MB, 64.2 kB
|
||||||
|
// if useSIPrefix is set to true
|
||||||
|
func formatBytes(i int64, useSIPrefix bool) (result string) {
|
||||||
|
if !useSIPrefix {
|
||||||
|
switch {
|
||||||
|
case i >= _TiB:
|
||||||
|
result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB)
|
||||||
|
case i >= _GiB:
|
||||||
|
result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB)
|
||||||
|
case i >= _MiB:
|
||||||
|
result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB)
|
||||||
|
case i >= _KiB:
|
||||||
|
result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB)
|
||||||
|
default:
|
||||||
|
result = fmt.Sprintf("%d B", i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch {
|
||||||
|
case i >= _TB:
|
||||||
|
result = fmt.Sprintf("%.02f TB", float64(i)/_TB)
|
||||||
|
case i >= _GB:
|
||||||
|
result = fmt.Sprintf("%.02f GB", float64(i)/_GB)
|
||||||
|
case i >= _MB:
|
||||||
|
result = fmt.Sprintf("%.02f MB", float64(i)/_MB)
|
||||||
|
case i >= _kB:
|
||||||
|
result = fmt.Sprintf("%.02f kB", float64(i)/_kB)
|
||||||
|
default:
|
||||||
|
result = fmt.Sprintf("%d B", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
20
vendor/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
20
vendor/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Fatih Arslan
|
||||||
|
|
||||||
|
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.
|
175
vendor/github.com/fatih/color/README.md
generated
vendored
Normal file
175
vendor/github.com/fatih/color/README.md
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color)
|
||||||
|
|
||||||
|
Color lets you use colorized outputs in terms of [ANSI Escape
|
||||||
|
Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It
|
||||||
|
has support for Windows too! The API can be used in several ways, pick one that
|
||||||
|
suits you.
|
||||||
|
|
||||||
|
![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg)
|
||||||
|
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/fatih/color
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Standard colors
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Print with default helper functions
|
||||||
|
color.Cyan("Prints text in cyan.")
|
||||||
|
|
||||||
|
// A newline will be appended automatically
|
||||||
|
color.Blue("Prints %s in blue.", "text")
|
||||||
|
|
||||||
|
// These are using the default foreground colors
|
||||||
|
color.Red("We have red")
|
||||||
|
color.Magenta("And many others ..")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mix and reuse colors
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create a new color object
|
||||||
|
c := color.New(color.FgCyan).Add(color.Underline)
|
||||||
|
c.Println("Prints cyan text with an underline.")
|
||||||
|
|
||||||
|
// Or just add them to New()
|
||||||
|
d := color.New(color.FgCyan, color.Bold)
|
||||||
|
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||||
|
|
||||||
|
// Mix up foreground and background colors, create new mixes!
|
||||||
|
red := color.New(color.FgRed)
|
||||||
|
|
||||||
|
boldRed := red.Add(color.Bold)
|
||||||
|
boldRed.Println("This will print text in bold red.")
|
||||||
|
|
||||||
|
whiteBackground := red.Add(color.BgWhite)
|
||||||
|
whiteBackground.Println("Red text with white background.")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use your own output (io.Writer)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Use your own io.Writer output
|
||||||
|
color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
|
||||||
|
|
||||||
|
blue := color.New(color.FgBlue)
|
||||||
|
blue.Fprint(writer, "This will print text in blue.")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom print functions (PrintFunc)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create a custom print function for convenience
|
||||||
|
red := color.New(color.FgRed).PrintfFunc()
|
||||||
|
red("Warning")
|
||||||
|
red("Error: %s", err)
|
||||||
|
|
||||||
|
// Mix up multiple attributes
|
||||||
|
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||||
|
notice("Don't forget this...")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom fprint functions (FprintFunc)
|
||||||
|
|
||||||
|
```go
|
||||||
|
blue := color.New(FgBlue).FprintfFunc()
|
||||||
|
blue(myWriter, "important notice: %s", stars)
|
||||||
|
|
||||||
|
// Mix up with multiple attributes
|
||||||
|
success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
|
||||||
|
success(myWriter, "Don't forget this...")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Insert into noncolor strings (SprintFunc)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create SprintXxx functions to mix strings with other non-colorized strings:
|
||||||
|
yellow := color.New(color.FgYellow).SprintFunc()
|
||||||
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||||
|
|
||||||
|
info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
|
||||||
|
fmt.Printf("This %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
// Use helper functions
|
||||||
|
fmt.Println("This", color.RedString("warning"), "should be not neglected.")
|
||||||
|
fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.")
|
||||||
|
|
||||||
|
// Windows supported too! Just don't forget to change the output to color.Output
|
||||||
|
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plug into existing code
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Use handy standard colors
|
||||||
|
color.Set(color.FgYellow)
|
||||||
|
|
||||||
|
fmt.Println("Existing text will now be in yellow")
|
||||||
|
fmt.Printf("This one %s\n", "too")
|
||||||
|
|
||||||
|
color.Unset() // Don't forget to unset
|
||||||
|
|
||||||
|
// You can mix up parameters
|
||||||
|
color.Set(color.FgMagenta, color.Bold)
|
||||||
|
defer color.Unset() // Use it in your function
|
||||||
|
|
||||||
|
fmt.Println("All text will now be bold magenta.")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable/Enable color
|
||||||
|
|
||||||
|
There might be a case where you want to explicitly disable/enable color output. the
|
||||||
|
`go-isatty` package will automatically disable color output for non-tty output streams
|
||||||
|
(for example if the output were piped directly to `less`)
|
||||||
|
|
||||||
|
`Color` has support to disable/enable colors both globally and for single color
|
||||||
|
definitions. For example suppose you have a CLI app and a `--no-color` bool flag. You
|
||||||
|
can easily disable the color output with:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||||
|
|
||||||
|
if *flagNoColor {
|
||||||
|
color.NoColor = true // disables colorized output
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It also has support for single color definitions (local). You can
|
||||||
|
disable/enable color output on the fly:
|
||||||
|
|
||||||
|
```go
|
||||||
|
c := color.New(color.FgCyan)
|
||||||
|
c.Println("Prints cyan text")
|
||||||
|
|
||||||
|
c.DisableColor()
|
||||||
|
c.Println("This is printed without any color")
|
||||||
|
|
||||||
|
c.EnableColor()
|
||||||
|
c.Println("This prints again cyan...")
|
||||||
|
```
|
||||||
|
|
||||||
|
## GitHub Actions
|
||||||
|
|
||||||
|
To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams.
|
||||||
|
|
||||||
|
## Todo
|
||||||
|
|
||||||
|
* Save/Return previous values
|
||||||
|
* Evaluate fmt.Formatter interface
|
||||||
|
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* [Fatih Arslan](https://github.com/fatih)
|
||||||
|
* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details
|
603
vendor/github.com/fatih/color/color.go
generated
vendored
Normal file
603
vendor/github.com/fatih/color/color.go
generated
vendored
Normal file
|
@ -0,0 +1,603 @@
|
||||||
|
package color
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/mattn/go-colorable"
|
||||||
|
"github.com/mattn/go-isatty"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||||
|
// false or true based on the stdout's file descriptor referring to a terminal
|
||||||
|
// or not. This is a global option and affects all colors. For more control
|
||||||
|
// over each color block use the methods DisableColor() individually.
|
||||||
|
NoColor = os.Getenv("TERM") == "dumb" ||
|
||||||
|
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
|
||||||
|
|
||||||
|
// Output defines the standard output of the print functions. By default
|
||||||
|
// os.Stdout is used.
|
||||||
|
Output = colorable.NewColorableStdout()
|
||||||
|
|
||||||
|
// Error defines a color supporting writer for os.Stderr.
|
||||||
|
Error = colorable.NewColorableStderr()
|
||||||
|
|
||||||
|
// colorsCache is used to reduce the count of created Color objects and
|
||||||
|
// allows to reuse already created objects with required Attribute.
|
||||||
|
colorsCache = make(map[Attribute]*Color)
|
||||||
|
colorsCacheMu sync.Mutex // protects colorsCache
|
||||||
|
)
|
||||||
|
|
||||||
|
// Color defines a custom color object which is defined by SGR parameters.
|
||||||
|
type Color struct {
|
||||||
|
params []Attribute
|
||||||
|
noColor *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attribute defines a single SGR Code
|
||||||
|
type Attribute int
|
||||||
|
|
||||||
|
const escape = "\x1b"
|
||||||
|
|
||||||
|
// Base attributes
|
||||||
|
const (
|
||||||
|
Reset Attribute = iota
|
||||||
|
Bold
|
||||||
|
Faint
|
||||||
|
Italic
|
||||||
|
Underline
|
||||||
|
BlinkSlow
|
||||||
|
BlinkRapid
|
||||||
|
ReverseVideo
|
||||||
|
Concealed
|
||||||
|
CrossedOut
|
||||||
|
)
|
||||||
|
|
||||||
|
// Foreground text colors
|
||||||
|
const (
|
||||||
|
FgBlack Attribute = iota + 30
|
||||||
|
FgRed
|
||||||
|
FgGreen
|
||||||
|
FgYellow
|
||||||
|
FgBlue
|
||||||
|
FgMagenta
|
||||||
|
FgCyan
|
||||||
|
FgWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Foreground Hi-Intensity text colors
|
||||||
|
const (
|
||||||
|
FgHiBlack Attribute = iota + 90
|
||||||
|
FgHiRed
|
||||||
|
FgHiGreen
|
||||||
|
FgHiYellow
|
||||||
|
FgHiBlue
|
||||||
|
FgHiMagenta
|
||||||
|
FgHiCyan
|
||||||
|
FgHiWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Background text colors
|
||||||
|
const (
|
||||||
|
BgBlack Attribute = iota + 40
|
||||||
|
BgRed
|
||||||
|
BgGreen
|
||||||
|
BgYellow
|
||||||
|
BgBlue
|
||||||
|
BgMagenta
|
||||||
|
BgCyan
|
||||||
|
BgWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Background Hi-Intensity text colors
|
||||||
|
const (
|
||||||
|
BgHiBlack Attribute = iota + 100
|
||||||
|
BgHiRed
|
||||||
|
BgHiGreen
|
||||||
|
BgHiYellow
|
||||||
|
BgHiBlue
|
||||||
|
BgHiMagenta
|
||||||
|
BgHiCyan
|
||||||
|
BgHiWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a newly created color object.
|
||||||
|
func New(value ...Attribute) *Color {
|
||||||
|
c := &Color{params: make([]Attribute, 0)}
|
||||||
|
c.Add(value...)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the given parameters immediately. It will change the color of
|
||||||
|
// output with the given SGR parameters until color.Unset() is called.
|
||||||
|
func Set(p ...Attribute) *Color {
|
||||||
|
c := New(p...)
|
||||||
|
c.Set()
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset resets all escape attributes and clears the output. Usually should
|
||||||
|
// be called after Set().
|
||||||
|
func Unset() {
|
||||||
|
if NoColor {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(Output, "%s[%dm", escape, Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the SGR sequence.
|
||||||
|
func (c *Color) Set() *Color {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(Output, c.format())
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) unset() {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) setWriter(w io.Writer) *Color {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w, c.format())
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) unsetWriter(w io.Writer) {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if NoColor {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "%s[%dm", escape, Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add is used to chain SGR parameters. Use as many as parameters to combine
|
||||||
|
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
|
||||||
|
func (c *Color) Add(value ...Attribute) *Color {
|
||||||
|
c.params = append(c.params, value...)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) prepend(value Attribute) {
|
||||||
|
c.params = append(c.params, 0)
|
||||||
|
copy(c.params[1:], c.params[0:])
|
||||||
|
c.params[0] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprint formats using the default formats for its operands and writes to w.
|
||||||
|
// Spaces are added between operands when neither is a string.
|
||||||
|
// It returns the number of bytes written and any write error encountered.
|
||||||
|
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||||
|
// type *os.File.
|
||||||
|
func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||||
|
c.setWriter(w)
|
||||||
|
defer c.unsetWriter(w)
|
||||||
|
|
||||||
|
return fmt.Fprint(w, 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. This is the standard fmt.Print() method wrapped with the given
|
||||||
|
// color.
|
||||||
|
func (c *Color) Print(a ...interface{}) (n int, err error) {
|
||||||
|
c.Set()
|
||||||
|
defer c.unset()
|
||||||
|
|
||||||
|
return fmt.Fprint(Output, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintf formats according to a format specifier and writes to w.
|
||||||
|
// It returns the number of bytes written and any write error encountered.
|
||||||
|
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||||
|
// type *os.File.
|
||||||
|
func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||||
|
c.setWriter(w)
|
||||||
|
defer c.unsetWriter(w)
|
||||||
|
|
||||||
|
return fmt.Fprintf(w, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf formats according to a format specifier and writes to standard output.
|
||||||
|
// It returns the number of bytes written and any write error encountered.
|
||||||
|
// This is the standard fmt.Printf() method wrapped with the given color.
|
||||||
|
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
|
||||||
|
c.Set()
|
||||||
|
defer c.unset()
|
||||||
|
|
||||||
|
return fmt.Fprintf(Output, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintln formats using the default formats for its operands and writes to w.
|
||||||
|
// Spaces are always added between operands and a newline is appended.
|
||||||
|
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||||
|
// type *os.File.
|
||||||
|
func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||||
|
c.setWriter(w)
|
||||||
|
defer c.unsetWriter(w)
|
||||||
|
|
||||||
|
return fmt.Fprintln(w, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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. This is the standard fmt.Print() method wrapped with the given
|
||||||
|
// color.
|
||||||
|
func (c *Color) Println(a ...interface{}) (n int, err error) {
|
||||||
|
c.Set()
|
||||||
|
defer c.unset()
|
||||||
|
|
||||||
|
return fmt.Fprintln(Output, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprint is just like Print, but returns a string instead of printing it.
|
||||||
|
func (c *Color) Sprint(a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprint(a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprintln is just like Println, but returns a string instead of printing it.
|
||||||
|
func (c *Color) Sprintln(a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprintln(a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprintf is just like Printf, but returns a string instead of printing it.
|
||||||
|
func (c *Color) Sprintf(format string, a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FprintFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Fprint().
|
||||||
|
func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {
|
||||||
|
return func(w io.Writer, a ...interface{}) {
|
||||||
|
c.Fprint(w, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Print().
|
||||||
|
func (c *Color) PrintFunc() func(a ...interface{}) {
|
||||||
|
return func(a ...interface{}) {
|
||||||
|
c.Print(a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FprintfFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Fprintf().
|
||||||
|
func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) {
|
||||||
|
return func(w io.Writer, format string, a ...interface{}) {
|
||||||
|
c.Fprintf(w, format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintfFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Printf().
|
||||||
|
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
|
||||||
|
return func(format string, a ...interface{}) {
|
||||||
|
c.Printf(format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FprintlnFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Fprintln().
|
||||||
|
func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {
|
||||||
|
return func(w io.Writer, a ...interface{}) {
|
||||||
|
c.Fprintln(w, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintlnFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Println().
|
||||||
|
func (c *Color) PrintlnFunc() func(a ...interface{}) {
|
||||||
|
return func(a ...interface{}) {
|
||||||
|
c.Println(a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SprintFunc returns a new function that returns colorized strings for the
|
||||||
|
// given arguments with fmt.Sprint(). Useful to put into or mix into other
|
||||||
|
// string. Windows users should use this in conjunction with color.Output, example:
|
||||||
|
//
|
||||||
|
// put := New(FgYellow).SprintFunc()
|
||||||
|
// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
|
||||||
|
func (c *Color) SprintFunc() func(a ...interface{}) string {
|
||||||
|
return func(a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprint(a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SprintfFunc returns a new function that returns colorized strings for the
|
||||||
|
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
|
||||||
|
// string. Windows users should use this in conjunction with color.Output.
|
||||||
|
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
|
||||||
|
return func(format string, a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SprintlnFunc returns a new function that returns colorized strings for the
|
||||||
|
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
|
||||||
|
// string. Windows users should use this in conjunction with color.Output.
|
||||||
|
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
|
||||||
|
return func(a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprintln(a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m"
|
||||||
|
// an example output might be: "1;36" -> bold cyan
|
||||||
|
func (c *Color) sequence() string {
|
||||||
|
format := make([]string, len(c.params))
|
||||||
|
for i, v := range c.params {
|
||||||
|
format[i] = strconv.Itoa(int(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(format, ";")
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap wraps the s string with the colors attributes. The string is ready to
|
||||||
|
// be printed.
|
||||||
|
func (c *Color) wrap(s string) string {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.format() + s + c.unformat()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) format() string {
|
||||||
|
return fmt.Sprintf("%s[%sm", escape, c.sequence())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) unformat() string {
|
||||||
|
return fmt.Sprintf("%s[%dm", escape, Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableColor disables the color output. Useful to not change any existing
|
||||||
|
// code and still being able to output. Can be used for flags like
|
||||||
|
// "--no-color". To enable back use EnableColor() method.
|
||||||
|
func (c *Color) DisableColor() {
|
||||||
|
c.noColor = boolPtr(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableColor enables the color output. Use it in conjunction with
|
||||||
|
// DisableColor(). Otherwise this method has no side effects.
|
||||||
|
func (c *Color) EnableColor() {
|
||||||
|
c.noColor = boolPtr(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) isNoColorSet() bool {
|
||||||
|
// check first if we have user set action
|
||||||
|
if c.noColor != nil {
|
||||||
|
return *c.noColor
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not return the global option, which is disabled by default
|
||||||
|
return NoColor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals returns a boolean value indicating whether two colors are equal.
|
||||||
|
func (c *Color) Equals(c2 *Color) bool {
|
||||||
|
if len(c.params) != len(c2.params) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, attr := range c.params {
|
||||||
|
if !c2.attrExists(attr) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) attrExists(a Attribute) bool {
|
||||||
|
for _, attr := range c.params {
|
||||||
|
if attr == a {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolPtr(v bool) *bool {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCachedColor(p Attribute) *Color {
|
||||||
|
colorsCacheMu.Lock()
|
||||||
|
defer colorsCacheMu.Unlock()
|
||||||
|
|
||||||
|
c, ok := colorsCache[p]
|
||||||
|
if !ok {
|
||||||
|
c = New(p)
|
||||||
|
colorsCache[p] = c
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func colorPrint(format string, p Attribute, a ...interface{}) {
|
||||||
|
c := getCachedColor(p)
|
||||||
|
|
||||||
|
if !strings.HasSuffix(format, "\n") {
|
||||||
|
format += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(a) == 0 {
|
||||||
|
c.Print(format)
|
||||||
|
} else {
|
||||||
|
c.Printf(format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func colorString(format string, p Attribute, a ...interface{}) string {
|
||||||
|
c := getCachedColor(p)
|
||||||
|
|
||||||
|
if len(a) == 0 {
|
||||||
|
return c.SprintFunc()(format)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Black is a convenient helper function to print with black foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) }
|
||||||
|
|
||||||
|
// Red is a convenient helper function to print with red foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) }
|
||||||
|
|
||||||
|
// Green is a convenient helper function to print with green foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) }
|
||||||
|
|
||||||
|
// Yellow is a convenient helper function to print with yellow foreground.
|
||||||
|
// A newline is appended to format by default.
|
||||||
|
func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) }
|
||||||
|
|
||||||
|
// Blue is a convenient helper function to print with blue foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) }
|
||||||
|
|
||||||
|
// Magenta is a convenient helper function to print with magenta foreground.
|
||||||
|
// A newline is appended to format by default.
|
||||||
|
func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) }
|
||||||
|
|
||||||
|
// Cyan is a convenient helper function to print with cyan foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) }
|
||||||
|
|
||||||
|
// White is a convenient helper function to print with white foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) }
|
||||||
|
|
||||||
|
// BlackString is a convenient helper function to return a string with black
|
||||||
|
// foreground.
|
||||||
|
func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) }
|
||||||
|
|
||||||
|
// RedString is a convenient helper function to return a string with red
|
||||||
|
// foreground.
|
||||||
|
func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) }
|
||||||
|
|
||||||
|
// GreenString is a convenient helper function to return a string with green
|
||||||
|
// foreground.
|
||||||
|
func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) }
|
||||||
|
|
||||||
|
// YellowString is a convenient helper function to return a string with yellow
|
||||||
|
// foreground.
|
||||||
|
func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) }
|
||||||
|
|
||||||
|
// BlueString is a convenient helper function to return a string with blue
|
||||||
|
// foreground.
|
||||||
|
func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) }
|
||||||
|
|
||||||
|
// MagentaString is a convenient helper function to return a string with magenta
|
||||||
|
// foreground.
|
||||||
|
func MagentaString(format string, a ...interface{}) string {
|
||||||
|
return colorString(format, FgMagenta, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CyanString is a convenient helper function to return a string with cyan
|
||||||
|
// foreground.
|
||||||
|
func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) }
|
||||||
|
|
||||||
|
// WhiteString is a convenient helper function to return a string with white
|
||||||
|
// foreground.
|
||||||
|
func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) }
|
||||||
|
|
||||||
|
// HiBlack is a convenient helper function to print with hi-intensity black foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) }
|
||||||
|
|
||||||
|
// HiRed is a convenient helper function to print with hi-intensity red foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) }
|
||||||
|
|
||||||
|
// HiGreen is a convenient helper function to print with hi-intensity green foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) }
|
||||||
|
|
||||||
|
// HiYellow is a convenient helper function to print with hi-intensity yellow foreground.
|
||||||
|
// A newline is appended to format by default.
|
||||||
|
func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) }
|
||||||
|
|
||||||
|
// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) }
|
||||||
|
|
||||||
|
// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground.
|
||||||
|
// A newline is appended to format by default.
|
||||||
|
func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) }
|
||||||
|
|
||||||
|
// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) }
|
||||||
|
|
||||||
|
// HiWhite is a convenient helper function to print with hi-intensity white foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) }
|
||||||
|
|
||||||
|
// HiBlackString is a convenient helper function to return a string with hi-intensity black
|
||||||
|
// foreground.
|
||||||
|
func HiBlackString(format string, a ...interface{}) string {
|
||||||
|
return colorString(format, FgHiBlack, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HiRedString is a convenient helper function to return a string with hi-intensity red
|
||||||
|
// foreground.
|
||||||
|
func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) }
|
||||||
|
|
||||||
|
// HiGreenString is a convenient helper function to return a string with hi-intensity green
|
||||||
|
// foreground.
|
||||||
|
func HiGreenString(format string, a ...interface{}) string {
|
||||||
|
return colorString(format, FgHiGreen, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HiYellowString is a convenient helper function to return a string with hi-intensity yellow
|
||||||
|
// foreground.
|
||||||
|
func HiYellowString(format string, a ...interface{}) string {
|
||||||
|
return colorString(format, FgHiYellow, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HiBlueString is a convenient helper function to return a string with hi-intensity blue
|
||||||
|
// foreground.
|
||||||
|
func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) }
|
||||||
|
|
||||||
|
// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta
|
||||||
|
// foreground.
|
||||||
|
func HiMagentaString(format string, a ...interface{}) string {
|
||||||
|
return colorString(format, FgHiMagenta, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HiCyanString is a convenient helper function to return a string with hi-intensity cyan
|
||||||
|
// foreground.
|
||||||
|
func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) }
|
||||||
|
|
||||||
|
// HiWhiteString is a convenient helper function to return a string with hi-intensity white
|
||||||
|
// foreground.
|
||||||
|
func HiWhiteString(format string, a ...interface{}) string {
|
||||||
|
return colorString(format, FgHiWhite, a...)
|
||||||
|
}
|
133
vendor/github.com/fatih/color/doc.go
generated
vendored
Normal file
133
vendor/github.com/fatih/color/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
Package color is an ANSI color package to output colorized or SGR defined
|
||||||
|
output to the standard output. The API can be used in several way, pick one
|
||||||
|
that suits you.
|
||||||
|
|
||||||
|
Use simple and default helper functions with predefined foreground colors:
|
||||||
|
|
||||||
|
color.Cyan("Prints text in cyan.")
|
||||||
|
|
||||||
|
// a newline will be appended automatically
|
||||||
|
color.Blue("Prints %s in blue.", "text")
|
||||||
|
|
||||||
|
// More default foreground colors..
|
||||||
|
color.Red("We have red")
|
||||||
|
color.Yellow("Yellow color too!")
|
||||||
|
color.Magenta("And many others ..")
|
||||||
|
|
||||||
|
// Hi-intensity colors
|
||||||
|
color.HiGreen("Bright green color.")
|
||||||
|
color.HiBlack("Bright black means gray..")
|
||||||
|
color.HiWhite("Shiny white color!")
|
||||||
|
|
||||||
|
However there are times where custom color mixes are required. Below are some
|
||||||
|
examples to create custom color objects and use the print functions of each
|
||||||
|
separate color object.
|
||||||
|
|
||||||
|
// Create a new color object
|
||||||
|
c := color.New(color.FgCyan).Add(color.Underline)
|
||||||
|
c.Println("Prints cyan text with an underline.")
|
||||||
|
|
||||||
|
// Or just add them to New()
|
||||||
|
d := color.New(color.FgCyan, color.Bold)
|
||||||
|
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||||
|
|
||||||
|
|
||||||
|
// Mix up foreground and background colors, create new mixes!
|
||||||
|
red := color.New(color.FgRed)
|
||||||
|
|
||||||
|
boldRed := red.Add(color.Bold)
|
||||||
|
boldRed.Println("This will print text in bold red.")
|
||||||
|
|
||||||
|
whiteBackground := red.Add(color.BgWhite)
|
||||||
|
whiteBackground.Println("Red text with White background.")
|
||||||
|
|
||||||
|
// Use your own io.Writer output
|
||||||
|
color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
|
||||||
|
|
||||||
|
blue := color.New(color.FgBlue)
|
||||||
|
blue.Fprint(myWriter, "This will print text in blue.")
|
||||||
|
|
||||||
|
You can create PrintXxx functions to simplify even more:
|
||||||
|
|
||||||
|
// Create a custom print function for convenient
|
||||||
|
red := color.New(color.FgRed).PrintfFunc()
|
||||||
|
red("warning")
|
||||||
|
red("error: %s", err)
|
||||||
|
|
||||||
|
// Mix up multiple attributes
|
||||||
|
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||||
|
notice("don't forget this...")
|
||||||
|
|
||||||
|
You can also FprintXxx functions to pass your own io.Writer:
|
||||||
|
|
||||||
|
blue := color.New(FgBlue).FprintfFunc()
|
||||||
|
blue(myWriter, "important notice: %s", stars)
|
||||||
|
|
||||||
|
// Mix up with multiple attributes
|
||||||
|
success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
|
||||||
|
success(myWriter, don't forget this...")
|
||||||
|
|
||||||
|
|
||||||
|
Or create SprintXxx functions to mix strings with other non-colorized strings:
|
||||||
|
|
||||||
|
yellow := New(FgYellow).SprintFunc()
|
||||||
|
red := New(FgRed).SprintFunc()
|
||||||
|
|
||||||
|
fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||||
|
|
||||||
|
info := New(FgWhite, BgGreen).SprintFunc()
|
||||||
|
fmt.Printf("this %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
Windows support is enabled by default. All Print functions work as intended.
|
||||||
|
However only for color.SprintXXX functions, user should use fmt.FprintXXX and
|
||||||
|
set the output to color.Output:
|
||||||
|
|
||||||
|
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||||
|
|
||||||
|
info := New(FgWhite, BgGreen).SprintFunc()
|
||||||
|
fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
Using with existing code is possible. Just use the Set() method to set the
|
||||||
|
standard output to the given parameters. That way a rewrite of an existing
|
||||||
|
code is not required.
|
||||||
|
|
||||||
|
// Use handy standard colors.
|
||||||
|
color.Set(color.FgYellow)
|
||||||
|
|
||||||
|
fmt.Println("Existing text will be now in Yellow")
|
||||||
|
fmt.Printf("This one %s\n", "too")
|
||||||
|
|
||||||
|
color.Unset() // don't forget to unset
|
||||||
|
|
||||||
|
// You can mix up parameters
|
||||||
|
color.Set(color.FgMagenta, color.Bold)
|
||||||
|
defer color.Unset() // use it in your function
|
||||||
|
|
||||||
|
fmt.Println("All text will be now bold magenta.")
|
||||||
|
|
||||||
|
There might be a case where you want to disable color output (for example to
|
||||||
|
pipe the standard output of your app to somewhere else). `Color` has support to
|
||||||
|
disable colors both globally and for single color definition. For example
|
||||||
|
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
|
||||||
|
the color output with:
|
||||||
|
|
||||||
|
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||||
|
|
||||||
|
if *flagNoColor {
|
||||||
|
color.NoColor = true // disables colorized output
|
||||||
|
}
|
||||||
|
|
||||||
|
It also has support for single color definitions (local). You can
|
||||||
|
disable/enable color output on the fly:
|
||||||
|
|
||||||
|
c := color.New(color.FgCyan)
|
||||||
|
c.Println("Prints cyan text")
|
||||||
|
|
||||||
|
c.DisableColor()
|
||||||
|
c.Println("This is printed without any color")
|
||||||
|
|
||||||
|
c.EnableColor()
|
||||||
|
c.Println("This prints again cyan...")
|
||||||
|
*/
|
||||||
|
package color
|
8
vendor/github.com/fatih/color/go.mod
generated
vendored
Normal file
8
vendor/github.com/fatih/color/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module github.com/fatih/color
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-colorable v0.1.8
|
||||||
|
github.com/mattn/go-isatty v0.0.12
|
||||||
|
)
|
7
vendor/github.com/fatih/color/go.sum
generated
vendored
Normal file
7
vendor/github.com/fatih/color/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
9
vendor/github.com/fsnotify/fsnotify/.editorconfig
generated
vendored
9
vendor/github.com/fsnotify/fsnotify/.editorconfig
generated
vendored
|
@ -1,5 +1,12 @@
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*.go]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
1
vendor/github.com/fsnotify/fsnotify/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/fsnotify/fsnotify/.gitattributes
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
go.sum linguist-generated
|
20
vendor/github.com/fsnotify/fsnotify/.travis.yml
generated
vendored
20
vendor/github.com/fsnotify/fsnotify/.travis.yml
generated
vendored
|
@ -2,29 +2,35 @@ sudo: false
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.8.x
|
- "stable"
|
||||||
- 1.9.x
|
- "1.11.x"
|
||||||
- tip
|
- "1.10.x"
|
||||||
|
- "1.9.x"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
include:
|
||||||
|
- go: "stable"
|
||||||
|
env: GOLINT=true
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- go: tip
|
- go: tip
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
before_script:
|
|
||||||
- go get -u github.com/golang/lint/golint
|
before_install:
|
||||||
|
- if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go test -v --race ./...
|
- go test --race ./...
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
|
- test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
|
||||||
- test -z "$(golint ./... | tee /dev/stderr)"
|
- if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi
|
||||||
- go vet ./...
|
- go vet ./...
|
||||||
|
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
- windows
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
2
vendor/github.com/fsnotify/fsnotify/LICENSE
generated
vendored
2
vendor/github.com/fsnotify/fsnotify/LICENSE
generated
vendored
|
@ -1,5 +1,5 @@
|
||||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
Copyright (c) 2012 fsnotify Authors. All rights reserved.
|
Copyright (c) 2012-2019 fsnotify Authors. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
|
|
71
vendor/github.com/fsnotify/fsnotify/README.md
generated
vendored
71
vendor/github.com/fsnotify/fsnotify/README.md
generated
vendored
|
@ -10,16 +10,16 @@ go get -u golang.org/x/sys/...
|
||||||
|
|
||||||
Cross platform: Windows, Linux, BSD and macOS.
|
Cross platform: Windows, Linux, BSD and macOS.
|
||||||
|
|
||||||
|Adapter |OS |Status |
|
| Adapter | OS | Status |
|
||||||
|----------|----------|----------|
|
| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|inotify |Linux 2.6.27 or later, Android\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)|
|
| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
|
||||||
|kqueue |BSD, macOS, iOS\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)|
|
| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
|
||||||
|ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)|
|
| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
|
||||||
|FSEvents |macOS |[Planned](https://github.com/fsnotify/fsnotify/issues/11)|
|
| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
|
||||||
|FEN |Solaris 11 |[In Progress](https://github.com/fsnotify/fsnotify/issues/12)|
|
| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) |
|
||||||
|fanotify |Linux 2.6.37+ | |
|
| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) |
|
||||||
|USN Journals |Windows |[Maybe](https://github.com/fsnotify/fsnotify/issues/53)|
|
| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) |
|
||||||
|Polling |*All* |[Maybe](https://github.com/fsnotify/fsnotify/issues/9)|
|
| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) |
|
||||||
|
|
||||||
\* Android and iOS are untested.
|
\* Android and iOS are untested.
|
||||||
|
|
||||||
|
@ -33,6 +33,53 @@ All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based o
|
||||||
|
|
||||||
Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
|
Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer watcher.Close()
|
||||||
|
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event, ok := <-watcher.Events:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("event:", event)
|
||||||
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||||
|
log.Println("modified file:", event.Name)
|
||||||
|
}
|
||||||
|
case err, ok := <-watcher.Errors:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = watcher.Add("/tmp/foo")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Please refer to [CONTRIBUTING][] before opening an issue or pull request.
|
Please refer to [CONTRIBUTING][] before opening an issue or pull request.
|
||||||
|
@ -65,6 +112,10 @@ There are OS-specific limits as to how many watches can be created:
|
||||||
* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error.
|
* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error.
|
||||||
* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error.
|
* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error.
|
||||||
|
|
||||||
|
**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?**
|
||||||
|
|
||||||
|
fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications.
|
||||||
|
|
||||||
[#62]: https://github.com/howeyc/fsnotify/issues/62
|
[#62]: https://github.com/howeyc/fsnotify/issues/62
|
||||||
[#18]: https://github.com/fsnotify/fsnotify/issues/18
|
[#18]: https://github.com/fsnotify/fsnotify/issues/18
|
||||||
[#11]: https://github.com/fsnotify/fsnotify/issues/11
|
[#11]: https://github.com/fsnotify/fsnotify/issues/11
|
||||||
|
|
4
vendor/github.com/fsnotify/fsnotify/fsnotify.go
generated
vendored
4
vendor/github.com/fsnotify/fsnotify/fsnotify.go
generated
vendored
|
@ -63,4 +63,6 @@ func (e Event) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common errors that can be reported by a watcher
|
// Common errors that can be reported by a watcher
|
||||||
var ErrEventOverflow = errors.New("fsnotify queue overflow")
|
var (
|
||||||
|
ErrEventOverflow = errors.New("fsnotify queue overflow")
|
||||||
|
)
|
||||||
|
|
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
Normal file
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module github.com/fsnotify/fsnotify
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9
|
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
Normal file
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
|
||||||
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
4
vendor/github.com/fsnotify/fsnotify/inotify_poller.go
generated
vendored
4
vendor/github.com/fsnotify/fsnotify/inotify_poller.go
generated
vendored
|
@ -40,12 +40,12 @@ func newFdPoller(fd int) (*fdPoller, error) {
|
||||||
poller.fd = fd
|
poller.fd = fd
|
||||||
|
|
||||||
// Create epoll fd
|
// Create epoll fd
|
||||||
poller.epfd, errno = unix.EpollCreate1(0)
|
poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC)
|
||||||
if poller.epfd == -1 {
|
if poller.epfd == -1 {
|
||||||
return nil, errno
|
return nil, errno
|
||||||
}
|
}
|
||||||
// Create pipe; pipe[0] is the read end, pipe[1] the write end.
|
// Create pipe; pipe[0] is the read end, pipe[1] the write end.
|
||||||
errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK)
|
errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC)
|
||||||
if errno != nil {
|
if errno != nil {
|
||||||
return nil, errno
|
return nil, errno
|
||||||
}
|
}
|
||||||
|
|
2
vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
generated
vendored
2
vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
generated
vendored
|
@ -8,4 +8,4 @@ package fsnotify
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const openMode = unix.O_NONBLOCK | unix.O_RDONLY
|
const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC
|
||||||
|
|
2
vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
generated
vendored
2
vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
generated
vendored
|
@ -9,4 +9,4 @@ package fsnotify
|
||||||
import "golang.org/x/sys/unix"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
// note: this constant is not defined on BSD
|
// note: this constant is not defined on BSD
|
||||||
const openMode = unix.O_EVTONLY
|
const openMode = unix.O_EVTONLY | unix.O_CLOEXEC
|
||||||
|
|
5
vendor/github.com/magiconair/properties/.travis.yml
generated
vendored
5
vendor/github.com/magiconair/properties/.travis.yml
generated
vendored
|
@ -1,5 +1,6 @@
|
||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
|
- 1.3.x
|
||||||
- 1.4.x
|
- 1.4.x
|
||||||
- 1.5.x
|
- 1.5.x
|
||||||
- 1.6.x
|
- 1.6.x
|
||||||
|
@ -9,4 +10,8 @@ go:
|
||||||
- "1.10.x"
|
- "1.10.x"
|
||||||
- "1.11.x"
|
- "1.11.x"
|
||||||
- "1.12.x"
|
- "1.12.x"
|
||||||
|
- "1.13.x"
|
||||||
|
- "1.14.x"
|
||||||
|
- "1.15.x"
|
||||||
|
- "1.16.x"
|
||||||
- tip
|
- tip
|
||||||
|
|
23
vendor/github.com/magiconair/properties/CHANGELOG.md
generated
vendored
23
vendor/github.com/magiconair/properties/CHANGELOG.md
generated
vendored
|
@ -1,8 +1,29 @@
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### [1.8.2](https://github.com/magiconair/properties/tree/v1.8.2) - 25 Aug 2020
|
||||||
|
|
||||||
|
* [PR #36](https://github.com/magiconair/properties/pull/36): Escape backslash on write
|
||||||
|
|
||||||
|
This patch ensures that backslashes are escaped on write. Existing applications which
|
||||||
|
rely on the old behavior may need to be updated.
|
||||||
|
|
||||||
|
Thanks to [@apesternikov](https://github.com/apesternikov) for the patch.
|
||||||
|
|
||||||
|
* [PR #42](https://github.com/magiconair/properties/pull/42): Made Content-Type check whitespace agnostic in LoadURL()
|
||||||
|
|
||||||
|
Thanks to [@aliras1](https://github.com/aliras1) for the patch.
|
||||||
|
|
||||||
|
* [PR #41](https://github.com/magiconair/properties/pull/41): Make key/value separator configurable on Write()
|
||||||
|
|
||||||
|
Thanks to [@mkjor](https://github.com/mkjor) for the patch.
|
||||||
|
|
||||||
|
* [PR #40](https://github.com/magiconair/properties/pull/40): Add method to return a sorted list of keys
|
||||||
|
|
||||||
|
Thanks to [@mkjor](https://github.com/mkjor) for the patch.
|
||||||
|
|
||||||
### [1.8.1](https://github.com/magiconair/properties/tree/v1.8.1) - 10 May 2019
|
### [1.8.1](https://github.com/magiconair/properties/tree/v1.8.1) - 10 May 2019
|
||||||
|
|
||||||
* [PR #26](https://github.com/magiconair/properties/pull/35): Close body always after request
|
* [PR #35](https://github.com/magiconair/properties/pull/35): Close body always after request
|
||||||
|
|
||||||
This patch ensures that in `LoadURL` the response body is always closed.
|
This patch ensures that in `LoadURL` the response body is always closed.
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
goproperties - properties file decoder for Go
|
Copyright (c) 2013-2020, Frank Schroeder
|
||||||
|
|
||||||
Copyright (c) 2013-2018 - Frank Schroeder
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
list of conditions and the following disclaimer.
|
list of conditions and the following disclaimer.
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
and/or other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
|
|
1
vendor/github.com/magiconair/properties/README.md
generated
vendored
1
vendor/github.com/magiconair/properties/README.md
generated
vendored
|
@ -1,6 +1,5 @@
|
||||||
[![](https://img.shields.io/github/tag/magiconair/properties.svg?style=flat-square&label=release)](https://github.com/magiconair/properties/releases)
|
[![](https://img.shields.io/github/tag/magiconair/properties.svg?style=flat-square&label=release)](https://github.com/magiconair/properties/releases)
|
||||||
[![Travis CI Status](https://img.shields.io/travis/magiconair/properties.svg?branch=master&style=flat-square&label=travis)](https://travis-ci.org/magiconair/properties)
|
[![Travis CI Status](https://img.shields.io/travis/magiconair/properties.svg?branch=master&style=flat-square&label=travis)](https://travis-ci.org/magiconair/properties)
|
||||||
[![CircleCI Status](https://img.shields.io/circleci/project/github/magiconair/properties.svg?label=circle+ci&style=flat-square)](https://circleci.com/gh/magiconair/properties)
|
|
||||||
[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg?style=flat-square)](https://raw.githubusercontent.com/magiconair/properties/master/LICENSE)
|
[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg?style=flat-square)](https://raw.githubusercontent.com/magiconair/properties/master/LICENSE)
|
||||||
[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties)
|
[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties)
|
||||||
|
|
||||||
|
|
2
vendor/github.com/magiconair/properties/go.mod
generated
vendored
2
vendor/github.com/magiconair/properties/go.mod
generated
vendored
|
@ -1 +1,3 @@
|
||||||
module github.com/magiconair/properties
|
module github.com/magiconair/properties
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
5
vendor/github.com/magiconair/properties/load.go
generated
vendored
5
vendor/github.com/magiconair/properties/load.go
generated
vendored
|
@ -132,11 +132,12 @@ func (l *Loader) LoadURL(url string) (*Properties, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ct := resp.Header.Get("Content-Type")
|
ct := resp.Header.Get("Content-Type")
|
||||||
|
ct = strings.Join(strings.Fields(ct), "")
|
||||||
var enc Encoding
|
var enc Encoding
|
||||||
switch strings.ToLower(ct) {
|
switch strings.ToLower(ct) {
|
||||||
case "text/plain", "text/plain; charset=iso-8859-1", "text/plain; charset=latin1":
|
case "text/plain", "text/plain;charset=iso-8859-1", "text/plain;charset=latin1":
|
||||||
enc = ISO_8859_1
|
enc = ISO_8859_1
|
||||||
case "", "text/plain; charset=utf-8":
|
case "", "text/plain;charset=utf-8":
|
||||||
enc = UTF8
|
enc = UTF8
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("properties: invalid content type %s", ct)
|
return nil, fmt.Errorf("properties: invalid content type %s", ct)
|
||||||
|
|
31
vendor/github.com/magiconair/properties/properties.go
generated
vendored
31
vendor/github.com/magiconair/properties/properties.go
generated
vendored
|
@ -8,11 +8,13 @@ package properties
|
||||||
// BUG(frank): Write() does not allow to configure the newline character. Therefore, on Windows LF is used.
|
// BUG(frank): Write() does not allow to configure the newline character. Therefore, on Windows LF is used.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -69,6 +71,9 @@ type Properties struct {
|
||||||
|
|
||||||
// Stores the keys in order of appearance.
|
// Stores the keys in order of appearance.
|
||||||
k []string
|
k []string
|
||||||
|
|
||||||
|
// WriteSeparator specifies the separator of key and value while writing the properties.
|
||||||
|
WriteSeparator string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProperties creates a new Properties struct with the default
|
// NewProperties creates a new Properties struct with the default
|
||||||
|
@ -111,7 +116,7 @@ func (p *Properties) Get(key string) (value string, ok bool) {
|
||||||
// circular references and malformed expressions
|
// circular references and malformed expressions
|
||||||
// so we panic if we still get an error here.
|
// so we panic if we still get an error here.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrorHandler(fmt.Errorf("%s in %q", err, key+" = "+v))
|
ErrorHandler(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return expanded, true
|
return expanded, true
|
||||||
|
@ -586,6 +591,12 @@ func (p *Properties) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort sorts the properties keys in alphabetical order.
|
||||||
|
// This is helpfully before writing the properties.
|
||||||
|
func (p *Properties) Sort() {
|
||||||
|
sort.Strings(p.k)
|
||||||
|
}
|
||||||
|
|
||||||
// Write writes all unexpanded 'key = value' pairs to the given writer.
|
// Write writes all unexpanded 'key = value' pairs to the given writer.
|
||||||
// Write returns the number of bytes written and any write error encountered.
|
// Write returns the number of bytes written and any write error encountered.
|
||||||
func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) {
|
func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) {
|
||||||
|
@ -626,7 +637,7 @@ func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n i
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range comments {
|
for _, c := range comments {
|
||||||
x, err = fmt.Fprintf(w, "%s%s\n", prefix, encode(c, "", enc))
|
x, err = fmt.Fprintf(w, "%s%s\n", prefix, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -635,8 +646,11 @@ func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sep := " = "
|
||||||
x, err = fmt.Fprintf(w, "%s = %s\n", encode(key, " :", enc), encode(value, "", enc))
|
if p.WriteSeparator != "" {
|
||||||
|
sep = p.WriteSeparator
|
||||||
|
}
|
||||||
|
x, err = fmt.Fprintf(w, "%s%s%s\n", encode(key, " :", enc), sep, encode(value, "", enc))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -753,7 +767,12 @@ func expand(s string, keys []string, prefix, postfix string, values map[string]s
|
||||||
|
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
if key == k {
|
if key == k {
|
||||||
return "", fmt.Errorf("circular reference")
|
var b bytes.Buffer
|
||||||
|
b.WriteString("circular reference in:\n")
|
||||||
|
for _, k1 := range keys {
|
||||||
|
fmt.Fprintf(&b, "%s=%s\n", k1, values[k1])
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf(b.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,6 +839,8 @@ func escape(r rune, special string) string {
|
||||||
return "\\r"
|
return "\\r"
|
||||||
case '\t':
|
case '\t':
|
||||||
return "\\t"
|
return "\\t"
|
||||||
|
case '\\':
|
||||||
|
return "\\\\"
|
||||||
default:
|
default:
|
||||||
if strings.ContainsRune(special, r) {
|
if strings.ContainsRune(special, r) {
|
||||||
return "\\" + string(r)
|
return "\\" + string(r)
|
||||||
|
|
15
vendor/github.com/mattn/go-colorable/.travis.yml
generated
vendored
Normal file
15
vendor/github.com/mattn/go-colorable/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
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)
|
||||||
|
|
21
vendor/github.com/mattn/go-colorable/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mattn/go-colorable/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.
|
48
vendor/github.com/mattn/go-colorable/README.md
generated
vendored
Normal file
48
vendor/github.com/mattn/go-colorable/README.md
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# go-colorable
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable)
|
||||||
|
[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)
|
||||||
|
|
||||||
|
Colorable writer for windows.
|
||||||
|
|
||||||
|
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
|
||||||
|
This package is possible to handle escape sequence for ansi color on windows.
|
||||||
|
|
||||||
|
## Too Bad!
|
||||||
|
|
||||||
|
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
|
||||||
|
|
||||||
|
|
||||||
|
## So Good!
|
||||||
|
|
||||||
|
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
|
||||||
|
logrus.SetOutput(colorable.NewColorableStdout())
|
||||||
|
|
||||||
|
logrus.Info("succeeded")
|
||||||
|
logrus.Warn("not correct")
|
||||||
|
logrus.Error("something error")
|
||||||
|
logrus.Fatal("panic")
|
||||||
|
```
|
||||||
|
|
||||||
|
You can compile above code on non-windows OSs.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
$ go get github.com/mattn/go-colorable
|
||||||
|
```
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
# Author
|
||||||
|
|
||||||
|
Yasuhiro Matsumoto (a.k.a mattn)
|
37
vendor/github.com/mattn/go-colorable/colorable_appengine.go
generated
vendored
Normal file
37
vendor/github.com/mattn/go-colorable/colorable_appengine.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// +build appengine
|
||||||
|
|
||||||
|
package colorable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-isatty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewColorable returns new instance of Writer which handles escape sequence.
|
||||||
|
func NewColorable(file *os.File) io.Writer {
|
||||||
|
if file == nil {
|
||||||
|
panic("nil passed instead of *os.File to NewColorable()")
|
||||||
|
}
|
||||||
|
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||||
|
func NewColorableStdout() io.Writer {
|
||||||
|
return os.Stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||||
|
func NewColorableStderr() io.Writer {
|
||||||
|
return os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableColorsStdout enable colors if possible.
|
||||||
|
func EnableColorsStdout(enabled *bool) func() {
|
||||||
|
if enabled != nil {
|
||||||
|
*enabled = true
|
||||||
|
}
|
||||||
|
return func() {}
|
||||||
|
}
|
38
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
Normal file
38
vendor/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// +build !windows
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package colorable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-isatty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewColorable returns new instance of Writer which handles escape sequence.
|
||||||
|
func NewColorable(file *os.File) io.Writer {
|
||||||
|
if file == nil {
|
||||||
|
panic("nil passed instead of *os.File to NewColorable()")
|
||||||
|
}
|
||||||
|
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
||||||
|
func NewColorableStdout() io.Writer {
|
||||||
|
return os.Stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
||||||
|
func NewColorableStderr() io.Writer {
|
||||||
|
return os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableColorsStdout enable colors if possible.
|
||||||
|
func EnableColorsStdout(enabled *bool) func() {
|
||||||
|
if enabled != nil {
|
||||||
|
*enabled = true
|
||||||
|
}
|
||||||
|
return func() {}
|
||||||
|
}
|
1043
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
Normal file
1043
vendor/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
8
vendor/github.com/mattn/go-colorable/go.mod
generated
vendored
Normal file
8
vendor/github.com/mattn/go-colorable/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module github.com/mattn/go-colorable
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-isatty v0.0.12
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
go 1.13
|
5
vendor/github.com/mattn/go-colorable/go.sum
generated
vendored
Normal file
5
vendor/github.com/mattn/go-colorable/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
12
vendor/github.com/mattn/go-colorable/go.test.sh
generated
vendored
Normal file
12
vendor/github.com/mattn/go-colorable/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
|
55
vendor/github.com/mattn/go-colorable/noncolorable.go
generated
vendored
Normal file
55
vendor/github.com/mattn/go-colorable/noncolorable.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package colorable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NonColorable holds writer but removes escape sequence.
|
||||||
|
type NonColorable struct {
|
||||||
|
out io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.
|
||||||
|
func NewNonColorable(w io.Writer) io.Writer {
|
||||||
|
return &NonColorable{out: w}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes data on console
|
||||||
|
func (w *NonColorable) Write(data []byte) (n int, err error) {
|
||||||
|
er := bytes.NewReader(data)
|
||||||
|
var bw [1]byte
|
||||||
|
loop:
|
||||||
|
for {
|
||||||
|
c1, err := er.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
if c1 != 0x1b {
|
||||||
|
bw[0] = c1
|
||||||
|
w.out.Write(bw[:])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c2, err := er.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
if c2 != 0x5b {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for {
|
||||||
|
c, err := er.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buf.Write([]byte(string(c)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(data), nil
|
||||||
|
}
|
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
|
||||||
|
|
||||||
|
[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)
|
||||||
|
[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-isatty)
|
||||||
|
[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](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
|
||||||
|
============
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth)
|
||||||
|
[![Codecov](https://codecov.io/gh/mattn/go-runewidth/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-runewidth)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/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
|
273
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
Normal file
273
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
// StrictEmojiNeutral should be set false if handle broken fonts
|
||||||
|
StrictEmojiNeutral bool = true
|
||||||
|
|
||||||
|
// DefaultCondition is a condition in current locale
|
||||||
|
DefaultCondition = &Condition{
|
||||||
|
EastAsianWidth: false,
|
||||||
|
StrictEmojiNeutral: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
StrictEmojiNeutral bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCondition return new instance of Condition which is current locale.
|
||||||
|
func NewCondition() *Condition {
|
||||||
|
return &Condition{
|
||||||
|
EastAsianWidth: EastAsianWidth,
|
||||||
|
StrictEmojiNeutral: StrictEmojiNeutral,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RuneWidth returns the number of cells in r.
|
||||||
|
// See http://www.unicode.org/reports/tr11/
|
||||||
|
func (c *Condition) RuneWidth(r rune) int {
|
||||||
|
// optimized version, verified by TestRuneWidthChecksums()
|
||||||
|
if !c.EastAsianWidth {
|
||||||
|
switch {
|
||||||
|
case r < 0x20 || r > 0x10FFFF:
|
||||||
|
return 0
|
||||||
|
case (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint
|
||||||
|
return 0
|
||||||
|
case r < 0x300:
|
||||||
|
return 1
|
||||||
|
case inTable(r, narrow):
|
||||||
|
return 1
|
||||||
|
case inTables(r, nonprint, combining):
|
||||||
|
return 0
|
||||||
|
case inTable(r, doublewidth):
|
||||||
|
return 2
|
||||||
|
default:
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch {
|
||||||
|
case r < 0 || r > 0x10FFFF || inTables(r, nonprint, combining):
|
||||||
|
return 0
|
||||||
|
case inTable(r, narrow):
|
||||||
|
return 1
|
||||||
|
case inTables(r, ambiguous, doublewidth):
|
||||||
|
return 2
|
||||||
|
case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow):
|
||||||
|
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)
|
||||||
|
}
|
439
vendor/github.com/mattn/go-runewidth/runewidth_table.go
generated
vendored
Normal file
439
vendor/github.com/mattn/go-runewidth/runewidth_table.go
generated
vendored
Normal file
|
@ -0,0 +1,439 @@
|
||||||
|
// 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 narrow = table{
|
||||||
|
{0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6},
|
||||||
|
{0x00AC, 0x00AC}, {0x00AF, 0x00AF}, {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
|
||||||
|
}
|
8
vendor/github.com/mitchellh/mapstructure/.travis.yml
generated
vendored
8
vendor/github.com/mitchellh/mapstructure/.travis.yml
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "1.11.x"
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test
|
|
52
vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
generated
vendored
52
vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
generated
vendored
|
@ -1,3 +1,55 @@
|
||||||
|
## unreleased
|
||||||
|
|
||||||
|
* Fix regression where `*time.Time` value would be set to empty and not be sent
|
||||||
|
to decode hooks properly [GH-232]
|
||||||
|
|
||||||
|
## 1.4.0
|
||||||
|
|
||||||
|
* A new decode hook type `DecodeHookFuncValue` has been added that has
|
||||||
|
access to the full values. [GH-183]
|
||||||
|
* Squash is now supported with embedded fields that are struct pointers [GH-205]
|
||||||
|
* Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206]
|
||||||
|
|
||||||
|
## 1.3.3
|
||||||
|
|
||||||
|
* Decoding maps from maps creates a settable value for decode hooks [GH-203]
|
||||||
|
|
||||||
|
## 1.3.2
|
||||||
|
|
||||||
|
* Decode into interface type with a struct value is supported [GH-187]
|
||||||
|
|
||||||
|
## 1.3.1
|
||||||
|
|
||||||
|
* Squash should only squash embedded structs. [GH-194]
|
||||||
|
|
||||||
|
## 1.3.0
|
||||||
|
|
||||||
|
* Added `",omitempty"` support. This will ignore zero values in the source
|
||||||
|
structure when encoding. [GH-145]
|
||||||
|
|
||||||
|
## 1.2.3
|
||||||
|
|
||||||
|
* Fix duplicate entries in Keys list with pointer values. [GH-185]
|
||||||
|
|
||||||
|
## 1.2.2
|
||||||
|
|
||||||
|
* Do not add unsettable (unexported) values to the unused metadata key
|
||||||
|
or "remain" value. [GH-150]
|
||||||
|
|
||||||
|
## 1.2.1
|
||||||
|
|
||||||
|
* Go modules checksum mismatch fix
|
||||||
|
|
||||||
|
## 1.2.0
|
||||||
|
|
||||||
|
* Added support to capture unused values in a field using the `",remain"` value
|
||||||
|
in the mapstructure tag. There is an example to showcase usage.
|
||||||
|
* Added `DecoderConfig` option to always squash embedded structs
|
||||||
|
* `json.Number` can decode into `uint` types
|
||||||
|
* Empty slices are preserved and not replaced with nil slices
|
||||||
|
* Fix panic that can occur in when decoding a map into a nil slice of structs
|
||||||
|
* Improved package documentation for godoc
|
||||||
|
|
||||||
## 1.1.2
|
## 1.1.2
|
||||||
|
|
||||||
* Fix error when decode hook decodes interface implementation into interface
|
* Fix error when decode hook decodes interface implementation into interface
|
||||||
|
|
71
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
71
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
|
@ -1,6 +1,7 @@
|
||||||
package mapstructure
|
package mapstructure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
@ -16,10 +17,11 @@ func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
|
||||||
// Create variables here so we can reference them with the reflect pkg
|
// Create variables here so we can reference them with the reflect pkg
|
||||||
var f1 DecodeHookFuncType
|
var f1 DecodeHookFuncType
|
||||||
var f2 DecodeHookFuncKind
|
var f2 DecodeHookFuncKind
|
||||||
|
var f3 DecodeHookFuncValue
|
||||||
|
|
||||||
// Fill in the variables into this interface and the rest is done
|
// Fill in the variables into this interface and the rest is done
|
||||||
// automatically using the reflect package.
|
// automatically using the reflect package.
|
||||||
potential := []interface{}{f1, f2}
|
potential := []interface{}{f1, f2, f3}
|
||||||
|
|
||||||
v := reflect.ValueOf(h)
|
v := reflect.ValueOf(h)
|
||||||
vt := v.Type()
|
vt := v.Type()
|
||||||
|
@ -38,13 +40,15 @@ func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
|
||||||
// that took reflect.Kind instead of reflect.Type.
|
// that took reflect.Kind instead of reflect.Type.
|
||||||
func DecodeHookExec(
|
func DecodeHookExec(
|
||||||
raw DecodeHookFunc,
|
raw DecodeHookFunc,
|
||||||
from reflect.Type, to reflect.Type,
|
from reflect.Value, to reflect.Value) (interface{}, error) {
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
switch f := typedDecodeHook(raw).(type) {
|
switch f := typedDecodeHook(raw).(type) {
|
||||||
case DecodeHookFuncType:
|
case DecodeHookFuncType:
|
||||||
return f(from, to, data)
|
return f(from.Type(), to.Type(), from.Interface())
|
||||||
case DecodeHookFuncKind:
|
case DecodeHookFuncKind:
|
||||||
return f(from.Kind(), to.Kind(), data)
|
return f(from.Kind(), to.Kind(), from.Interface())
|
||||||
|
case DecodeHookFuncValue:
|
||||||
|
return f(from, to)
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("invalid decode hook signature")
|
return nil, errors.New("invalid decode hook signature")
|
||||||
}
|
}
|
||||||
|
@ -56,22 +60,16 @@ func DecodeHookExec(
|
||||||
// The composed funcs are called in order, with the result of the
|
// The composed funcs are called in order, with the result of the
|
||||||
// previous transformation.
|
// previous transformation.
|
||||||
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
|
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
|
||||||
return func(
|
return func(f reflect.Value, t reflect.Value) (interface{}, error) {
|
||||||
f reflect.Type,
|
|
||||||
t reflect.Type,
|
|
||||||
data interface{}) (interface{}, error) {
|
|
||||||
var err error
|
var err error
|
||||||
|
var data interface{}
|
||||||
|
newFrom := f
|
||||||
for _, f1 := range fs {
|
for _, f1 := range fs {
|
||||||
data, err = DecodeHookExec(f1, f, t, data)
|
data, err = DecodeHookExec(f1, newFrom, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
newFrom = reflect.ValueOf(data)
|
||||||
// Modify the from kind to be correct with the new data
|
|
||||||
f = nil
|
|
||||||
if val := reflect.ValueOf(data); val.IsValid() {
|
|
||||||
f = val.Type()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
|
@ -215,3 +213,44 @@ func WeaklyTypedHook(
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RecursiveStructToMapHookFunc() DecodeHookFunc {
|
||||||
|
return func(f reflect.Value, t reflect.Value) (interface{}, error) {
|
||||||
|
if f.Kind() != reflect.Struct {
|
||||||
|
return f.Interface(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var i interface{} = struct{}{}
|
||||||
|
if t.Type() != reflect.TypeOf(&i).Elem() {
|
||||||
|
return f.Interface(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m := make(map[string]interface{})
|
||||||
|
t.Set(reflect.ValueOf(m))
|
||||||
|
|
||||||
|
return f.Interface(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies
|
||||||
|
// strings to the UnmarshalText function, when the target type
|
||||||
|
// implements the encoding.TextUnmarshaler interface
|
||||||
|
func TextUnmarshallerHookFunc() DecodeHookFuncType {
|
||||||
|
return func(
|
||||||
|
f reflect.Type,
|
||||||
|
t reflect.Type,
|
||||||
|
data interface{}) (interface{}, error) {
|
||||||
|
if f.Kind() != reflect.String {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
result := reflect.New(t).Interface()
|
||||||
|
unmarshaller, ok := result.(encoding.TextUnmarshaler)
|
||||||
|
if !ok {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
if err := unmarshaller.UnmarshalText([]byte(data.(string))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
vendor/github.com/mitchellh/mapstructure/go.mod
generated
vendored
2
vendor/github.com/mitchellh/mapstructure/go.mod
generated
vendored
|
@ -1 +1,3 @@
|
||||||
module github.com/mitchellh/mapstructure
|
module github.com/mitchellh/mapstructure
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
481
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
481
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
|
@ -1,10 +1,161 @@
|
||||||
// Package mapstructure exposes functionality to convert an arbitrary
|
// Package mapstructure exposes functionality to convert one arbitrary
|
||||||
// map[string]interface{} into a native Go structure.
|
// Go type into another, typically to convert a map[string]interface{}
|
||||||
|
// into a native Go structure.
|
||||||
//
|
//
|
||||||
// The Go structure can be arbitrarily complex, containing slices,
|
// The Go structure can be arbitrarily complex, containing slices,
|
||||||
// other structs, etc. and the decoder will properly decode nested
|
// other structs, etc. and the decoder will properly decode nested
|
||||||
// maps and so on into the proper structures in the native Go struct.
|
// maps and so on into the proper structures in the native Go struct.
|
||||||
// See the examples to see what the decoder is capable of.
|
// See the examples to see what the decoder is capable of.
|
||||||
|
//
|
||||||
|
// The simplest function to start with is Decode.
|
||||||
|
//
|
||||||
|
// Field Tags
|
||||||
|
//
|
||||||
|
// When decoding to a struct, mapstructure will use the field name by
|
||||||
|
// default to perform the mapping. For example, if a struct has a field
|
||||||
|
// "Username" then mapstructure will look for a key in the source value
|
||||||
|
// of "username" (case insensitive).
|
||||||
|
//
|
||||||
|
// type User struct {
|
||||||
|
// Username string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// You can change the behavior of mapstructure by using struct tags.
|
||||||
|
// The default struct tag that mapstructure looks for is "mapstructure"
|
||||||
|
// but you can customize it using DecoderConfig.
|
||||||
|
//
|
||||||
|
// Renaming Fields
|
||||||
|
//
|
||||||
|
// To rename the key that mapstructure looks for, use the "mapstructure"
|
||||||
|
// tag and set a value directly. For example, to change the "username" example
|
||||||
|
// above to "user":
|
||||||
|
//
|
||||||
|
// type User struct {
|
||||||
|
// Username string `mapstructure:"user"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Embedded Structs and Squashing
|
||||||
|
//
|
||||||
|
// Embedded structs are treated as if they're another field with that name.
|
||||||
|
// By default, the two structs below are equivalent when decoding with
|
||||||
|
// mapstructure:
|
||||||
|
//
|
||||||
|
// type Person struct {
|
||||||
|
// Name string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// type Friend struct {
|
||||||
|
// Person
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// type Friend struct {
|
||||||
|
// Person Person
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// This would require an input that looks like below:
|
||||||
|
//
|
||||||
|
// map[string]interface{}{
|
||||||
|
// "person": map[string]interface{}{"name": "alice"},
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// If your "person" value is NOT nested, then you can append ",squash" to
|
||||||
|
// your tag value and mapstructure will treat it as if the embedded struct
|
||||||
|
// were part of the struct directly. Example:
|
||||||
|
//
|
||||||
|
// type Friend struct {
|
||||||
|
// Person `mapstructure:",squash"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Now the following input would be accepted:
|
||||||
|
//
|
||||||
|
// map[string]interface{}{
|
||||||
|
// "name": "alice",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// When decoding from a struct to a map, the squash tag squashes the struct
|
||||||
|
// fields into a single map. Using the example structs from above:
|
||||||
|
//
|
||||||
|
// Friend{Person: Person{Name: "alice"}}
|
||||||
|
//
|
||||||
|
// Will be decoded into a map:
|
||||||
|
//
|
||||||
|
// map[string]interface{}{
|
||||||
|
// "name": "alice",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// DecoderConfig has a field that changes the behavior of mapstructure
|
||||||
|
// to always squash embedded structs.
|
||||||
|
//
|
||||||
|
// Remainder Values
|
||||||
|
//
|
||||||
|
// If there are any unmapped keys in the source value, mapstructure by
|
||||||
|
// default will silently ignore them. You can error by setting ErrorUnused
|
||||||
|
// in DecoderConfig. If you're using Metadata you can also maintain a slice
|
||||||
|
// of the unused keys.
|
||||||
|
//
|
||||||
|
// You can also use the ",remain" suffix on your tag to collect all unused
|
||||||
|
// values in a map. The field with this tag MUST be a map type and should
|
||||||
|
// probably be a "map[string]interface{}" or "map[interface{}]interface{}".
|
||||||
|
// See example below:
|
||||||
|
//
|
||||||
|
// type Friend struct {
|
||||||
|
// Name string
|
||||||
|
// Other map[string]interface{} `mapstructure:",remain"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Given the input below, Other would be populated with the other
|
||||||
|
// values that weren't used (everything but "name"):
|
||||||
|
//
|
||||||
|
// map[string]interface{}{
|
||||||
|
// "name": "bob",
|
||||||
|
// "address": "123 Maple St.",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Omit Empty Values
|
||||||
|
//
|
||||||
|
// When decoding from a struct to any other value, you may use the
|
||||||
|
// ",omitempty" suffix on your tag to omit that value if it equates to
|
||||||
|
// the zero value. The zero value of all types is specified in the Go
|
||||||
|
// specification.
|
||||||
|
//
|
||||||
|
// For example, the zero type of a numeric type is zero ("0"). If the struct
|
||||||
|
// field value is zero and a numeric type, the field is empty, and it won't
|
||||||
|
// be encoded into the destination type.
|
||||||
|
//
|
||||||
|
// type Source {
|
||||||
|
// Age int `mapstructure:",omitempty"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Unexported fields
|
||||||
|
//
|
||||||
|
// Since unexported (private) struct fields cannot be set outside the package
|
||||||
|
// where they are defined, the decoder will simply skip them.
|
||||||
|
//
|
||||||
|
// For this output type definition:
|
||||||
|
//
|
||||||
|
// type Exported struct {
|
||||||
|
// private string // this unexported field will be skipped
|
||||||
|
// Public string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Using this map as input:
|
||||||
|
//
|
||||||
|
// map[string]interface{}{
|
||||||
|
// "private": "I will be ignored",
|
||||||
|
// "Public": "I made it through!",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The following struct will be decoded:
|
||||||
|
//
|
||||||
|
// type Exported struct {
|
||||||
|
// private: "" // field is left with an empty string (zero value)
|
||||||
|
// Public: "I made it through!"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Other Configuration
|
||||||
|
//
|
||||||
|
// mapstructure is highly configurable. See the DecoderConfig struct
|
||||||
|
// for other features and options that are supported.
|
||||||
package mapstructure
|
package mapstructure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -21,10 +172,11 @@ import (
|
||||||
// data transformations. See "DecodeHook" in the DecoderConfig
|
// data transformations. See "DecodeHook" in the DecoderConfig
|
||||||
// struct.
|
// struct.
|
||||||
//
|
//
|
||||||
// The type should be DecodeHookFuncType or DecodeHookFuncKind.
|
// The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or
|
||||||
// Either is accepted. Types are a superset of Kinds (Types can return
|
// DecodeHookFuncValue.
|
||||||
// Kinds) and are generally a richer thing to use, but Kinds are simpler
|
// Values are a superset of Types (Values can return types), and Types are a
|
||||||
// if you only need those.
|
// superset of Kinds (Types can return Kinds) and are generally a richer thing
|
||||||
|
// to use, but Kinds are simpler if you only need those.
|
||||||
//
|
//
|
||||||
// The reason DecodeHookFunc is multi-typed is for backwards compatibility:
|
// The reason DecodeHookFunc is multi-typed is for backwards compatibility:
|
||||||
// we started with Kinds and then realized Types were the better solution,
|
// we started with Kinds and then realized Types were the better solution,
|
||||||
|
@ -40,15 +192,22 @@ type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface
|
||||||
// source and target types.
|
// source and target types.
|
||||||
type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
|
type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
|
||||||
|
|
||||||
|
// DecodeHookFuncRaw is a DecodeHookFunc which has complete access to both the source and target
|
||||||
|
// values.
|
||||||
|
type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error)
|
||||||
|
|
||||||
// DecoderConfig is the configuration that is used to create a new decoder
|
// DecoderConfig is the configuration that is used to create a new decoder
|
||||||
// and allows customization of various aspects of decoding.
|
// and allows customization of various aspects of decoding.
|
||||||
type DecoderConfig struct {
|
type DecoderConfig struct {
|
||||||
// DecodeHook, if set, will be called before any decoding and any
|
// DecodeHook, if set, will be called before any decoding and any
|
||||||
// type conversion (if WeaklyTypedInput is on). This lets you modify
|
// type conversion (if WeaklyTypedInput is on). This lets you modify
|
||||||
// the values before they're set down onto the resulting struct.
|
// the values before they're set down onto the resulting struct. The
|
||||||
|
// DecodeHook is called for every map and value in the input. This means
|
||||||
|
// that if a struct has embedded fields with squash tags the decode hook
|
||||||
|
// is called only once with all of the input data, not once for each
|
||||||
|
// embedded struct.
|
||||||
//
|
//
|
||||||
// If an error is returned, the entire decode will fail with that
|
// If an error is returned, the entire decode will fail with that error.
|
||||||
// error.
|
|
||||||
DecodeHook DecodeHookFunc
|
DecodeHook DecodeHookFunc
|
||||||
|
|
||||||
// If ErrorUnused is true, then it is an error for there to exist
|
// If ErrorUnused is true, then it is an error for there to exist
|
||||||
|
@ -80,6 +239,14 @@ type DecoderConfig struct {
|
||||||
//
|
//
|
||||||
WeaklyTypedInput bool
|
WeaklyTypedInput bool
|
||||||
|
|
||||||
|
// Squash will squash embedded structs. A squash tag may also be
|
||||||
|
// added to an individual struct field using a tag. For example:
|
||||||
|
//
|
||||||
|
// type Parent struct {
|
||||||
|
// Child `mapstructure:",squash"`
|
||||||
|
// }
|
||||||
|
Squash bool
|
||||||
|
|
||||||
// Metadata is the struct that will contain extra metadata about
|
// Metadata is the struct that will contain extra metadata about
|
||||||
// the decoding. If this is nil, then no metadata will be tracked.
|
// the decoding. If this is nil, then no metadata will be tracked.
|
||||||
Metadata *Metadata
|
Metadata *Metadata
|
||||||
|
@ -261,9 +428,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||||
if d.config.DecodeHook != nil {
|
if d.config.DecodeHook != nil {
|
||||||
// We have a DecodeHook, so let's pre-process the input.
|
// We have a DecodeHook, so let's pre-process the input.
|
||||||
var err error
|
var err error
|
||||||
input, err = DecodeHookExec(
|
input, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal)
|
||||||
d.config.DecodeHook,
|
|
||||||
inputVal.Type(), outVal.Type(), input)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error decoding '%s': %s", name, err)
|
return fmt.Errorf("error decoding '%s': %s", name, err)
|
||||||
}
|
}
|
||||||
|
@ -271,6 +436,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
outputKind := getKind(outVal)
|
outputKind := getKind(outVal)
|
||||||
|
addMetaKey := true
|
||||||
switch outputKind {
|
switch outputKind {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
err = d.decodeBool(name, input, outVal)
|
err = d.decodeBool(name, input, outVal)
|
||||||
|
@ -289,7 +455,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
err = d.decodeMap(name, input, outVal)
|
err = d.decodeMap(name, input, outVal)
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
err = d.decodePtr(name, input, outVal)
|
addMetaKey, err = d.decodePtr(name, input, outVal)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
err = d.decodeSlice(name, input, outVal)
|
err = d.decodeSlice(name, input, outVal)
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
|
@ -303,7 +469,7 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||||
|
|
||||||
// If we reached here, then we successfully decoded SOMETHING, so
|
// If we reached here, then we successfully decoded SOMETHING, so
|
||||||
// mark the key as used if we're tracking metainput.
|
// mark the key as used if we're tracking metainput.
|
||||||
if d.config.Metadata != nil && name != "" {
|
if addMetaKey && d.config.Metadata != nil && name != "" {
|
||||||
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +480,34 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
|
||||||
// value to "data" of that type.
|
// value to "data" of that type.
|
||||||
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
||||||
if val.IsValid() && val.Elem().IsValid() {
|
if val.IsValid() && val.Elem().IsValid() {
|
||||||
return d.decode(name, data, val.Elem())
|
elem := val.Elem()
|
||||||
|
|
||||||
|
// If we can't address this element, then its not writable. Instead,
|
||||||
|
// we make a copy of the value (which is a pointer and therefore
|
||||||
|
// writable), decode into that, and replace the whole value.
|
||||||
|
copied := false
|
||||||
|
if !elem.CanAddr() {
|
||||||
|
copied = true
|
||||||
|
|
||||||
|
// Make *T
|
||||||
|
copy := reflect.New(elem.Type())
|
||||||
|
|
||||||
|
// *T = elem
|
||||||
|
copy.Elem().Set(elem)
|
||||||
|
|
||||||
|
// Set elem so we decode into it
|
||||||
|
elem = copy
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode. If we have an error then return. We also return right
|
||||||
|
// away if we're not a copy because that means we decoded directly.
|
||||||
|
if err := d.decode(name, data, elem); err != nil || !copied {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're a copy, we need to set te final result
|
||||||
|
val.Set(elem.Elem())
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
|
@ -386,8 +579,8 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
|
||||||
|
|
||||||
if !converted {
|
if !converted {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||||
name, val.Type(), dataVal.Type())
|
name, val.Type(), dataVal.Type(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -412,7 +605,12 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
|
||||||
val.SetInt(0)
|
val.SetInt(0)
|
||||||
}
|
}
|
||||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||||
i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
|
str := dataVal.String()
|
||||||
|
if str == "" {
|
||||||
|
str = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
i, err := strconv.ParseInt(str, 0, val.Type().Bits())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
val.SetInt(i)
|
val.SetInt(i)
|
||||||
} else {
|
} else {
|
||||||
|
@ -428,8 +626,8 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
|
||||||
val.SetInt(i)
|
val.SetInt(i)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||||
name, val.Type(), dataVal.Type())
|
name, val.Type(), dataVal.Type(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -438,6 +636,7 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
|
||||||
func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||||
dataKind := getKind(dataVal)
|
dataKind := getKind(dataVal)
|
||||||
|
dataType := dataVal.Type()
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case dataKind == reflect.Int:
|
case dataKind == reflect.Int:
|
||||||
|
@ -463,16 +662,33 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
|
||||||
val.SetUint(0)
|
val.SetUint(0)
|
||||||
}
|
}
|
||||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||||
i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
|
str := dataVal.String()
|
||||||
|
if str == "" {
|
||||||
|
str = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
i, err := strconv.ParseUint(str, 0, val.Type().Bits())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
val.SetUint(i)
|
val.SetUint(i)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
|
return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
|
||||||
}
|
}
|
||||||
|
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
|
||||||
|
jn := data.(json.Number)
|
||||||
|
i, err := jn.Int64()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"error decoding json.Number into %s: %s", name, err)
|
||||||
|
}
|
||||||
|
if i < 0 && !d.config.WeaklyTypedInput {
|
||||||
|
return fmt.Errorf("cannot parse '%s', %d overflows uint",
|
||||||
|
name, i)
|
||||||
|
}
|
||||||
|
val.SetUint(uint64(i))
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||||
name, val.Type(), dataVal.Type())
|
name, val.Type(), dataVal.Type(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -502,8 +718,8 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||||
name, val.Type(), dataVal.Type())
|
name, val.Type(), dataVal.Type(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -528,7 +744,12 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value)
|
||||||
val.SetFloat(0)
|
val.SetFloat(0)
|
||||||
}
|
}
|
||||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||||
f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
|
str := dataVal.String()
|
||||||
|
if str == "" {
|
||||||
|
str = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := strconv.ParseFloat(str, val.Type().Bits())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
val.SetFloat(f)
|
val.SetFloat(f)
|
||||||
} else {
|
} else {
|
||||||
|
@ -544,8 +765,8 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value)
|
||||||
val.SetFloat(i)
|
val.SetFloat(i)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||||
name, val.Type(), dataVal.Type())
|
name, val.Type(), dataVal.Type(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -596,7 +817,7 @@ func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val ref
|
||||||
|
|
||||||
for i := 0; i < dataVal.Len(); i++ {
|
for i := 0; i < dataVal.Len(); i++ {
|
||||||
err := d.decode(
|
err := d.decode(
|
||||||
fmt.Sprintf("%s[%d]", name, i),
|
name+"["+strconv.Itoa(i)+"]",
|
||||||
dataVal.Index(i).Interface(), val)
|
dataVal.Index(i).Interface(), val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -629,7 +850,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, k := range dataVal.MapKeys() {
|
for _, k := range dataVal.MapKeys() {
|
||||||
fieldName := fmt.Sprintf("%s[%s]", name, k)
|
fieldName := name + "[" + k.String() + "]"
|
||||||
|
|
||||||
// First decode the key into the proper type
|
// First decode the key into the proper type
|
||||||
currentKey := reflect.Indirect(reflect.New(valKeyType))
|
currentKey := reflect.Indirect(reflect.New(valKeyType))
|
||||||
|
@ -678,27 +899,40 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||||
}
|
}
|
||||||
|
|
||||||
tagValue := f.Tag.Get(d.config.TagName)
|
tagValue := f.Tag.Get(d.config.TagName)
|
||||||
tagParts := strings.Split(tagValue, ",")
|
keyName := f.Name
|
||||||
|
|
||||||
|
// If Squash is set in the config, we squash the field down.
|
||||||
|
squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
|
||||||
|
|
||||||
// Determine the name of the key in the map
|
// Determine the name of the key in the map
|
||||||
keyName := f.Name
|
if index := strings.Index(tagValue, ","); index != -1 {
|
||||||
if tagParts[0] != "" {
|
if tagValue[:index] == "-" {
|
||||||
if tagParts[0] == "-" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
keyName = tagParts[0]
|
// If "omitempty" is specified in the tag, it ignores empty values.
|
||||||
}
|
if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) {
|
||||||
|
continue
|
||||||
// If "squash" is specified in the tag, we squash the field down.
|
|
||||||
squash := false
|
|
||||||
for _, tag := range tagParts[1:] {
|
|
||||||
if tag == "squash" {
|
|
||||||
squash = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if squash && v.Kind() != reflect.Struct {
|
// If "squash" is specified in the tag, we squash the field down.
|
||||||
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
|
squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1
|
||||||
|
if squash {
|
||||||
|
// When squashing, the embedded type can be a pointer to a struct.
|
||||||
|
if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// The final type must be a struct
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyName = tagValue[:index]
|
||||||
|
} else if len(tagValue) > 0 {
|
||||||
|
if tagValue == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
keyName = tagValue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
@ -713,11 +947,22 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||||
mType := reflect.MapOf(vKeyType, vElemType)
|
mType := reflect.MapOf(vKeyType, vElemType)
|
||||||
vMap := reflect.MakeMap(mType)
|
vMap := reflect.MakeMap(mType)
|
||||||
|
|
||||||
err := d.decode(keyName, x.Interface(), vMap)
|
// Creating a pointer to a map so that other methods can completely
|
||||||
|
// overwrite the map if need be (looking at you decodeMapFromMap). The
|
||||||
|
// indirection allows the underlying map to be settable (CanSet() == true)
|
||||||
|
// where as reflect.MakeMap returns an unsettable map.
|
||||||
|
addrVal := reflect.New(vMap.Type())
|
||||||
|
reflect.Indirect(addrVal).Set(vMap)
|
||||||
|
|
||||||
|
err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the underlying map may have been completely overwritten so pull
|
||||||
|
// it indirectly out of the enclosing value.
|
||||||
|
vMap = reflect.Indirect(addrVal)
|
||||||
|
|
||||||
if squash {
|
if squash {
|
||||||
for _, k := range vMap.MapKeys() {
|
for _, k := range vMap.MapKeys() {
|
||||||
valMap.SetMapIndex(k, vMap.MapIndex(k))
|
valMap.SetMapIndex(k, vMap.MapIndex(k))
|
||||||
|
@ -738,7 +983,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (bool, error) {
|
||||||
// If the input data is nil, then we want to just set the output
|
// If the input data is nil, then we want to just set the output
|
||||||
// pointer to be nil as well.
|
// pointer to be nil as well.
|
||||||
isNil := data == nil
|
isNil := data == nil
|
||||||
|
@ -759,7 +1004,7 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
|
||||||
val.Set(nilValue)
|
val.Set(nilValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an element of the concrete (non pointer) type and decode
|
// Create an element of the concrete (non pointer) type and decode
|
||||||
|
@ -773,16 +1018,16 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
val.Set(realVal)
|
val.Set(realVal)
|
||||||
} else {
|
} else {
|
||||||
if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
|
if err := d.decode(name, data, reflect.Indirect(val)); err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
|
||||||
|
@ -791,8 +1036,8 @@ func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) e
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||||
if val.Type() != dataVal.Type() {
|
if val.Type() != dataVal.Type() {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||||
name, val.Type(), dataVal.Type())
|
name, val.Type(), dataVal.Type(), data)
|
||||||
}
|
}
|
||||||
val.Set(dataVal)
|
val.Set(dataVal)
|
||||||
return nil
|
return nil
|
||||||
|
@ -805,8 +1050,8 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||||
valElemType := valType.Elem()
|
valElemType := valType.Elem()
|
||||||
sliceType := reflect.SliceOf(valElemType)
|
sliceType := reflect.SliceOf(valElemType)
|
||||||
|
|
||||||
valSlice := val
|
// If we have a non array/slice type then we first attempt to convert.
|
||||||
if valSlice.IsNil() || d.config.ZeroFields {
|
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
||||||
if d.config.WeaklyTypedInput {
|
if d.config.WeaklyTypedInput {
|
||||||
switch {
|
switch {
|
||||||
// Slice and array we use the normal logic
|
// Slice and array we use the normal logic
|
||||||
|
@ -833,18 +1078,17 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check input type
|
return fmt.Errorf(
|
||||||
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
"'%s': source data must be an array or slice, got %s", name, dataValKind)
|
||||||
return fmt.Errorf(
|
}
|
||||||
"'%s': source data must be an array or slice, got %s", name, dataValKind)
|
|
||||||
|
|
||||||
}
|
// If the input value is nil, then don't allocate since empty != nil
|
||||||
|
if dataVal.IsNil() {
|
||||||
// If the input value is empty, then don't allocate since non-nil != nil
|
return nil
|
||||||
if dataVal.Len() == 0 {
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
valSlice := val
|
||||||
|
if valSlice.IsNil() || d.config.ZeroFields {
|
||||||
// Make a new slice to hold our result, same size as the original data.
|
// Make a new slice to hold our result, same size as the original data.
|
||||||
valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
|
valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
|
||||||
}
|
}
|
||||||
|
@ -859,7 +1103,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||||
}
|
}
|
||||||
currentField := valSlice.Index(i)
|
currentField := valSlice.Index(i)
|
||||||
|
|
||||||
fieldName := fmt.Sprintf("%s[%d]", name, i)
|
fieldName := name + "[" + strconv.Itoa(i) + "]"
|
||||||
if err := d.decode(fieldName, currentData, currentField); err != nil {
|
if err := d.decode(fieldName, currentData, currentField); err != nil {
|
||||||
errors = appendErrors(errors, err)
|
errors = appendErrors(errors, err)
|
||||||
}
|
}
|
||||||
|
@ -926,7 +1170,7 @@ func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value)
|
||||||
currentData := dataVal.Index(i).Interface()
|
currentData := dataVal.Index(i).Interface()
|
||||||
currentField := valArray.Index(i)
|
currentField := valArray.Index(i)
|
||||||
|
|
||||||
fieldName := fmt.Sprintf("%s[%d]", name, i)
|
fieldName := name + "[" + strconv.Itoa(i) + "]"
|
||||||
if err := d.decode(fieldName, currentData, currentField); err != nil {
|
if err := d.decode(fieldName, currentData, currentField); err != nil {
|
||||||
errors = appendErrors(errors, err)
|
errors = appendErrors(errors, err)
|
||||||
}
|
}
|
||||||
|
@ -962,13 +1206,23 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
// Not the most efficient way to do this but we can optimize later if
|
// Not the most efficient way to do this but we can optimize later if
|
||||||
// we want to. To convert from struct to struct we go to map first
|
// we want to. To convert from struct to struct we go to map first
|
||||||
// as an intermediary.
|
// as an intermediary.
|
||||||
m := make(map[string]interface{})
|
|
||||||
mval := reflect.Indirect(reflect.ValueOf(&m))
|
// Make a new map to hold our result
|
||||||
if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil {
|
mapType := reflect.TypeOf((map[string]interface{})(nil))
|
||||||
|
mval := reflect.MakeMap(mapType)
|
||||||
|
|
||||||
|
// Creating a pointer to a map so that other methods can completely
|
||||||
|
// overwrite the map if need be (looking at you decodeMapFromMap). The
|
||||||
|
// indirection allows the underlying map to be settable (CanSet() == true)
|
||||||
|
// where as reflect.MakeMap returns an unsettable map.
|
||||||
|
addrVal := reflect.New(mval.Type())
|
||||||
|
|
||||||
|
reflect.Indirect(addrVal).Set(mval)
|
||||||
|
if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := d.decodeStructFromMap(name, mval, val)
|
result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1005,6 +1259,11 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
field reflect.StructField
|
field reflect.StructField
|
||||||
val reflect.Value
|
val reflect.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remainField is set to a valid field set with the "remain" tag if
|
||||||
|
// we are keeping track of remaining values.
|
||||||
|
var remainField *field
|
||||||
|
|
||||||
fields := []field{}
|
fields := []field{}
|
||||||
for len(structs) > 0 {
|
for len(structs) > 0 {
|
||||||
structVal := structs[0]
|
structVal := structs[0]
|
||||||
|
@ -1014,30 +1273,47 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
|
|
||||||
for i := 0; i < structType.NumField(); i++ {
|
for i := 0; i < structType.NumField(); i++ {
|
||||||
fieldType := structType.Field(i)
|
fieldType := structType.Field(i)
|
||||||
fieldKind := fieldType.Type.Kind()
|
fieldVal := structVal.Field(i)
|
||||||
|
if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct {
|
||||||
|
// Handle embedded struct pointers as embedded structs.
|
||||||
|
fieldVal = fieldVal.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
// If "squash" is specified in the tag, we squash the field down.
|
// If "squash" is specified in the tag, we squash the field down.
|
||||||
squash := false
|
squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous
|
||||||
|
remain := false
|
||||||
|
|
||||||
|
// We always parse the tags cause we're looking for other tags too
|
||||||
tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
|
tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
|
||||||
for _, tag := range tagParts[1:] {
|
for _, tag := range tagParts[1:] {
|
||||||
if tag == "squash" {
|
if tag == "squash" {
|
||||||
squash = true
|
squash = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tag == "remain" {
|
||||||
|
remain = true
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if squash {
|
if squash {
|
||||||
if fieldKind != reflect.Struct {
|
if fieldVal.Kind() != reflect.Struct {
|
||||||
errors = appendErrors(errors,
|
errors = appendErrors(errors,
|
||||||
fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
|
fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldVal.Kind()))
|
||||||
} else {
|
} else {
|
||||||
structs = append(structs, structVal.FieldByName(fieldType.Name))
|
structs = append(structs, fieldVal)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal struct field, store it away
|
// Build our field
|
||||||
fields = append(fields, field{fieldType, structVal.Field(i)})
|
if remain {
|
||||||
|
remainField = &field{fieldType, fieldVal}
|
||||||
|
} else {
|
||||||
|
// Normal struct field, store it away
|
||||||
|
fields = append(fields, field{fieldType, fieldVal})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1078,9 +1354,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the key we're using from the unused map so we stop tracking
|
|
||||||
delete(dataValKeysUnused, rawMapKey.Interface())
|
|
||||||
|
|
||||||
if !fieldValue.IsValid() {
|
if !fieldValue.IsValid() {
|
||||||
// This should never happen
|
// This should never happen
|
||||||
panic("field is not valid")
|
panic("field is not valid")
|
||||||
|
@ -1092,10 +1365,13 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete the key we're using from the unused map so we stop tracking
|
||||||
|
delete(dataValKeysUnused, rawMapKey.Interface())
|
||||||
|
|
||||||
// If the name is empty string, then we're at the root, and we
|
// If the name is empty string, then we're at the root, and we
|
||||||
// don't dot-join the fields.
|
// don't dot-join the fields.
|
||||||
if name != "" {
|
if name != "" {
|
||||||
fieldName = fmt.Sprintf("%s.%s", name, fieldName)
|
fieldName = name + "." + fieldName
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
|
if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
|
||||||
|
@ -1103,6 +1379,25 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a "remain"-tagged field and we have unused keys then
|
||||||
|
// we put the unused keys directly into the remain field.
|
||||||
|
if remainField != nil && len(dataValKeysUnused) > 0 {
|
||||||
|
// Build a map of only the unused values
|
||||||
|
remain := map[interface{}]interface{}{}
|
||||||
|
for key := range dataValKeysUnused {
|
||||||
|
remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode it as-if we were just decoding this map onto our map.
|
||||||
|
if err := d.decodeMap(name, remain, remainField.val); err != nil {
|
||||||
|
errors = appendErrors(errors, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the map to nil so we have none so that the next check will
|
||||||
|
// not error (ErrorUnused)
|
||||||
|
dataValKeysUnused = nil
|
||||||
|
}
|
||||||
|
|
||||||
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
|
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
|
||||||
keys := make([]string, 0, len(dataValKeysUnused))
|
keys := make([]string, 0, len(dataValKeysUnused))
|
||||||
for rawKey := range dataValKeysUnused {
|
for rawKey := range dataValKeysUnused {
|
||||||
|
@ -1123,7 +1418,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
for rawKey := range dataValKeysUnused {
|
for rawKey := range dataValKeysUnused {
|
||||||
key := rawKey.(string)
|
key := rawKey.(string)
|
||||||
if name != "" {
|
if name != "" {
|
||||||
key = fmt.Sprintf("%s.%s", name, key)
|
key = name + "." + key
|
||||||
}
|
}
|
||||||
|
|
||||||
d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
|
d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
|
||||||
|
@ -1133,6 +1428,24 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isEmptyValue(v reflect.Value) bool {
|
||||||
|
switch getKind(v) {
|
||||||
|
case reflect.Array, reflect.Map, reflect.Slice, 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.Ptr:
|
||||||
|
return v.IsNil()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func getKind(val reflect.Value) reflect.Kind {
|
func getKind(val reflect.Value) reflect.Kind {
|
||||||
kind := val.Kind()
|
kind := val.Kind()
|
||||||
|
|
||||||
|
|
2
vendor/github.com/pelletier/go-toml/.dockerignore
generated
vendored
Normal file
2
vendor/github.com/pelletier/go-toml/.dockerignore
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
cmd/tomll/tomll
|
||||||
|
cmd/tomljson/tomljson
|
3
vendor/github.com/pelletier/go-toml/.gitignore
generated
vendored
3
vendor/github.com/pelletier/go-toml/.gitignore
generated
vendored
|
@ -1,2 +1,5 @@
|
||||||
test_program/test_program_bin
|
test_program/test_program_bin
|
||||||
fuzz/
|
fuzz/
|
||||||
|
cmd/tomll/tomll
|
||||||
|
cmd/tomljson/tomljson
|
||||||
|
cmd/tomltestgen/tomltestgen
|
||||||
|
|
23
vendor/github.com/pelletier/go-toml/.travis.yml
generated
vendored
23
vendor/github.com/pelletier/go-toml/.travis.yml
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
sudo: false
|
|
||||||
language: go
|
|
||||||
go:
|
|
||||||
- 1.8.x
|
|
||||||
- 1.9.x
|
|
||||||
- 1.10.x
|
|
||||||
- tip
|
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- go: tip
|
|
||||||
fast_finish: true
|
|
||||||
script:
|
|
||||||
- if [ -n "$(go fmt ./...)" ]; then exit 1; fi
|
|
||||||
- ./test.sh
|
|
||||||
- ./benchmark.sh $TRAVIS_BRANCH https://github.com/$TRAVIS_REPO_SLUG.git
|
|
||||||
before_install:
|
|
||||||
- go get github.com/axw/gocov/gocov
|
|
||||||
- go get github.com/mattn/goveralls
|
|
||||||
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
|
||||||
branches:
|
|
||||||
only: [master]
|
|
||||||
after_success:
|
|
||||||
- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=coverage.out -repotoken $COVERALLS_TOKEN
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue