Browse Source

Tendermint <-> Application refactor

pull/164/head
Jae Kwon 9 years ago
parent
commit
ef43af19ab
401 changed files with 2400 additions and 76616 deletions
  1. +0
    -135
      Godeps/Godeps.json
  2. +0
    -5
      Godeps/Readme
  3. +0
    -2
      Godeps/_workspace/.gitignore
  4. +0
    -120
      Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160.go
  5. +0
    -64
      Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160_test.go
  6. +0
    -161
      Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160block.go
  7. +0
    -1411
      Godeps/_workspace/src/github.com/agl/ed25519/edwards25519/const.go
  8. +0
    -2127
      Godeps/_workspace/src/github.com/agl/ed25519/edwards25519/edwards25519.go
  9. +0
    -6
      Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml
  10. +0
    -21
      Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE
  11. +0
    -298
      Godeps/_workspace/src/github.com/codegangsta/cli/README.md
  12. +0
    -298
      Godeps/_workspace/src/github.com/codegangsta/cli/app.go
  13. +0
    -679
      Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go
  14. +0
    -13
      Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
  15. +0
    -5
      Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete
  16. +0
    -19
      Godeps/_workspace/src/github.com/codegangsta/cli/cli.go
  17. +0
    -100
      Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go
  18. +0
    -184
      Godeps/_workspace/src/github.com/codegangsta/cli/command.go
  19. +0
    -49
      Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go
  20. +0
    -344
      Godeps/_workspace/src/github.com/codegangsta/cli/context.go
  21. +0
    -111
      Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go
  22. +0
    -454
      Godeps/_workspace/src/github.com/codegangsta/cli/flag.go
  23. +0
    -742
      Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go
  24. +0
    -235
      Godeps/_workspace/src/github.com/codegangsta/cli/help.go
  25. +0
    -22
      Godeps/_workspace/src/github.com/codegangsta/cli/help_test.go
  26. +0
    -19
      Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go
  27. +0
    -22
      Godeps/_workspace/src/github.com/gorilla/websocket/.gitignore
  28. +0
    -6
      Godeps/_workspace/src/github.com/gorilla/websocket/.travis.yml
  29. +0
    -8
      Godeps/_workspace/src/github.com/gorilla/websocket/AUTHORS
  30. +0
    -22
      Godeps/_workspace/src/github.com/gorilla/websocket/LICENSE
  31. +0
    -59
      Godeps/_workspace/src/github.com/gorilla/websocket/README.md
  32. +0
    -19
      Godeps/_workspace/src/github.com/gorilla/websocket/bench_test.go
  33. +0
    -235
      Godeps/_workspace/src/github.com/gorilla/websocket/client.go
  34. +0
    -249
      Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go
  35. +0
    -63
      Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go
  36. +0
    -825
      Godeps/_workspace/src/github.com/gorilla/websocket/conn.go
  37. +0
    -238
      Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go
  38. +0
    -148
      Godeps/_workspace/src/github.com/gorilla/websocket/doc.go
  39. +0
    -13
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md
  40. +0
    -14
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
  41. +0
    -246
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go
  42. +0
    -19
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
  43. +0
    -106
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go
  44. +0
    -92
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/home.html
  45. +0
    -51
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/hub.go
  46. +0
    -39
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/main.go
  47. +0
    -9
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md
  48. +0
    -193
      Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go
  49. +0
    -49
      Godeps/_workspace/src/github.com/gorilla/websocket/json.go
  50. +0
    -63
      Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go
  51. +0
    -247
      Godeps/_workspace/src/github.com/gorilla/websocket/server.go
  52. +0
    -33
      Godeps/_workspace/src/github.com/gorilla/websocket/server_test.go
  53. +0
    -44
      Godeps/_workspace/src/github.com/gorilla/websocket/util.go
  54. +0
    -34
      Godeps/_workspace/src/github.com/gorilla/websocket/util_test.go
  55. +0
    -225
      Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack.go
  56. +0
    -19
      Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_pool.go
  57. +0
    -27
      Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_pool_chan.go
  58. +0
    -231
      Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_test.go
  59. +0
    -21
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/LICENSE
  60. +0
    -13
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_appengine.go
  61. +0
    -12
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_darwin.go
  62. +0
    -18
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_freebsd.go
  63. +0
    -14
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_linux.go
  64. +0
    -20
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_notwindows.go
  65. +0
    -26
      Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_windows.go
  66. +0
    -42
      Godeps/_workspace/src/github.com/mattn/go-colorable/README.md
  67. +0
    -16
      Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
  68. +0
    -594
      Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_windows.go
  69. +0
    -9
      Godeps/_workspace/src/github.com/naoina/go-stringutil/.travis.yml
  70. +0
    -19
      Godeps/_workspace/src/github.com/naoina/go-stringutil/LICENSE
  71. +0
    -13
      Godeps/_workspace/src/github.com/naoina/go-stringutil/README.md
  72. +0
    -120
      Godeps/_workspace/src/github.com/naoina/go-stringutil/strings.go
  73. +0
    -35
      Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go
  74. +0
    -88
      Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go
  75. +0
    -11
      Godeps/_workspace/src/github.com/naoina/toml/.travis.yml
  76. +0
    -19
      Godeps/_workspace/src/github.com/naoina/toml/LICENSE
  77. +0
    -16
      Godeps/_workspace/src/github.com/naoina/toml/Makefile
  78. +0
    -364
      Godeps/_workspace/src/github.com/naoina/toml/README.md
  79. +0
    -184
      Godeps/_workspace/src/github.com/naoina/toml/ast/ast.go
  80. +0
    -649
      Godeps/_workspace/src/github.com/naoina/toml/decode.go
  81. +0
    -49
      Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go
  82. +0
    -1083
      Godeps/_workspace/src/github.com/naoina/toml/decode_test.go
  83. +0
    -211
      Godeps/_workspace/src/github.com/naoina/toml/encode.go
  84. +0
    -298
      Godeps/_workspace/src/github.com/naoina/toml/encode_test.go
  85. +0
    -31
      Godeps/_workspace/src/github.com/naoina/toml/error.go
  86. +0
    -54
      Godeps/_workspace/src/github.com/naoina/toml/parse.go
  87. +0
    -138
      Godeps/_workspace/src/github.com/naoina/toml/parse.peg
  88. +0
    -3065
      Godeps/_workspace/src/github.com/naoina/toml/parse.peg.go
  89. +0
    -244
      Godeps/_workspace/src/github.com/naoina/toml/testdata/test.toml
  90. +0
    -79
      Godeps/_workspace/src/github.com/naoina/toml/util.go
  91. +0
    -9
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/LICENSE
  92. +0
    -65
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/README.md
  93. +0
    -57
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/gotwilio.go
  94. +0
    -54
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/gotwilio_test.go
  95. +0
    -112
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/sms.go
  96. +0
    -84
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/util.go
  97. +0
    -70
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/util_test.go
  98. +0
    -161
      Godeps/_workspace/src/github.com/sfreiberg/gotwilio/voice.go
  99. +0
    -8
      Godeps/_workspace/src/github.com/spf13/pflag/.travis.yml
  100. +0
    -28
      Godeps/_workspace/src/github.com/spf13/pflag/LICENSE

+ 0
- 135
Godeps/Godeps.json View File

@ -1,135 +0,0 @@
{
"ImportPath": "github.com/tendermint/tendermint",
"GoVersion": "go1.4.2",
"Packages": [
"./..."
],
"Deps": [
{
"ImportPath": "code.google.com/p/go.crypto/ripemd160",
"Comment": "null-236",
"Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e"
},
{
"ImportPath": "github.com/agl/ed25519/edwards25519",
"Rev": "d2b94fd789ea21d12fac1a4443dd3a3f79cda72c"
},
{
"ImportPath": "github.com/codegangsta/cli",
"Comment": "1.2.0-106-ga889873",
"Rev": "a889873af50a499d060097216dcdbcc26ed09e7c"
},
{
"ImportPath": "github.com/gorilla/websocket",
"Rev": "1f87405cd9755fc388e111c4003caca4a2f52fa6"
},
{
"ImportPath": "github.com/inconshreveable/log15/stack",
"Comment": "v2.3-38-g352fceb",
"Rev": "352fceb48e895bd1dd0b9f5d3ae8f8516c49af0f"
},
{
"ImportPath": "github.com/inconshreveable/log15/term",
"Comment": "v2.3-38-g352fceb",
"Rev": "352fceb48e895bd1dd0b9f5d3ae8f8516c49af0f"
},
{
"ImportPath": "github.com/mattn/go-colorable",
"Rev": "043ae16291351db8465272edf465c9f388161627"
},
{
"ImportPath": "github.com/naoina/go-stringutil",
"Rev": "360db0db4b01d34e12a2ec042c09e7d37fece761"
},
{
"ImportPath": "github.com/naoina/toml",
"Rev": "7b2dffbeaee47506726f29e36d19cf4ee90d361b"
},
{
"ImportPath": "github.com/sfreiberg/gotwilio",
"Rev": "b7230c284bd0c1614c94d00b9998c49f9a2737d8"
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "5644820622454e71517561946e3d94b9f9db6842"
},
{
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
"Rev": "63c9e642efad852f49e20a6f90194cae112fd2ac"
},
{
"ImportPath": "github.com/syndtr/gosnappy/snappy",
"Rev": "ce8acff4829e0c2458a67ead32390ac0a381c862"
},
{
"ImportPath": "github.com/tendermint/ed25519",
"Rev": "533fb6548e2071076888eda3c38749d707ba49bc"
},
{
"ImportPath": "github.com/tendermint/flowcontrol",
"Rev": "84d9671090430e8ec80e35b339907e0579b999eb"
},
{
"ImportPath": "github.com/tendermint/go-common",
"Rev": "6b54e7b8d945347f8fd1bdf83a2e9843561abbc5"
},
{
"ImportPath": "github.com/tendermint/go-config",
"Rev": "3b895c7ce4999ee6fff7b7ca6253f0b41d9bf85c"
},
{
"ImportPath": "github.com/tendermint/go-db",
"Rev": "28d39f8726c76b163e881c3d05dad227c93200ae"
},
{
"ImportPath": "github.com/tendermint/go-logger",
"Rev": "b072ed317354e6b507d6abde4c0cfbb516f31ab5"
},
{
"ImportPath": "github.com/tendermint/go-merkle",
"Rev": "8eab4cc2d55f17ff1529151ba2905015ad00e17d"
},
{
"ImportPath": "github.com/tendermint/go-p2p",
"Rev": "318a1b353532af2dcc430b9a7db976617fc729b8"
},
{
"ImportPath": "github.com/tendermint/go-wire",
"Rev": "4331183eb80dbaaedc9e84ab22e219c2d7d0bbe7"
},
{
"ImportPath": "github.com/tendermint/log15",
"Comment": "v2.3-36-g6e46075",
"Rev": "6e460758f10ef42a4724b8e4a82fee59aaa0e41d"
},
{
"ImportPath": "golang.org/x/crypto/curve25519",
"Rev": "02a186af8b62cb007f392270669b91be5527d39c"
},
{
"ImportPath": "golang.org/x/crypto/nacl/box",
"Rev": "02a186af8b62cb007f392270669b91be5527d39c"
},
{
"ImportPath": "golang.org/x/crypto/nacl/secretbox",
"Rev": "02a186af8b62cb007f392270669b91be5527d39c"
},
{
"ImportPath": "golang.org/x/crypto/poly1305",
"Rev": "02a186af8b62cb007f392270669b91be5527d39c"
},
{
"ImportPath": "golang.org/x/crypto/ripemd160",
"Rev": "02a186af8b62cb007f392270669b91be5527d39c"
},
{
"ImportPath": "golang.org/x/crypto/salsa20/salsa",
"Rev": "02a186af8b62cb007f392270669b91be5527d39c"
},
{
"ImportPath": "gopkg.in/fatih/set.v0",
"Comment": "v0.1.0-3-g27c4092",
"Rev": "27c40922c40b43fe04554d8223a402af3ea333f3"
}
]
}

+ 0
- 5
Godeps/Readme View File

@ -1,5 +0,0 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

+ 0
- 2
Godeps/_workspace/.gitignore View File

@ -1,2 +0,0 @@
/pkg
/bin

+ 0
- 120
Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160.go View File

@ -1,120 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package ripemd160 implements the RIPEMD-160 hash algorithm.
package ripemd160
// RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart
// Preneel with specifications available at:
// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf.
import (
"crypto"
"hash"
)
func init() {
crypto.RegisterHash(crypto.RIPEMD160, New)
}
// The size of the checksum in bytes.
const Size = 20
// The block size of the hash algorithm in bytes.
const BlockSize = 64
const (
_s0 = 0x67452301
_s1 = 0xefcdab89
_s2 = 0x98badcfe
_s3 = 0x10325476
_s4 = 0xc3d2e1f0
)
// digest represents the partial evaluation of a checksum.
type digest struct {
s [5]uint32 // running context
x [BlockSize]byte // temporary buffer
nx int // index into x
tc uint64 // total count of bytes processed
}
func (d *digest) Reset() {
d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4
d.nx = 0
d.tc = 0
}
// New returns a new hash.Hash computing the checksum.
func New() hash.Hash {
result := new(digest)
result.Reset()
return result
}
func (d *digest) Size() int { return Size }
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.tc += uint64(nn)
if d.nx > 0 {
n := len(p)
if n > BlockSize-d.nx {
n = BlockSize - d.nx
}
for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i]
}
d.nx += n
if d.nx == BlockSize {
_Block(d, d.x[0:])
d.nx = 0
}
p = p[n:]
}
n := _Block(d, p)
p = p[n:]
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := *d0
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
tc := d.tc
var tmp [64]byte
tmp[0] = 0x80
if tc%64 < 56 {
d.Write(tmp[0 : 56-tc%64])
} else {
d.Write(tmp[0 : 64+56-tc%64])
}
// Length in bits.
tc <<= 3
for i := uint(0); i < 8; i++ {
tmp[i] = byte(tc >> (8 * i))
}
d.Write(tmp[0:8])
if d.nx != 0 {
panic("d.nx != 0")
}
var digest [Size]byte
for i, s := range d.s {
digest[i*4] = byte(s)
digest[i*4+1] = byte(s >> 8)
digest[i*4+2] = byte(s >> 16)
digest[i*4+3] = byte(s >> 24)
}
return append(in, digest[:]...)
}

+ 0
- 64
Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160_test.go View File

@ -1,64 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ripemd160
// Test vectors are from:
// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
import (
"fmt"
"io"
"testing"
)
type mdTest struct {
out string
in string
}
var vectors = [...]mdTest{
{"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""},
{"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"},
{"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"},
{"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"},
{"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"},
{"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
{"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
{"9b752e45573d4b39f4dbd3323cab82bf63326bfb", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"},
}
func TestVectors(t *testing.T) {
for i := 0; i < len(vectors); i++ {
tv := vectors[i]
md := New()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(md, tv.in)
} else {
io.WriteString(md, tv.in[0:len(tv.in)/2])
md.Sum(nil)
io.WriteString(md, tv.in[len(tv.in)/2:])
}
s := fmt.Sprintf("%x", md.Sum(nil))
if s != tv.out {
t.Fatalf("RIPEMD-160[%d](%s) = %s, expected %s", j, tv.in, s, tv.out)
}
md.Reset()
}
}
}
func TestMillionA(t *testing.T) {
md := New()
for i := 0; i < 100000; i++ {
io.WriteString(md, "aaaaaaaaaa")
}
out := "52783243c1697bdbe16d37f97f68f08325dc1528"
s := fmt.Sprintf("%x", md.Sum(nil))
if s != out {
t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out)
}
md.Reset()
}

+ 0
- 161
Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160block.go View File

@ -1,161 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// RIPEMD-160 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
package ripemd160
// work buffer indices and roll amounts for one line
var _n = [80]uint{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
}
var _r = [80]uint{
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
}
// same for the other parallel one
var n_ = [80]uint{
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11,
}
var r_ = [80]uint{
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11,
}
func _Block(md *digest, p []byte) int {
n := 0
var x [16]uint32
var alpha, beta uint32
for len(p) >= BlockSize {
a, b, c, d, e := md.s[0], md.s[1], md.s[2], md.s[3], md.s[4]
aa, bb, cc, dd, ee := a, b, c, d, e
j := 0
for i := 0; i < 16; i++ {
x[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
j += 4
}
// round 1
i := 0
for i < 16 {
alpha = a + (b ^ c ^ d) + x[_n[i]]
s := _r[i]
alpha = (alpha<<s | alpha>>(32-s)) + e
beta = c<<10 | c>>22
a, b, c, d, e = e, alpha, b, beta, d
// parallel line
alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6
s = r_[i]
alpha = (alpha<<s | alpha>>(32-s)) + ee
beta = cc<<10 | cc>>22
aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
i++
}
// round 2
for i < 32 {
alpha = a + (b&c | ^b&d) + x[_n[i]] + 0x5a827999
s := _r[i]
alpha = (alpha<<s | alpha>>(32-s)) + e
beta = c<<10 | c>>22
a, b, c, d, e = e, alpha, b, beta, d
// parallel line
alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124
s = r_[i]
alpha = (alpha<<s | alpha>>(32-s)) + ee
beta = cc<<10 | cc>>22
aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
i++
}
// round 3
for i < 48 {
alpha = a + (b | ^c ^ d) + x[_n[i]] + 0x6ed9eba1
s := _r[i]
alpha = (alpha<<s | alpha>>(32-s)) + e
beta = c<<10 | c>>22
a, b, c, d, e = e, alpha, b, beta, d
// parallel line
alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3
s = r_[i]
alpha = (alpha<<s | alpha>>(32-s)) + ee
beta = cc<<10 | cc>>22
aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
i++
}
// round 4
for i < 64 {
alpha = a + (b&d | c&^d) + x[_n[i]] + 0x8f1bbcdc
s := _r[i]
alpha = (alpha<<s | alpha>>(32-s)) + e
beta = c<<10 | c>>22
a, b, c, d, e = e, alpha, b, beta, d
// parallel line
alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9
s = r_[i]
alpha = (alpha<<s | alpha>>(32-s)) + ee
beta = cc<<10 | cc>>22
aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
i++
}
// round 5
for i < 80 {
alpha = a + (b ^ (c | ^d)) + x[_n[i]] + 0xa953fd4e
s := _r[i]
alpha = (alpha<<s | alpha>>(32-s)) + e
beta = c<<10 | c>>22
a, b, c, d, e = e, alpha, b, beta, d
// parallel line
alpha = aa + (bb ^ cc ^ dd) + x[n_[i]]
s = r_[i]
alpha = (alpha<<s | alpha>>(32-s)) + ee
beta = cc<<10 | cc>>22
aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
i++
}
// combine results
dd += c + md.s[1]
md.s[1] = md.s[2] + d + ee
md.s[2] = md.s[3] + e + aa
md.s[3] = md.s[4] + a + bb
md.s[4] = md.s[0] + b + cc
md.s[0] = dd
p = p[BlockSize:]
n += BlockSize
}
return n
}

+ 0
- 1411
Godeps/_workspace/src/github.com/agl/ed25519/edwards25519/const.go
File diff suppressed because it is too large
View File


+ 0
- 2127
Godeps/_workspace/src/github.com/agl/ed25519/edwards25519/edwards25519.go
File diff suppressed because it is too large
View File


+ 0
- 6
Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml View File

@ -1,6 +0,0 @@
language: go
go: 1.1
script:
- go vet ./...
- go test -v ./...

+ 0
- 21
Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE View File

@ -1,21 +0,0 @@
Copyright (C) 2013 Jeremy Saenz
All Rights Reserved.
MIT LICENSE
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.

+ 0
- 298
Godeps/_workspace/src/github.com/codegangsta/cli/README.md View File

@ -1,298 +0,0 @@
[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli)
# cli.go
cli.go is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
You can view the API docs here:
http://godoc.org/github.com/codegangsta/cli
## Overview
Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
**This is where cli.go comes into play.** cli.go makes command line programming fun, organized, and expressive!
## Installation
Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html).
To install `cli.go`, simply run:
```
$ go get github.com/codegangsta/cli
```
Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used:
```
export PATH=$PATH:$GOPATH/bin
```
## Getting Started
One of the philosophies behind cli.go is that an API should be playful and full of discovery. So a cli.go app can be as little as one line of code in `main()`.
``` go
package main
import (
"os"
"github.com/codegangsta/cli"
)
func main() {
cli.NewApp().Run(os.Args)
}
```
This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation:
``` go
package main
import (
"os"
"github.com/codegangsta/cli"
)
func main() {
app := cli.NewApp()
app.Name = "boom"
app.Usage = "make an explosive entrance"
app.Action = func(c *cli.Context) {
println("boom! I say!")
}
app.Run(os.Args)
}
```
Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below.
## Example
Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness!
Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it:
``` go
package main
import (
"os"
"github.com/codegangsta/cli"
)
func main() {
app := cli.NewApp()
app.Name = "greet"
app.Usage = "fight the loneliness!"
app.Action = func(c *cli.Context) {
println("Hello friend!")
}
app.Run(os.Args)
}
```
Install our command to the `$GOPATH/bin` directory:
```
$ go install
```
Finally run our new command:
```
$ greet
Hello friend!
```
cli.go also generates some bitchass help text:
```
$ greet help
NAME:
greet - fight the loneliness!
USAGE:
greet [global options] command [command options] [arguments...]
VERSION:
0.0.0
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS
--version Shows version information
```
### Arguments
You can lookup arguments by calling the `Args` function on `cli.Context`.
``` go
...
app.Action = func(c *cli.Context) {
println("Hello", c.Args()[0])
}
...
```
### Flags
Setting and querying flags is simple.
``` go
...
app.Flags = []cli.Flag {
cli.StringFlag{
Name: "lang",
Value: "english",
Usage: "language for the greeting",
},
}
app.Action = func(c *cli.Context) {
name := "someone"
if len(c.Args()) > 0 {
name = c.Args()[0]
}
if c.String("lang") == "spanish" {
println("Hola", name)
} else {
println("Hello", name)
}
}
...
```
#### Alternate Names
You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g.
``` go
app.Flags = []cli.Flag {
cli.StringFlag{
Name: "lang, l",
Value: "english",
Usage: "language for the greeting",
},
}
```
That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error.
#### Values from the Environment
You can also have the default value set from the environment via `EnvVar`. e.g.
``` go
app.Flags = []cli.Flag {
cli.StringFlag{
Name: "lang, l",
Value: "english",
Usage: "language for the greeting",
EnvVar: "APP_LANG",
},
}
```
The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default.
``` go
app.Flags = []cli.Flag {
cli.StringFlag{
Name: "lang, l",
Value: "english",
Usage: "language for the greeting",
EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG",
},
}
```
### Subcommands
Subcommands can be defined for a more git-like command line app.
```go
...
app.Commands = []cli.Command{
{
Name: "add",
Aliases: []string{"a"},
Usage: "add a task to the list",
Action: func(c *cli.Context) {
println("added task: ", c.Args().First())
},
},
{
Name: "complete",
Aliases: []string{"c"},
Usage: "complete a task on the list",
Action: func(c *cli.Context) {
println("completed task: ", c.Args().First())
},
},
{
Name: "template",
Aliases: []string{"r"},
Usage: "options for task templates",
Subcommands: []cli.Command{
{
Name: "add",
Usage: "add a new template",
Action: func(c *cli.Context) {
println("new task template: ", c.Args().First())
},
},
{
Name: "remove",
Usage: "remove an existing template",
Action: func(c *cli.Context) {
println("removed task template: ", c.Args().First())
},
},
},
},
}
...
```
### Bash Completion
You can enable completion commands by setting the `EnableBashCompletion`
flag on the `App` object. By default, this setting will only auto-complete to
show an app's subcommands, but you can write your own completion methods for
the App or its subcommands.
```go
...
var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
app := cli.NewApp()
app.EnableBashCompletion = true
app.Commands = []cli.Command{
{
Name: "complete",
Aliases: []string{"c"},
Usage: "complete a task on the list",
Action: func(c *cli.Context) {
println("completed task: ", c.Args().First())
},
BashComplete: func(c *cli.Context) {
// This will complete if no args are passed
if len(c.Args()) > 0 {
return
}
for _, t := range tasks {
fmt.Println(t)
}
},
}
}
...
```
#### To Enable
Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while
setting the `PROG` variable to the name of your program:
`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete`
## Contribution Guidelines
Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch.
If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together.
If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out.

+ 0
- 298
Godeps/_workspace/src/github.com/codegangsta/cli/app.go View File

@ -1,298 +0,0 @@
package cli
import (
"fmt"
"io"
"io/ioutil"
"os"
"time"
)
// App is the main structure of a cli application. It is recomended that
// and app be created with the cli.NewApp() function
type App struct {
// The name of the program. Defaults to os.Args[0]
Name string
// Description of the program.
Usage string
// Version of the program
Version string
// List of commands to execute
Commands []Command
// List of flags to parse
Flags []Flag
// Boolean to enable bash completion commands
EnableBashCompletion bool
// Boolean to hide built-in help command
HideHelp bool
// Boolean to hide built-in version flag
HideVersion bool
// An action to execute when the bash-completion flag is set
BashComplete func(context *Context)
// An action to execute before any subcommands are run, but after the context is ready
// If a non-nil error is returned, no subcommands are run
Before func(context *Context) error
// An action to execute after any subcommands are run, but after the subcommand has finished
// It is run even if Action() panics
After func(context *Context) error
// The action to execute when no subcommands are specified
Action func(context *Context)
// Execute this function if the proper command cannot be found
CommandNotFound func(context *Context, command string)
// Compilation date
Compiled time.Time
// List of all authors who contributed
Authors []Author
// Name of Author (Note: Use App.Authors, this is deprecated)
Author string
// Email of Author (Note: Use App.Authors, this is deprecated)
Email string
// Writer writer to write output to
Writer io.Writer
}
// Tries to find out when this binary was compiled.
// Returns the current time if it fails to find it.
func compileTime() time.Time {
info, err := os.Stat(os.Args[0])
if err != nil {
return time.Now()
}
return info.ModTime()
}
// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
func NewApp() *App {
return &App{
Name: os.Args[0],
Usage: "A new cli application",
Version: "0.0.0",
BashComplete: DefaultAppComplete,
Action: helpCommand.Action,
Compiled: compileTime(),
Writer: os.Stdout,
}
}
// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
func (a *App) Run(arguments []string) (err error) {
if a.Author != "" || a.Email != "" {
a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email})
}
// append help to commands
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
a.Commands = append(a.Commands, helpCommand)
if (HelpFlag != BoolFlag{}) {
a.appendFlag(HelpFlag)
}
}
//append version/help flags
if a.EnableBashCompletion {
a.appendFlag(BashCompletionFlag)
}
if !a.HideVersion {
a.appendFlag(VersionFlag)
}
// parse flags
set := flagSet(a.Name, a.Flags)
set.SetOutput(ioutil.Discard)
err = set.Parse(arguments[1:])
nerr := normalizeFlags(a.Flags, set)
if nerr != nil {
fmt.Fprintln(a.Writer, nerr)
context := NewContext(a, set, set)
ShowAppHelp(context)
fmt.Fprintln(a.Writer)
return nerr
}
context := NewContext(a, set, set)
if err != nil {
fmt.Fprintf(a.Writer, "Incorrect Usage.\n\n")
ShowAppHelp(context)
fmt.Fprintln(a.Writer)
return err
}
if checkCompletions(context) {
return nil
}
if checkHelp(context) {
return nil
}
if checkVersion(context) {
return nil
}
if a.After != nil {
defer func() {
// err is always nil here.
// There is a check to see if it is non-nil
// just few lines before.
err = a.After(context)
}()
}
if a.Before != nil {
err := a.Before(context)
if err != nil {
return err
}
}
args := context.Args()
if args.Present() {
name := args.First()
c := a.Command(name)
if c != nil {
return c.Run(context)
}
}
// Run default Action
a.Action(context)
return nil
}
// Another entry point to the cli app, takes care of passing arguments and error handling
func (a *App) RunAndExitOnError() {
if err := a.Run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
// append help to commands
if len(a.Commands) > 0 {
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
a.Commands = append(a.Commands, helpCommand)
if (HelpFlag != BoolFlag{}) {
a.appendFlag(HelpFlag)
}
}
}
// append flags
if a.EnableBashCompletion {
a.appendFlag(BashCompletionFlag)
}
// parse flags
set := flagSet(a.Name, a.Flags)
set.SetOutput(ioutil.Discard)
err = set.Parse(ctx.Args().Tail())
nerr := normalizeFlags(a.Flags, set)
context := NewContext(a, set, ctx.globalSet)
if nerr != nil {
fmt.Fprintln(a.Writer, nerr)
if len(a.Commands) > 0 {
ShowSubcommandHelp(context)
} else {
ShowCommandHelp(ctx, context.Args().First())
}
fmt.Fprintln(a.Writer)
return nerr
}
if err != nil {
fmt.Fprintf(a.Writer, "Incorrect Usage.\n\n")
ShowSubcommandHelp(context)
return err
}
if checkCompletions(context) {
return nil
}
if len(a.Commands) > 0 {
if checkSubcommandHelp(context) {
return nil
}
} else {
if checkCommandHelp(ctx, context.Args().First()) {
return nil
}
}
if a.After != nil {
defer func() {
// err is always nil here.
// There is a check to see if it is non-nil
// just few lines before.
err = a.After(context)
}()
}
if a.Before != nil {
err := a.Before(context)
if err != nil {
return err
}
}
args := context.Args()
if args.Present() {
name := args.First()
c := a.Command(name)
if c != nil {
return c.Run(context)
}
}
// Run default Action
a.Action(context)
return nil
}
// Returns the named command on App. Returns nil if the command does not exist
func (a *App) Command(name string) *Command {
for _, c := range a.Commands {
if c.HasName(name) {
return &c
}
}
return nil
}
func (a *App) hasFlag(flag Flag) bool {
for _, f := range a.Flags {
if flag == f {
return true
}
}
return false
}
func (a *App) appendFlag(flag Flag) {
if !a.hasFlag(flag) {
a.Flags = append(a.Flags, flag)
}
}
// Author represents someone who has contributed to a cli project.
type Author struct {
Name string // The Authors name
Email string // The Authors email
}
// String makes Author comply to the Stringer interface, to allow an easy print in the templating process
func (a Author) String() string {
e := ""
if a.Email != "" {
e = "<" + a.Email + "> "
}
return fmt.Sprintf("%v %v", a.Name, e)
}

+ 0
- 679
Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go View File

@ -1,679 +0,0 @@
package cli_test
import (
"bytes"
"flag"
"fmt"
"io"
"os"
"strings"
"testing"
"github.com/codegangsta/cli"
)
func ExampleApp() {
// set args for examples sake
os.Args = []string{"greet", "--name", "Jeremy"}
app := cli.NewApp()
app.Name = "greet"
app.Flags = []cli.Flag{
cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
}
app.Action = func(c *cli.Context) {
fmt.Printf("Hello %v\n", c.String("name"))
}
app.Author = "Harrison"
app.Email = "harrison@lolwut.com"
app.Authors = []cli.Author{cli.Author{Name: "Oliver Allen", Email: "oliver@toyshop.com"}}
app.Run(os.Args)
// Output:
// Hello Jeremy
}
func ExampleAppSubcommand() {
// set args for examples sake
os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
app := cli.NewApp()
app.Name = "say"
app.Commands = []cli.Command{
{
Name: "hello",
Aliases: []string{"hi"},
Usage: "use it to see a description",
Description: "This is how we describe hello the function",
Subcommands: []cli.Command{
{
Name: "english",
Aliases: []string{"en"},
Usage: "sends a greeting in english",
Description: "greets someone in english",
Flags: []cli.Flag{
cli.StringFlag{
Name: "name",
Value: "Bob",
Usage: "Name of the person to greet",
},
},
Action: func(c *cli.Context) {
fmt.Println("Hello,", c.String("name"))
},
},
},
},
}
app.Run(os.Args)
// Output:
// Hello, Jeremy
}
func ExampleAppHelp() {
// set args for examples sake
os.Args = []string{"greet", "h", "describeit"}
app := cli.NewApp()
app.Name = "greet"
app.Flags = []cli.Flag{
cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
}
app.Commands = []cli.Command{
{
Name: "describeit",
Aliases: []string{"d"},
Usage: "use it to see a description",
Description: "This is how we describe describeit the function",
Action: func(c *cli.Context) {
fmt.Printf("i like to describe things")
},
},
}
app.Run(os.Args)
// Output:
// NAME:
// describeit - use it to see a description
//
// USAGE:
// command describeit [arguments...]
//
// DESCRIPTION:
// This is how we describe describeit the function
}
func ExampleAppBashComplete() {
// set args for examples sake
os.Args = []string{"greet", "--generate-bash-completion"}
app := cli.NewApp()
app.Name = "greet"
app.EnableBashCompletion = true
app.Commands = []cli.Command{
{
Name: "describeit",
Aliases: []string{"d"},
Usage: "use it to see a description",
Description: "This is how we describe describeit the function",
Action: func(c *cli.Context) {
fmt.Printf("i like to describe things")
},
}, {
Name: "next",
Usage: "next example",
Description: "more stuff to see when generating bash completion",
Action: func(c *cli.Context) {
fmt.Printf("the next example")
},
},
}
app.Run(os.Args)
// Output:
// describeit
// d
// next
// help
// h
}
func TestApp_Run(t *testing.T) {
s := ""
app := cli.NewApp()
app.Action = func(c *cli.Context) {
s = s + c.Args().First()
}
err := app.Run([]string{"command", "foo"})
expect(t, err, nil)
err = app.Run([]string{"command", "bar"})
expect(t, err, nil)
expect(t, s, "foobar")
}
var commandAppTests = []struct {
name string
expected bool
}{
{"foobar", true},
{"batbaz", true},
{"b", true},
{"f", true},
{"bat", false},
{"nothing", false},
}
func TestApp_Command(t *testing.T) {
app := cli.NewApp()
fooCommand := cli.Command{Name: "foobar", Aliases: []string{"f"}}
batCommand := cli.Command{Name: "batbaz", Aliases: []string{"b"}}
app.Commands = []cli.Command{
fooCommand,
batCommand,
}
for _, test := range commandAppTests {
expect(t, app.Command(test.name) != nil, test.expected)
}
}
func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
var parsedOption, firstArg string
app := cli.NewApp()
command := cli.Command{
Name: "cmd",
Flags: []cli.Flag{
cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
},
Action: func(c *cli.Context) {
parsedOption = c.String("option")
firstArg = c.Args().First()
},
}
app.Commands = []cli.Command{command}
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
expect(t, parsedOption, "my-option")
expect(t, firstArg, "my-arg")
}
func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
var context *cli.Context
a := cli.NewApp()
a.Commands = []cli.Command{
{
Name: "foo",
Action: func(c *cli.Context) {
context = c
},
Flags: []cli.Flag{
cli.StringFlag{
Name: "lang",
Value: "english",
Usage: "language for the greeting",
},
},
Before: func(_ *cli.Context) error { return nil },
},
}
a.Run([]string{"", "foo", "--lang", "spanish", "abcd"})
expect(t, context.Args().Get(0), "abcd")
expect(t, context.String("lang"), "spanish")
}
func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
var parsedOption string
var args []string
app := cli.NewApp()
command := cli.Command{
Name: "cmd",
Flags: []cli.Flag{
cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
},
Action: func(c *cli.Context) {
parsedOption = c.String("option")
args = c.Args()
},
}
app.Commands = []cli.Command{command}
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"})
expect(t, parsedOption, "my-option")
expect(t, args[0], "my-arg")
expect(t, args[1], "--")
expect(t, args[2], "--notARealFlag")
}
func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) {
var args []string
app := cli.NewApp()
command := cli.Command{
Name: "cmd",
Action: func(c *cli.Context) {
args = c.Args()
},
}
app.Commands = []cli.Command{command}
app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"})
expect(t, args[0], "my-arg")
expect(t, args[1], "--")
expect(t, args[2], "notAFlagAtAll")
}
func TestApp_Float64Flag(t *testing.T) {
var meters float64
app := cli.NewApp()
app.Flags = []cli.Flag{
cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
}
app.Action = func(c *cli.Context) {
meters = c.Float64("height")
}
app.Run([]string{"", "--height", "1.93"})
expect(t, meters, 1.93)
}
func TestApp_ParseSliceFlags(t *testing.T) {
var parsedOption, firstArg string
var parsedIntSlice []int
var parsedStringSlice []string
app := cli.NewApp()
command := cli.Command{
Name: "cmd",
Flags: []cli.Flag{
cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"},
cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"},
},
Action: func(c *cli.Context) {
parsedIntSlice = c.IntSlice("p")
parsedStringSlice = c.StringSlice("ip")
parsedOption = c.String("option")
firstArg = c.Args().First()
},
}
app.Commands = []cli.Command{command}
app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
IntsEquals := func(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
StrsEquals := func(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
var expectedIntSlice = []int{22, 80}
var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
if !IntsEquals(parsedIntSlice, expectedIntSlice) {
t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
}
if !StrsEquals(parsedStringSlice, expectedStringSlice) {
t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
}
}
func TestApp_DefaultStdout(t *testing.T) {
app := cli.NewApp()
if app.Writer != os.Stdout {
t.Error("Default output writer not set.")
}
}
type mockWriter struct {
written []byte
}
func (fw *mockWriter) Write(p []byte) (n int, err error) {
if fw.written == nil {
fw.written = p
} else {
fw.written = append(fw.written, p...)
}
return len(p), nil
}
func (fw *mockWriter) GetWritten() (b []byte) {
return fw.written
}
func TestApp_SetStdout(t *testing.T) {
w := &mockWriter{}
app := cli.NewApp()
app.Name = "test"
app.Writer = w
err := app.Run([]string{"help"})
if err != nil {
t.Fatalf("Run error: %s", err)
}
if len(w.written) == 0 {
t.Error("App did not write output to desired writer.")
}
}
func TestApp_BeforeFunc(t *testing.T) {
beforeRun, subcommandRun := false, false
beforeError := fmt.Errorf("fail")
var err error
app := cli.NewApp()
app.Before = func(c *cli.Context) error {
beforeRun = true
s := c.String("opt")
if s == "fail" {
return beforeError
}
return nil
}
app.Commands = []cli.Command{
cli.Command{
Name: "sub",
Action: func(c *cli.Context) {
subcommandRun = true
},
},
}
app.Flags = []cli.Flag{
cli.StringFlag{Name: "opt"},
}
// run with the Before() func succeeding
err = app.Run([]string{"command", "--opt", "succeed", "sub"})
if err != nil {
t.Fatalf("Run error: %s", err)
}
if beforeRun == false {
t.Errorf("Before() not executed when expected")
}
if subcommandRun == false {
t.Errorf("Subcommand not executed when expected")
}
// reset
beforeRun, subcommandRun = false, false
// run with the Before() func failing
err = app.Run([]string{"command", "--opt", "fail", "sub"})
// should be the same error produced by the Before func
if err != beforeError {
t.Errorf("Run error expected, but not received")
}
if beforeRun == false {
t.Errorf("Before() not executed when expected")
}
if subcommandRun == true {
t.Errorf("Subcommand executed when NOT expected")
}
}
func TestApp_AfterFunc(t *testing.T) {
afterRun, subcommandRun := false, false
afterError := fmt.Errorf("fail")
var err error
app := cli.NewApp()
app.After = func(c *cli.Context) error {
afterRun = true
s := c.String("opt")
if s == "fail" {
return afterError
}
return nil
}
app.Commands = []cli.Command{
cli.Command{
Name: "sub",
Action: func(c *cli.Context) {
subcommandRun = true
},
},
}
app.Flags = []cli.Flag{
cli.StringFlag{Name: "opt"},
}
// run with the After() func succeeding
err = app.Run([]string{"command", "--opt", "succeed", "sub"})
if err != nil {
t.Fatalf("Run error: %s", err)
}
if afterRun == false {
t.Errorf("After() not executed when expected")
}
if subcommandRun == false {
t.Errorf("Subcommand not executed when expected")
}
// reset
afterRun, subcommandRun = false, false
// run with the Before() func failing
err = app.Run([]string{"command", "--opt", "fail", "sub"})
// should be the same error produced by the Before func
if err != afterError {
t.Errorf("Run error expected, but not received")
}
if afterRun == false {
t.Errorf("After() not executed when expected")
}
if subcommandRun == false {
t.Errorf("Subcommand not executed when expected")
}
}
func TestAppNoHelpFlag(t *testing.T) {
oldFlag := cli.HelpFlag
defer func() {
cli.HelpFlag = oldFlag
}()
cli.HelpFlag = cli.BoolFlag{}
app := cli.NewApp()
err := app.Run([]string{"test", "-h"})
if err != flag.ErrHelp {
t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err)
}
}
func TestAppHelpPrinter(t *testing.T) {
oldPrinter := cli.HelpPrinter
defer func() {
cli.HelpPrinter = oldPrinter
}()
var wasCalled = false
cli.HelpPrinter = func(w io.Writer, template string, data interface{}) {
wasCalled = true
}
app := cli.NewApp()
app.Run([]string{"-h"})
if wasCalled == false {
t.Errorf("Help printer expected to be called, but was not")
}
}
func TestAppVersionPrinter(t *testing.T) {
oldPrinter := cli.VersionPrinter
defer func() {
cli.VersionPrinter = oldPrinter
}()
var wasCalled = false
cli.VersionPrinter = func(c *cli.Context) {
wasCalled = true
}
app := cli.NewApp()
ctx := cli.NewContext(app, nil, nil)
cli.ShowVersion(ctx)
if wasCalled == false {
t.Errorf("Version printer expected to be called, but was not")
}
}
func TestAppCommandNotFound(t *testing.T) {
beforeRun, subcommandRun := false, false
app := cli.NewApp()
app.CommandNotFound = func(c *cli.Context, command string) {
beforeRun = true
}
app.Commands = []cli.Command{
cli.Command{
Name: "bar",
Action: func(c *cli.Context) {
subcommandRun = true
},
},
}
app.Run([]string{"command", "foo"})
expect(t, beforeRun, true)
expect(t, subcommandRun, false)
}
func TestGlobalFlagsInSubcommands(t *testing.T) {
subcommandRun := false
app := cli.NewApp()
app.Flags = []cli.Flag{
cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
}
app.Commands = []cli.Command{
cli.Command{
Name: "foo",
Subcommands: []cli.Command{
{
Name: "bar",
Action: func(c *cli.Context) {
if c.GlobalBool("debug") {
subcommandRun = true
}
},
},
},
},
}
app.Run([]string{"command", "-d", "foo", "bar"})
expect(t, subcommandRun, true)
}
func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
var subcommandHelpTopics = [][]string{
{"command", "foo", "--help"},
{"command", "foo", "-h"},
{"command", "foo", "help"},
}
for _, flagSet := range subcommandHelpTopics {
t.Logf("==> checking with flags %v", flagSet)
app := cli.NewApp()
buf := new(bytes.Buffer)
app.Writer = buf
subCmdBar := cli.Command{
Name: "bar",
Usage: "does bar things",
}
subCmdBaz := cli.Command{
Name: "baz",
Usage: "does baz things",
}
cmd := cli.Command{
Name: "foo",
Description: "descriptive wall of text about how it does foo things",
Subcommands: []cli.Command{subCmdBar, subCmdBaz},
}
app.Commands = []cli.Command{cmd}
err := app.Run(flagSet)
if err != nil {
t.Error(err)
}
output := buf.String()
t.Logf("output: %q\n", buf.Bytes())
if strings.Contains(output, "No help topic for") {
t.Errorf("expect a help topic, got none: \n%q", output)
}
for _, shouldContain := range []string{
cmd.Name, cmd.Description,
subCmdBar.Name, subCmdBar.Usage,
subCmdBaz.Name, subCmdBaz.Usage,
} {
if !strings.Contains(output, shouldContain) {
t.Errorf("want help to contain %q, did not: \n%q", shouldContain, output)
}
}
}
}

+ 0
- 13
Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete View File

@ -1,13 +0,0 @@
#! /bin/bash
_cli_bash_autocomplete() {
local cur prev opts base
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _cli_bash_autocomplete $PROG

+ 0
- 5
Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete View File

@ -1,5 +0,0 @@
autoload -U compinit && compinit
autoload -U bashcompinit && bashcompinit
script_dir=$(dirname $0)
source ${script_dir}/bash_autocomplete

+ 0
- 19
Godeps/_workspace/src/github.com/codegangsta/cli/cli.go View File

@ -1,19 +0,0 @@
// Package cli provides a minimal framework for creating and organizing command line
// Go applications. cli is designed to be easy to understand and write, the most simple
// cli application can be written as follows:
// func main() {
// cli.NewApp().Run(os.Args)
// }
//
// Of course this application does not do much, so let's make this an actual application:
// func main() {
// app := cli.NewApp()
// app.Name = "greet"
// app.Usage = "say a greeting"
// app.Action = func(c *cli.Context) {
// println("Greetings")
// }
//
// app.Run(os.Args)
// }
package cli

+ 0
- 100
Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go View File

@ -1,100 +0,0 @@
package cli_test
import (
"os"
"github.com/codegangsta/cli"
)
func Example() {
app := cli.NewApp()
app.Name = "todo"
app.Usage = "task list on the command line"
app.Commands = []cli.Command{
{
Name: "add",
Aliases: []string{"a"},
Usage: "add a task to the list",
Action: func(c *cli.Context) {
println("added task: ", c.Args().First())
},
},
{
Name: "complete",
Aliases: []string{"c"},
Usage: "complete a task on the list",
Action: func(c *cli.Context) {
println("completed task: ", c.Args().First())
},
},
}
app.Run(os.Args)
}
func ExampleSubcommand() {
app := cli.NewApp()
app.Name = "say"
app.Commands = []cli.Command{
{
Name: "hello",
Aliases: []string{"hi"},
Usage: "use it to see a description",
Description: "This is how we describe hello the function",
Subcommands: []cli.Command{
{
Name: "english",
Aliases: []string{"en"},
Usage: "sends a greeting in english",
Description: "greets someone in english",
Flags: []cli.Flag{
cli.StringFlag{
Name: "name",
Value: "Bob",
Usage: "Name of the person to greet",
},
},
Action: func(c *cli.Context) {
println("Hello, ", c.String("name"))
},
}, {
Name: "spanish",
Aliases: []string{"sp"},
Usage: "sends a greeting in spanish",
Flags: []cli.Flag{
cli.StringFlag{
Name: "surname",
Value: "Jones",
Usage: "Surname of the person to greet",
},
},
Action: func(c *cli.Context) {
println("Hola, ", c.String("surname"))
},
}, {
Name: "french",
Aliases: []string{"fr"},
Usage: "sends a greeting in french",
Flags: []cli.Flag{
cli.StringFlag{
Name: "nickname",
Value: "Stevie",
Usage: "Nickname of the person to greet",
},
},
Action: func(c *cli.Context) {
println("Bonjour, ", c.String("nickname"))
},
},
},
}, {
Name: "bye",
Usage: "says goodbye",
Action: func(c *cli.Context) {
println("bye")
},
},
}
app.Run(os.Args)
}

+ 0
- 184
Godeps/_workspace/src/github.com/codegangsta/cli/command.go View File

@ -1,184 +0,0 @@
package cli
import (
"fmt"
"io/ioutil"
"strings"
)
// Command is a subcommand for a cli.App.
type Command struct {
// The name of the command
Name string
// short name of the command. Typically one character (deprecated, use `Aliases`)
ShortName string
// A list of aliases for the command
Aliases []string
// A short description of the usage of this command
Usage string
// A longer explanation of how the command works
Description string
// The function to call when checking for bash command completions
BashComplete func(context *Context)
// An action to execute before any sub-subcommands are run, but after the context is ready
// If a non-nil error is returned, no sub-subcommands are run
Before func(context *Context) error
// An action to execute after any subcommands are run, but after the subcommand has finished
// It is run even if Action() panics
After func(context *Context) error
// The function to call when this command is invoked
Action func(context *Context)
// List of child commands
Subcommands []Command
// List of flags to parse
Flags []Flag
// Treat all flags as normal arguments if true
SkipFlagParsing bool
// Boolean to hide built-in help command
HideHelp bool
}
// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
func (c Command) Run(ctx *Context) error {
if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil {
return c.startApp(ctx)
}
if !c.HideHelp && (HelpFlag != BoolFlag{}) {
// append help to flags
c.Flags = append(
c.Flags,
HelpFlag,
)
}
if ctx.App.EnableBashCompletion {
c.Flags = append(c.Flags, BashCompletionFlag)
}
set := flagSet(c.Name, c.Flags)
set.SetOutput(ioutil.Discard)
firstFlagIndex := -1
terminatorIndex := -1
for index, arg := range ctx.Args() {
if arg == "--" {
terminatorIndex = index
break
} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
firstFlagIndex = index
}
}
var err error
if firstFlagIndex > -1 && !c.SkipFlagParsing {
args := ctx.Args()
regularArgs := make([]string, len(args[1:firstFlagIndex]))
copy(regularArgs, args[1:firstFlagIndex])
var flagArgs []string
if terminatorIndex > -1 {
flagArgs = args[firstFlagIndex:terminatorIndex]
regularArgs = append(regularArgs, args[terminatorIndex:]...)
} else {
flagArgs = args[firstFlagIndex:]
}
err = set.Parse(append(flagArgs, regularArgs...))
} else {
err = set.Parse(ctx.Args().Tail())
}
if err != nil {
fmt.Fprint(ctx.App.Writer, "Incorrect Usage.\n\n")
ShowCommandHelp(ctx, c.Name)
fmt.Fprintln(ctx.App.Writer)
return err
}
nerr := normalizeFlags(c.Flags, set)
if nerr != nil {
fmt.Fprintln(ctx.App.Writer, nerr)
fmt.Fprintln(ctx.App.Writer)
ShowCommandHelp(ctx, c.Name)
fmt.Fprintln(ctx.App.Writer)
return nerr
}
context := NewContext(ctx.App, set, ctx.globalSet)
if checkCommandCompletions(context, c.Name) {
return nil
}
if checkCommandHelp(context, c.Name) {
return nil
}
context.Command = c
c.Action(context)
return nil
}
func (c Command) Names() []string {
names := []string{c.Name}
if c.ShortName != "" {
names = append(names, c.ShortName)
}
return append(names, c.Aliases...)
}
// Returns true if Command.Name or Command.ShortName matches given name
func (c Command) HasName(name string) bool {
for _, n := range c.Names() {
if n == name {
return true
}
}
return false
}
func (c Command) startApp(ctx *Context) error {
app := NewApp()
// set the name and usage
app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
if c.Description != "" {
app.Usage = c.Description
} else {
app.Usage = c.Usage
}
// set CommandNotFound
app.CommandNotFound = ctx.App.CommandNotFound
// set the flags and commands
app.Commands = c.Subcommands
app.Flags = c.Flags
app.HideHelp = c.HideHelp
app.Version = ctx.App.Version
app.HideVersion = ctx.App.HideVersion
app.Compiled = ctx.App.Compiled
app.Author = ctx.App.Author
app.Email = ctx.App.Email
app.Writer = ctx.App.Writer
// bash completion
app.EnableBashCompletion = ctx.App.EnableBashCompletion
if c.BashComplete != nil {
app.BashComplete = c.BashComplete
}
// set the actions
app.Before = c.Before
app.After = c.After
if c.Action != nil {
app.Action = c.Action
} else {
app.Action = helpSubcommand.Action
}
return app.RunAsSubcommand(ctx)
}

+ 0
- 49
Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go View File

@ -1,49 +0,0 @@
package cli_test
import (
"flag"
"testing"
"github.com/codegangsta/cli"
)
func TestCommandDoNotIgnoreFlags(t *testing.T) {
app := cli.NewApp()
set := flag.NewFlagSet("test", 0)
test := []string{"blah", "blah", "-break"}
set.Parse(test)
c := cli.NewContext(app, set, set)
command := cli.Command{
Name: "test-cmd",
Aliases: []string{"tc"},
Usage: "this is for testing",
Description: "testing",
Action: func(_ *cli.Context) {},
}
err := command.Run(c)
expect(t, err.Error(), "flag provided but not defined: -break")
}
func TestCommandIgnoreFlags(t *testing.T) {
app := cli.NewApp()
set := flag.NewFlagSet("test", 0)
test := []string{"blah", "blah"}
set.Parse(test)
c := cli.NewContext(app, set, set)
command := cli.Command{
Name: "test-cmd",
Aliases: []string{"tc"},
Usage: "this is for testing",
Description: "testing",
Action: func(_ *cli.Context) {},
SkipFlagParsing: true,
}
err := command.Run(c)
expect(t, err, nil)
}

+ 0
- 344
Godeps/_workspace/src/github.com/codegangsta/cli/context.go View File

@ -1,344 +0,0 @@
package cli
import (
"errors"
"flag"
"strconv"
"strings"
"time"
)
// Context is a type that is passed through to
// each Handler action in a cli application. Context
// can be used to retrieve context-specific Args and
// parsed command-line options.
type Context struct {
App *App
Command Command
flagSet *flag.FlagSet
globalSet *flag.FlagSet
setFlags map[string]bool
globalSetFlags map[string]bool
}
// Creates a new context. For use in when invoking an App or Command action.
func NewContext(app *App, set *flag.FlagSet, globalSet *flag.FlagSet) *Context {
return &Context{App: app, flagSet: set, globalSet: globalSet}
}
// Looks up the value of a local int flag, returns 0 if no int flag exists
func (c *Context) Int(name string) int {
return lookupInt(name, c.flagSet)
}
// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists
func (c *Context) Duration(name string) time.Duration {
return lookupDuration(name, c.flagSet)
}
// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists
func (c *Context) Float64(name string) float64 {
return lookupFloat64(name, c.flagSet)
}
// Looks up the value of a local bool flag, returns false if no bool flag exists
func (c *Context) Bool(name string) bool {
return lookupBool(name, c.flagSet)
}
// Looks up the value of a local boolT flag, returns false if no bool flag exists
func (c *Context) BoolT(name string) bool {
return lookupBoolT(name, c.flagSet)
}
// Looks up the value of a local string flag, returns "" if no string flag exists
func (c *Context) String(name string) string {
return lookupString(name, c.flagSet)
}
// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
func (c *Context) StringSlice(name string) []string {
return lookupStringSlice(name, c.flagSet)
}
// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
func (c *Context) IntSlice(name string) []int {
return lookupIntSlice(name, c.flagSet)
}
// Looks up the value of a local generic flag, returns nil if no generic flag exists
func (c *Context) Generic(name string) interface{} {
return lookupGeneric(name, c.flagSet)
}
// Looks up the value of a global int flag, returns 0 if no int flag exists
func (c *Context) GlobalInt(name string) int {
return lookupInt(name, c.globalSet)
}
// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists
func (c *Context) GlobalDuration(name string) time.Duration {
return lookupDuration(name, c.globalSet)
}
// Looks up the value of a global bool flag, returns false if no bool flag exists
func (c *Context) GlobalBool(name string) bool {
return lookupBool(name, c.globalSet)
}
// Looks up the value of a global string flag, returns "" if no string flag exists
func (c *Context) GlobalString(name string) string {
return lookupString(name, c.globalSet)
}
// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
func (c *Context) GlobalStringSlice(name string) []string {
return lookupStringSlice(name, c.globalSet)
}
// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
func (c *Context) GlobalIntSlice(name string) []int {
return lookupIntSlice(name, c.globalSet)
}
// Looks up the value of a global generic flag, returns nil if no generic flag exists
func (c *Context) GlobalGeneric(name string) interface{} {
return lookupGeneric(name, c.globalSet)
}
// Returns the number of flags set
func (c *Context) NumFlags() int {
return c.flagSet.NFlag()
}
// Determines if the flag was actually set
func (c *Context) IsSet(name string) bool {
if c.setFlags == nil {
c.setFlags = make(map[string]bool)
c.flagSet.Visit(func(f *flag.Flag) {
c.setFlags[f.Name] = true
})
}
return c.setFlags[name] == true
}
// Determines if the global flag was actually set
func (c *Context) GlobalIsSet(name string) bool {
if c.globalSetFlags == nil {
c.globalSetFlags = make(map[string]bool)
c.globalSet.Visit(func(f *flag.Flag) {
c.globalSetFlags[f.Name] = true
})
}
return c.globalSetFlags[name] == true
}
// Returns a slice of flag names used in this context.
func (c *Context) FlagNames() (names []string) {
for _, flag := range c.Command.Flags {
name := strings.Split(flag.getName(), ",")[0]
if name == "help" {
continue
}
names = append(names, name)
}
return
}
// Returns a slice of global flag names used by the app.
func (c *Context) GlobalFlagNames() (names []string) {
for _, flag := range c.App.Flags {
name := strings.Split(flag.getName(), ",")[0]
if name == "help" || name == "version" {
continue
}
names = append(names, name)
}
return
}
type Args []string
// Returns the command line arguments associated with the context.
func (c *Context) Args() Args {
args := Args(c.flagSet.Args())
return args
}
// Returns the nth argument, or else a blank string
func (a Args) Get(n int) string {
if len(a) > n {
return a[n]
}
return ""
}
// Returns the first argument, or else a blank string
func (a Args) First() string {
return a.Get(0)
}
// Return the rest of the arguments (not the first one)
// or else an empty string slice
func (a Args) Tail() []string {
if len(a) >= 2 {
return []string(a)[1:]
}
return []string{}
}
// Checks if there are any arguments present
func (a Args) Present() bool {
return len(a) != 0
}
// Swaps arguments at the given indexes
func (a Args) Swap(from, to int) error {
if from >= len(a) || to >= len(a) {
return errors.New("index out of range")
}
a[from], a[to] = a[to], a[from]
return nil
}
func lookupInt(name string, set *flag.FlagSet) int {
f := set.Lookup(name)
if f != nil {
val, err := strconv.Atoi(f.Value.String())
if err != nil {
return 0
}
return val
}
return 0
}
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
f := set.Lookup(name)
if f != nil {
val, err := time.ParseDuration(f.Value.String())
if err == nil {
return val
}
}
return 0
}
func lookupFloat64(name string, set *flag.FlagSet) float64 {
f := set.Lookup(name)
if f != nil {
val, err := strconv.ParseFloat(f.Value.String(), 64)
if err != nil {
return 0
}
return val
}
return 0
}
func lookupString(name string, set *flag.FlagSet) string {
f := set.Lookup(name)
if f != nil {
return f.Value.String()
}
return ""
}
func lookupStringSlice(name string, set *flag.FlagSet) []string {
f := set.Lookup(name)
if f != nil {
return (f.Value.(*StringSlice)).Value()
}
return nil
}
func lookupIntSlice(name string, set *flag.FlagSet) []int {
f := set.Lookup(name)
if f != nil {
return (f.Value.(*IntSlice)).Value()
}
return nil
}
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
f := set.Lookup(name)
if f != nil {
return f.Value
}
return nil
}
func lookupBool(name string, set *flag.FlagSet) bool {
f := set.Lookup(name)
if f != nil {
val, err := strconv.ParseBool(f.Value.String())
if err != nil {
return false
}
return val
}
return false
}
func lookupBoolT(name string, set *flag.FlagSet) bool {
f := set.Lookup(name)
if f != nil {
val, err := strconv.ParseBool(f.Value.String())
if err != nil {
return true
}
return val
}
return false
}
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
switch ff.Value.(type) {
case *StringSlice:
default:
set.Set(name, ff.Value.String())
}
}
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
visited := make(map[string]bool)
set.Visit(func(f *flag.Flag) {
visited[f.Name] = true
})
for _, f := range flags {
parts := strings.Split(f.getName(), ",")
if len(parts) == 1 {
continue
}
var ff *flag.Flag
for _, name := range parts {
name = strings.Trim(name, " ")
if visited[name] {
if ff != nil {
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
}
ff = set.Lookup(name)
}
}
if ff == nil {
continue
}
for _, name := range parts {
name = strings.Trim(name, " ")
if !visited[name] {
copyFlag(name, ff, set)
}
}
}
return nil
}

+ 0
- 111
Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go View File

@ -1,111 +0,0 @@
package cli_test
import (
"flag"
"testing"
"time"
"github.com/codegangsta/cli"
)
func TestNewContext(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Int("myflag", 12, "doc")
globalSet := flag.NewFlagSet("test", 0)
globalSet.Int("myflag", 42, "doc")
command := cli.Command{Name: "mycommand"}
c := cli.NewContext(nil, set, globalSet)
c.Command = command
expect(t, c.Int("myflag"), 12)
expect(t, c.GlobalInt("myflag"), 42)
expect(t, c.Command.Name, "mycommand")
}
func TestContext_Int(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Int("myflag", 12, "doc")
c := cli.NewContext(nil, set, set)
expect(t, c.Int("myflag"), 12)
}
func TestContext_Duration(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Duration("myflag", time.Duration(12*time.Second), "doc")
c := cli.NewContext(nil, set, set)
expect(t, c.Duration("myflag"), time.Duration(12*time.Second))
}
func TestContext_String(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.String("myflag", "hello world", "doc")
c := cli.NewContext(nil, set, set)
expect(t, c.String("myflag"), "hello world")
}
func TestContext_Bool(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", false, "doc")
c := cli.NewContext(nil, set, set)
expect(t, c.Bool("myflag"), false)
}
func TestContext_BoolT(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", true, "doc")
c := cli.NewContext(nil, set, set)
expect(t, c.BoolT("myflag"), true)
}
func TestContext_Args(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", false, "doc")
c := cli.NewContext(nil, set, set)
set.Parse([]string{"--myflag", "bat", "baz"})
expect(t, len(c.Args()), 2)
expect(t, c.Bool("myflag"), true)
}
func TestContext_IsSet(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", false, "doc")
set.String("otherflag", "hello world", "doc")
globalSet := flag.NewFlagSet("test", 0)
globalSet.Bool("myflagGlobal", true, "doc")
c := cli.NewContext(nil, set, globalSet)
set.Parse([]string{"--myflag", "bat", "baz"})
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
expect(t, c.IsSet("myflag"), true)
expect(t, c.IsSet("otherflag"), false)
expect(t, c.IsSet("bogusflag"), false)
expect(t, c.IsSet("myflagGlobal"), false)
}
func TestContext_GlobalIsSet(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", false, "doc")
set.String("otherflag", "hello world", "doc")
globalSet := flag.NewFlagSet("test", 0)
globalSet.Bool("myflagGlobal", true, "doc")
globalSet.Bool("myflagGlobalUnset", true, "doc")
c := cli.NewContext(nil, set, globalSet)
set.Parse([]string{"--myflag", "bat", "baz"})
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
expect(t, c.GlobalIsSet("myflag"), false)
expect(t, c.GlobalIsSet("otherflag"), false)
expect(t, c.GlobalIsSet("bogusflag"), false)
expect(t, c.GlobalIsSet("myflagGlobal"), true)
expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
expect(t, c.GlobalIsSet("bogusGlobal"), false)
}
func TestContext_NumFlags(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", false, "doc")
set.String("otherflag", "hello world", "doc")
globalSet := flag.NewFlagSet("test", 0)
globalSet.Bool("myflagGlobal", true, "doc")
c := cli.NewContext(nil, set, globalSet)
set.Parse([]string{"--myflag", "--otherflag=foo"})
globalSet.Parse([]string{"--myflagGlobal"})
expect(t, c.NumFlags(), 2)
}

+ 0
- 454
Godeps/_workspace/src/github.com/codegangsta/cli/flag.go View File

@ -1,454 +0,0 @@
package cli
import (
"flag"
"fmt"
"os"
"strconv"
"strings"
"time"
)
// This flag enables bash-completion for all commands and subcommands
var BashCompletionFlag = BoolFlag{
Name: "generate-bash-completion",
}
// This flag prints the version for the application
var VersionFlag = BoolFlag{
Name: "version, v",
Usage: "print the version",
}
// This flag prints the help for all commands and subcommands
// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
// unless HideHelp is set to true)
var HelpFlag = BoolFlag{
Name: "help, h",
Usage: "show help",
}
// Flag is a common interface related to parsing flags in cli.
// For more advanced flag parsing techniques, it is recomended that
// this interface be implemented.
type Flag interface {
fmt.Stringer
// Apply Flag settings to the given flag set
Apply(*flag.FlagSet)
getName() string
}
func flagSet(name string, flags []Flag) *flag.FlagSet {
set := flag.NewFlagSet(name, flag.ContinueOnError)
for _, f := range flags {
f.Apply(set)
}
return set
}
func eachName(longName string, fn func(string)) {
parts := strings.Split(longName, ",")
for _, name := range parts {
name = strings.Trim(name, " ")
fn(name)
}
}
// Generic is a generic parseable type identified by a specific flag
type Generic interface {
Set(value string) error
String() string
}
// GenericFlag is the flag type for types implementing Generic
type GenericFlag struct {
Name string
Value Generic
Usage string
EnvVar string
}
// String returns the string representation of the generic flag to display the
// help text to the user (uses the String() method of the generic flag to show
// the value)
func (f GenericFlag) String() string {
return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s \"%v\"\t%v", prefixFor(f.Name), f.Name, f.Value, f.Usage))
}
// Apply takes the flagset and calls Set on the generic flag with the value
// provided by the user for parsing by the flag
func (f GenericFlag) Apply(set *flag.FlagSet) {
val := f.Value
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
val.Set(envVal)
break
}
}
}
eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage)
})
}
func (f GenericFlag) getName() string {
return f.Name
}
type StringSlice []string
func (f *StringSlice) Set(value string) error {
*f = append(*f, value)
return nil
}
func (f *StringSlice) String() string {
return fmt.Sprintf("%s", *f)
}
func (f *StringSlice) Value() []string {
return *f
}
type StringSliceFlag struct {
Name string
Value *StringSlice
Usage string
EnvVar string
}
func (f StringSliceFlag) String() string {
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
pref := prefixFor(firstName)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
}
func (f StringSliceFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
newVal := &StringSlice{}
for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s)
newVal.Set(s)
}
f.Value = newVal
break
}
}
}
eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage)
})
}
func (f StringSliceFlag) getName() string {
return f.Name
}
type IntSlice []int
func (f *IntSlice) Set(value string) error {
tmp, err := strconv.Atoi(value)
if err != nil {
return err
} else {
*f = append(*f, tmp)
}
return nil
}
func (f *IntSlice) String() string {
return fmt.Sprintf("%d", *f)
}
func (f *IntSlice) Value() []int {
return *f
}
type IntSliceFlag struct {
Name string
Value *IntSlice
Usage string
EnvVar string
}
func (f IntSliceFlag) String() string {
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
pref := prefixFor(firstName)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
}
func (f IntSliceFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
newVal := &IntSlice{}
for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s)
err := newVal.Set(s)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
}
}
f.Value = newVal
break
}
}
}
eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage)
})
}
func (f IntSliceFlag) getName() string {
return f.Name
}
type BoolFlag struct {
Name string
Usage string
EnvVar string
}
func (f BoolFlag) String() string {
return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
}
func (f BoolFlag) Apply(set *flag.FlagSet) {
val := false
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
envValBool, err := strconv.ParseBool(envVal)
if err == nil {
val = envValBool
}
break
}
}
}
eachName(f.Name, func(name string) {
set.Bool(name, val, f.Usage)
})
}
func (f BoolFlag) getName() string {
return f.Name
}
type BoolTFlag struct {
Name string
Usage string
EnvVar string
}
func (f BoolTFlag) String() string {
return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
}
func (f BoolTFlag) Apply(set *flag.FlagSet) {
val := true
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
envValBool, err := strconv.ParseBool(envVal)
if err == nil {
val = envValBool
break
}
}
}
}
eachName(f.Name, func(name string) {
set.Bool(name, val, f.Usage)
})
}
func (f BoolTFlag) getName() string {
return f.Name
}
type StringFlag struct {
Name string
Value string
Usage string
EnvVar string
}
func (f StringFlag) String() string {
var fmtString string
fmtString = "%s %v\t%v"
if len(f.Value) > 0 {
fmtString = "%s \"%v\"\t%v"
} else {
fmtString = "%s %v\t%v"
}
return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage))
}
func (f StringFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
f.Value = envVal
break
}
}
}
eachName(f.Name, func(name string) {
set.String(name, f.Value, f.Usage)
})
}
func (f StringFlag) getName() string {
return f.Name
}
type IntFlag struct {
Name string
Value int
Usage string
EnvVar string
}
func (f IntFlag) String() string {
return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
}
func (f IntFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
envValInt, err := strconv.ParseInt(envVal, 0, 64)
if err == nil {
f.Value = int(envValInt)
break
}
}
}
}
eachName(f.Name, func(name string) {
set.Int(name, f.Value, f.Usage)
})
}
func (f IntFlag) getName() string {
return f.Name
}
type DurationFlag struct {
Name string
Value time.Duration
Usage string
EnvVar string
}
func (f DurationFlag) String() string {
return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
}
func (f DurationFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
envValDuration, err := time.ParseDuration(envVal)
if err == nil {
f.Value = envValDuration
break
}
}
}
}
eachName(f.Name, func(name string) {
set.Duration(name, f.Value, f.Usage)
})
}
func (f DurationFlag) getName() string {
return f.Name
}
type Float64Flag struct {
Name string
Value float64
Usage string
EnvVar string
}
func (f Float64Flag) String() string {
return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
}
func (f Float64Flag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
for _, envVar := range strings.Split(f.EnvVar, ",") {
envVar = strings.TrimSpace(envVar)
if envVal := os.Getenv(envVar); envVal != "" {
envValFloat, err := strconv.ParseFloat(envVal, 10)
if err == nil {
f.Value = float64(envValFloat)
}
}
}
}
eachName(f.Name, func(name string) {
set.Float64(name, f.Value, f.Usage)
})
}
func (f Float64Flag) getName() string {
return f.Name
}
func prefixFor(name string) (prefix string) {
if len(name) == 1 {
prefix = "-"
} else {
prefix = "--"
}
return
}
func prefixedNames(fullName string) (prefixed string) {
parts := strings.Split(fullName, ",")
for i, name := range parts {
name = strings.Trim(name, " ")
prefixed += prefixFor(name) + name
if i < len(parts)-1 {
prefixed += ", "
}
}
return
}
func withEnvHint(envVar, str string) string {
envText := ""
if envVar != "" {
envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $"))
}
return str + envText
}

+ 0
- 742
Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go View File

@ -1,742 +0,0 @@
package cli_test
import (
"fmt"
"os"
"reflect"
"strings"
"testing"
"github.com/codegangsta/cli"
)
var boolFlagTests = []struct {
name string
expected string
}{
{"help", "--help\t"},
{"h", "-h\t"},
}
func TestBoolFlagHelpOutput(t *testing.T) {
for _, test := range boolFlagTests {
flag := cli.BoolFlag{Name: test.name}
output := flag.String()
if output != test.expected {
t.Errorf("%s does not match %s", output, test.expected)
}
}
}
var stringFlagTests = []struct {
name string
value string
expected string
}{
{"help", "", "--help \t"},
{"h", "", "-h \t"},
{"h", "", "-h \t"},
{"test", "Something", "--test \"Something\"\t"},
}
func TestStringFlagHelpOutput(t *testing.T) {
for _, test := range stringFlagTests {
flag := cli.StringFlag{Name: test.name, Value: test.value}
output := flag.String()
if output != test.expected {
t.Errorf("%s does not match %s", output, test.expected)
}
}
}
func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_FOO", "derp")
for _, test := range stringFlagTests {
flag := cli.StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_FOO]") {
t.Errorf("%s does not end with [$APP_FOO]", output)
}
}
}
var stringSliceFlagTests = []struct {
name string
value *cli.StringSlice
expected string
}{
{"help", func() *cli.StringSlice {
s := &cli.StringSlice{}
s.Set("")
return s
}(), "--help [--help option --help option]\t"},
{"h", func() *cli.StringSlice {
s := &cli.StringSlice{}
s.Set("")
return s
}(), "-h [-h option -h option]\t"},
{"h", func() *cli.StringSlice {
s := &cli.StringSlice{}
s.Set("")
return s
}(), "-h [-h option -h option]\t"},
{"test", func() *cli.StringSlice {
s := &cli.StringSlice{}
s.Set("Something")
return s
}(), "--test [--test option --test option]\t"},
}
func TestStringSliceFlagHelpOutput(t *testing.T) {
for _, test := range stringSliceFlagTests {
flag := cli.StringSliceFlag{Name: test.name, Value: test.value}
output := flag.String()
if output != test.expected {
t.Errorf("%q does not match %q", output, test.expected)
}
}
}
func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_QWWX", "11,4")
for _, test := range stringSliceFlagTests {
flag := cli.StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_QWWX]") {
t.Errorf("%q does not end with [$APP_QWWX]", output)
}
}
}
var intFlagTests = []struct {
name string
expected string
}{
{"help", "--help \"0\"\t"},
{"h", "-h \"0\"\t"},
}
func TestIntFlagHelpOutput(t *testing.T) {
for _, test := range intFlagTests {
flag := cli.IntFlag{Name: test.name}
output := flag.String()
if output != test.expected {
t.Errorf("%s does not match %s", output, test.expected)
}
}
}
func TestIntFlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_BAR", "2")
for _, test := range intFlagTests {
flag := cli.IntFlag{Name: test.name, EnvVar: "APP_BAR"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_BAR]") {
t.Errorf("%s does not end with [$APP_BAR]", output)
}
}
}
var durationFlagTests = []struct {
name string
expected string
}{
{"help", "--help \"0\"\t"},
{"h", "-h \"0\"\t"},
}
func TestDurationFlagHelpOutput(t *testing.T) {
for _, test := range durationFlagTests {
flag := cli.DurationFlag{Name: test.name}
output := flag.String()
if output != test.expected {
t.Errorf("%s does not match %s", output, test.expected)
}
}
}
func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_BAR", "2h3m6s")
for _, test := range durationFlagTests {
flag := cli.DurationFlag{Name: test.name, EnvVar: "APP_BAR"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_BAR]") {
t.Errorf("%s does not end with [$APP_BAR]", output)
}
}
}
var intSliceFlagTests = []struct {
name string
value *cli.IntSlice
expected string
}{
{"help", &cli.IntSlice{}, "--help [--help option --help option]\t"},
{"h", &cli.IntSlice{}, "-h [-h option -h option]\t"},
{"h", &cli.IntSlice{}, "-h [-h option -h option]\t"},
{"test", func() *cli.IntSlice {
i := &cli.IntSlice{}
i.Set("9")
return i
}(), "--test [--test option --test option]\t"},
}
func TestIntSliceFlagHelpOutput(t *testing.T) {
for _, test := range intSliceFlagTests {
flag := cli.IntSliceFlag{Name: test.name, Value: test.value}
output := flag.String()
if output != test.expected {
t.Errorf("%q does not match %q", output, test.expected)
}
}
}
func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_SMURF", "42,3")
for _, test := range intSliceFlagTests {
flag := cli.IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_SMURF]") {
t.Errorf("%q does not end with [$APP_SMURF]", output)
}
}
}
var float64FlagTests = []struct {
name string
expected string
}{
{"help", "--help \"0\"\t"},
{"h", "-h \"0\"\t"},
}
func TestFloat64FlagHelpOutput(t *testing.T) {
for _, test := range float64FlagTests {
flag := cli.Float64Flag{Name: test.name}
output := flag.String()
if output != test.expected {
t.Errorf("%s does not match %s", output, test.expected)
}
}
}
func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_BAZ", "99.4")
for _, test := range float64FlagTests {
flag := cli.Float64Flag{Name: test.name, EnvVar: "APP_BAZ"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_BAZ]") {
t.Errorf("%s does not end with [$APP_BAZ]", output)
}
}
}
var genericFlagTests = []struct {
name string
value cli.Generic
expected string
}{
{"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"},
{"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"},
}
func TestGenericFlagHelpOutput(t *testing.T) {
for _, test := range genericFlagTests {
flag := cli.GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"}
output := flag.String()
if output != test.expected {
t.Errorf("%q does not match %q", output, test.expected)
}
}
}
func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) {
os.Clearenv()
os.Setenv("APP_ZAP", "3")
for _, test := range genericFlagTests {
flag := cli.GenericFlag{Name: test.name, EnvVar: "APP_ZAP"}
output := flag.String()
if !strings.HasSuffix(output, " [$APP_ZAP]") {
t.Errorf("%s does not end with [$APP_ZAP]", output)
}
}
}
func TestParseMultiString(t *testing.T) {
(&cli.App{
Flags: []cli.Flag{
cli.StringFlag{Name: "serve, s"},
},
Action: func(ctx *cli.Context) {
if ctx.String("serve") != "10" {
t.Errorf("main name not set")
}
if ctx.String("s") != "10" {
t.Errorf("short name not set")
}
},
}).Run([]string{"run", "-s", "10"})
}
func TestParseMultiStringFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_COUNT", "20")
(&cli.App{
Flags: []cli.Flag{
cli.StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
},
Action: func(ctx *cli.Context) {
if ctx.String("count") != "20" {
t.Errorf("main name not set")
}
if ctx.String("c") != "20" {
t.Errorf("short name not set")
}
},
}).Run([]string{"run"})
}
func TestParseMultiStringFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_COUNT", "20")
(&cli.App{
Flags: []cli.Flag{
cli.StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
},
Action: func(ctx *cli.Context) {
if ctx.String("count") != "20" {
t.Errorf("main name not set")
}
if ctx.String("c") != "20" {
t.Errorf("short name not set")
}
},
}).Run([]string{"run"})
}
func TestParseMultiStringSlice(t *testing.T) {
(&cli.App{
Flags: []cli.Flag{
cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
t.Errorf("main name not set")
}
if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
t.Errorf("short name not set")
}
},
}).Run([]string{"run", "-s", "10", "-s", "20"})
}
func TestParseMultiStringSliceFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_INTERVALS", "20,30,40")
(&cli.App{
Flags: []cli.Flag{
cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "APP_INTERVALS"},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
t.Errorf("main name not set from env")
}
if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
t.Errorf("short name not set from env")
}
},
}).Run([]string{"run"})
}
func TestParseMultiStringSliceFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_INTERVALS", "20,30,40")
(&cli.App{
Flags: []cli.Flag{
cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
t.Errorf("main name not set from env")
}
if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
t.Errorf("short name not set from env")
}
},
}).Run([]string{"run"})
}
func TestParseMultiInt(t *testing.T) {
a := cli.App{
Flags: []cli.Flag{
cli.IntFlag{Name: "serve, s"},
},
Action: func(ctx *cli.Context) {
if ctx.Int("serve") != 10 {
t.Errorf("main name not set")
}
if ctx.Int("s") != 10 {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run", "-s", "10"})
}
func TestParseMultiIntFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_TIMEOUT_SECONDS", "10")
a := cli.App{
Flags: []cli.Flag{
cli.IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
},
Action: func(ctx *cli.Context) {
if ctx.Int("timeout") != 10 {
t.Errorf("main name not set")
}
if ctx.Int("t") != 10 {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiIntFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_TIMEOUT_SECONDS", "10")
a := cli.App{
Flags: []cli.Flag{
cli.IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
},
Action: func(ctx *cli.Context) {
if ctx.Int("timeout") != 10 {
t.Errorf("main name not set")
}
if ctx.Int("t") != 10 {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiIntSlice(t *testing.T) {
(&cli.App{
Flags: []cli.Flag{
cli.IntSliceFlag{Name: "serve, s", Value: &cli.IntSlice{}},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) {
t.Errorf("main name not set")
}
if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) {
t.Errorf("short name not set")
}
},
}).Run([]string{"run", "-s", "10", "-s", "20"})
}
func TestParseMultiIntSliceFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_INTERVALS", "20,30,40")
(&cli.App{
Flags: []cli.Flag{
cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "APP_INTERVALS"},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
t.Errorf("main name not set from env")
}
if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
t.Errorf("short name not set from env")
}
},
}).Run([]string{"run"})
}
func TestParseMultiIntSliceFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_INTERVALS", "20,30,40")
(&cli.App{
Flags: []cli.Flag{
cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
t.Errorf("main name not set from env")
}
if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
t.Errorf("short name not set from env")
}
},
}).Run([]string{"run"})
}
func TestParseMultiFloat64(t *testing.T) {
a := cli.App{
Flags: []cli.Flag{
cli.Float64Flag{Name: "serve, s"},
},
Action: func(ctx *cli.Context) {
if ctx.Float64("serve") != 10.2 {
t.Errorf("main name not set")
}
if ctx.Float64("s") != 10.2 {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run", "-s", "10.2"})
}
func TestParseMultiFloat64FromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
a := cli.App{
Flags: []cli.Flag{
cli.Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
},
Action: func(ctx *cli.Context) {
if ctx.Float64("timeout") != 15.5 {
t.Errorf("main name not set")
}
if ctx.Float64("t") != 15.5 {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
a := cli.App{
Flags: []cli.Flag{
cli.Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
},
Action: func(ctx *cli.Context) {
if ctx.Float64("timeout") != 15.5 {
t.Errorf("main name not set")
}
if ctx.Float64("t") != 15.5 {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiBool(t *testing.T) {
a := cli.App{
Flags: []cli.Flag{
cli.BoolFlag{Name: "serve, s"},
},
Action: func(ctx *cli.Context) {
if ctx.Bool("serve") != true {
t.Errorf("main name not set")
}
if ctx.Bool("s") != true {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run", "--serve"})
}
func TestParseMultiBoolFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_DEBUG", "1")
a := cli.App{
Flags: []cli.Flag{
cli.BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
},
Action: func(ctx *cli.Context) {
if ctx.Bool("debug") != true {
t.Errorf("main name not set from env")
}
if ctx.Bool("d") != true {
t.Errorf("short name not set from env")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiBoolFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_DEBUG", "1")
a := cli.App{
Flags: []cli.Flag{
cli.BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
},
Action: func(ctx *cli.Context) {
if ctx.Bool("debug") != true {
t.Errorf("main name not set from env")
}
if ctx.Bool("d") != true {
t.Errorf("short name not set from env")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiBoolT(t *testing.T) {
a := cli.App{
Flags: []cli.Flag{
cli.BoolTFlag{Name: "serve, s"},
},
Action: func(ctx *cli.Context) {
if ctx.BoolT("serve") != true {
t.Errorf("main name not set")
}
if ctx.BoolT("s") != true {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run", "--serve"})
}
func TestParseMultiBoolTFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_DEBUG", "0")
a := cli.App{
Flags: []cli.Flag{
cli.BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
},
Action: func(ctx *cli.Context) {
if ctx.BoolT("debug") != false {
t.Errorf("main name not set from env")
}
if ctx.BoolT("d") != false {
t.Errorf("short name not set from env")
}
},
}
a.Run([]string{"run"})
}
func TestParseMultiBoolTFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_DEBUG", "0")
a := cli.App{
Flags: []cli.Flag{
cli.BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
},
Action: func(ctx *cli.Context) {
if ctx.BoolT("debug") != false {
t.Errorf("main name not set from env")
}
if ctx.BoolT("d") != false {
t.Errorf("short name not set from env")
}
},
}
a.Run([]string{"run"})
}
type Parser [2]string
func (p *Parser) Set(value string) error {
parts := strings.Split(value, ",")
if len(parts) != 2 {
return fmt.Errorf("invalid format")
}
(*p)[0] = parts[0]
(*p)[1] = parts[1]
return nil
}
func (p *Parser) String() string {
return fmt.Sprintf("%s,%s", p[0], p[1])
}
func TestParseGeneric(t *testing.T) {
a := cli.App{
Flags: []cli.Flag{
cli.GenericFlag{Name: "serve, s", Value: &Parser{}},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
t.Errorf("main name not set")
}
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
t.Errorf("short name not set")
}
},
}
a.Run([]string{"run", "-s", "10,20"})
}
func TestParseGenericFromEnv(t *testing.T) {
os.Clearenv()
os.Setenv("APP_SERVE", "20,30")
a := cli.App{
Flags: []cli.Flag{
cli.GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) {
t.Errorf("main name not set from env")
}
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) {
t.Errorf("short name not set from env")
}
},
}
a.Run([]string{"run"})
}
func TestParseGenericFromEnvCascade(t *testing.T) {
os.Clearenv()
os.Setenv("APP_FOO", "99,2000")
a := cli.App{
Flags: []cli.Flag{
cli.GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
},
Action: func(ctx *cli.Context) {
if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
t.Errorf("value not set from env")
}
},
}
a.Run([]string{"run"})
}

+ 0
- 235
Godeps/_workspace/src/github.com/codegangsta/cli/help.go View File

@ -1,235 +0,0 @@
package cli
import (
"fmt"
"io"
"strings"
"text/tabwriter"
"text/template"
)
// The text template for the Default help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
var AppHelpTemplate = `NAME:
{{.Name}} - {{.Usage}}
USAGE:
{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...]
VERSION:
{{.Version}}{{if len .Authors}}
AUTHOR(S):
{{range .Authors}}{{ . }}{{end}}{{end}}
COMMANDS:
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
{{end}}{{if .Flags}}
GLOBAL OPTIONS:
{{range .Flags}}{{.}}
{{end}}{{end}}
`
// The text template for the command help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
var CommandHelpTemplate = `NAME:
{{.Name}} - {{.Usage}}
USAGE:
command {{.Name}}{{if .Flags}} [command options]{{end}} [arguments...]{{if .Description}}
DESCRIPTION:
{{.Description}}{{end}}{{if .Flags}}
OPTIONS:
{{range .Flags}}{{.}}
{{end}}{{ end }}
`
// The text template for the subcommand help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
var SubcommandHelpTemplate = `NAME:
{{.Name}} - {{.Usage}}
USAGE:
{{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...]
COMMANDS:
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
{{end}}{{if .Flags}}
OPTIONS:
{{range .Flags}}{{.}}
{{end}}{{end}}
`
var helpCommand = Command{
Name: "help",
Aliases: []string{"h"},
Usage: "Shows a list of commands or help for one command",
Action: func(c *Context) {
args := c.Args()
if args.Present() {
ShowCommandHelp(c, args.First())
} else {
ShowAppHelp(c)
}
},
}
var helpSubcommand = Command{
Name: "help",
Aliases: []string{"h"},
Usage: "Shows a list of commands or help for one command",
Action: func(c *Context) {
args := c.Args()
if args.Present() {
ShowCommandHelp(c, args.First())
} else {
ShowSubcommandHelp(c)
}
},
}
// Prints help for the App or Command
type helpPrinter func(w io.Writer, templ string, data interface{})
var HelpPrinter helpPrinter = printHelp
// Prints version for the App
var VersionPrinter = printVersion
func ShowAppHelp(c *Context) {
HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
}
// Prints the list of subcommands as the default app completion method
func DefaultAppComplete(c *Context) {
for _, command := range c.App.Commands {
for _, name := range command.Names() {
fmt.Fprintln(c.App.Writer, name)
}
}
}
// Prints help for the given command
func ShowCommandHelp(ctx *Context, command string) {
// show the subcommand help for a command with subcommands
if command == "" {
HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
return
}
for _, c := range ctx.App.Commands {
if c.HasName(command) {
HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
return
}
}
if ctx.App.CommandNotFound != nil {
ctx.App.CommandNotFound(ctx, command)
} else {
fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command)
}
}
// Prints help for the given subcommand
func ShowSubcommandHelp(c *Context) {
ShowCommandHelp(c, c.Command.Name)
}
// Prints the version number of the App
func ShowVersion(c *Context) {
VersionPrinter(c)
}
func printVersion(c *Context) {
fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
}
// Prints the lists of commands within a given context
func ShowCompletions(c *Context) {
a := c.App
if a != nil && a.BashComplete != nil {
a.BashComplete(c)
}
}
// Prints the custom completions for a given command
func ShowCommandCompletions(ctx *Context, command string) {
c := ctx.App.Command(command)
if c != nil && c.BashComplete != nil {
c.BashComplete(ctx)
}
}
func printHelp(out io.Writer, templ string, data interface{}) {
funcMap := template.FuncMap{
"join": strings.Join,
}
w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0)
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
err := t.Execute(w, data)
if err != nil {
panic(err)
}
w.Flush()
}
func checkVersion(c *Context) bool {
if c.GlobalBool("version") {
ShowVersion(c)
return true
}
return false
}
func checkHelp(c *Context) bool {
if c.GlobalBool("h") || c.GlobalBool("help") {
ShowAppHelp(c)
return true
}
return false
}
func checkCommandHelp(c *Context, name string) bool {
if c.Bool("h") || c.Bool("help") {
ShowCommandHelp(c, name)
return true
}
return false
}
func checkSubcommandHelp(c *Context) bool {
if c.GlobalBool("h") || c.GlobalBool("help") {
ShowSubcommandHelp(c)
return true
}
return false
}
func checkCompletions(c *Context) bool {
if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
ShowCompletions(c)
return true
}
return false
}
func checkCommandCompletions(c *Context, name string) bool {
if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
ShowCommandCompletions(c, name)
return true
}
return false
}

+ 0
- 22
Godeps/_workspace/src/github.com/codegangsta/cli/help_test.go View File

@ -1,22 +0,0 @@
package cli_test
import (
"bytes"
"testing"
"github.com/codegangsta/cli"
)
func Test_ShowAppHelp_NoAuthor(t *testing.T) {
output := new(bytes.Buffer)
app := cli.NewApp()
app.Writer = output
c := cli.NewContext(app, nil, nil)
cli.ShowAppHelp(c)
if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
}
}

+ 0
- 19
Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go View File

@ -1,19 +0,0 @@
package cli_test
import (
"reflect"
"testing"
)
/* Test Helpers */
func expect(t *testing.T, a interface{}, b interface{}) {
if a != b {
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
}
}
func refute(t *testing.T, a interface{}, b interface{}) {
if a == b {
t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
}
}

+ 0
- 22
Godeps/_workspace/src/github.com/gorilla/websocket/.gitignore View File

@ -1,22 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe

+ 0
- 6
Godeps/_workspace/src/github.com/gorilla/websocket/.travis.yml View File

@ -1,6 +0,0 @@
language: go
go:
- 1.1
- 1.2
- tip

+ 0
- 8
Godeps/_workspace/src/github.com/gorilla/websocket/AUTHORS View File

@ -1,8 +0,0 @@
# This is the official list of Gorilla WebSocket authors for copyright
# purposes.
#
# Please keep the list sorted.
Gary Burd <gary@beagledreams.com>
Joachim Bauch <mail@joachim-bauch.de>

+ 0
- 22
Godeps/_workspace/src/github.com/gorilla/websocket/LICENSE View File

@ -1,22 +0,0 @@
Copyright (c) 2013 The Gorilla WebSocket Authors. 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.
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.

+ 0
- 59
Godeps/_workspace/src/github.com/gorilla/websocket/README.md View File

@ -1,59 +0,0 @@
# Gorilla WebSocket
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
### Documentation
* [API Reference](http://godoc.org/github.com/gorilla/websocket)
* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
### Status
The Gorilla WebSocket package provides a complete and tested implementation of
the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
package API is stable.
### Installation
go get github.com/gorilla/websocket
### Protocol Compliance
The Gorilla WebSocket package passes the server tests in the [Autobahn Test
Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
### Gorilla WebSocket compared with other packages
<table>
<tr>
<th></th>
<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
</tr>
<tr>
<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
<tr><td colspan="3">Other Features</tr></td>
<tr><td>Limit size of received message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.SetReadLimit">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=5082">No</a></td></tr>
<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
</table>
Notes:
1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
2. The application can get the type of a received data message by implementing
a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
function.
3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
Read returns when the input buffer is full or a frame boundary is
encountered. Each call to Write sends a single frame message. The Gorilla
io.Reader and io.WriteCloser operate on a single WebSocket message.

+ 0
- 19
Godeps/_workspace/src/github.com/gorilla/websocket/bench_test.go View File

@ -1,19 +0,0 @@
// Copyright 2014 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"testing"
)
func BenchmarkMaskBytes(b *testing.B) {
var key [4]byte
data := make([]byte, 1024)
pos := 0
for i := 0; i < b.N; i++ {
pos = maskBytes(key, pos, data)
}
b.SetBytes(int64(len(data)))
}

+ 0
- 235
Godeps/_workspace/src/github.com/gorilla/websocket/client.go View File

@ -1,235 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"crypto/tls"
"errors"
"net"
"net/http"
"net/url"
"strings"
"time"
)
// ErrBadHandshake is returned when the server response to opening handshake is
// invalid.
var ErrBadHandshake = errors.New("websocket: bad handshake")
// NewClient creates a new client connection using the given net connection.
// The URL u specifies the host and request URI. Use requestHeader to specify
// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
// (Cookie). Use the response.Header to get the selected subprotocol
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
//
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,
// etc.
func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
challengeKey, err := generateChallengeKey()
if err != nil {
return nil, nil, err
}
acceptKey := computeAcceptKey(challengeKey)
c = newConn(netConn, false, readBufSize, writeBufSize)
p := c.writeBuf[:0]
p = append(p, "GET "...)
p = append(p, u.RequestURI()...)
p = append(p, " HTTP/1.1\r\nHost: "...)
p = append(p, u.Host...)
// "Upgrade" is capitalized for servers that do not use case insensitive
// comparisons on header tokens.
p = append(p, "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: "...)
p = append(p, challengeKey...)
p = append(p, "\r\n"...)
for k, vs := range requestHeader {
for _, v := range vs {
p = append(p, k...)
p = append(p, ": "...)
p = append(p, v...)
p = append(p, "\r\n"...)
}
}
p = append(p, "\r\n"...)
if _, err := netConn.Write(p); err != nil {
return nil, nil, err
}
resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET", URL: u})
if err != nil {
return nil, nil, err
}
if resp.StatusCode != 101 ||
!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
resp.Header.Get("Sec-Websocket-Accept") != acceptKey {
return nil, resp, ErrBadHandshake
}
c.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
return c, resp, nil
}
// A Dialer contains options for connecting to WebSocket server.
type Dialer struct {
// NetDial specifies the dial function for creating TCP connections. If
// NetDial is nil, net.Dial is used.
NetDial func(network, addr string) (net.Conn, error)
// TLSClientConfig specifies the TLS configuration to use with tls.Client.
// If nil, the default configuration is used.
TLSClientConfig *tls.Config
// HandshakeTimeout specifies the duration for the handshake to complete.
HandshakeTimeout time.Duration
// Input and output buffer sizes. If the buffer size is zero, then a
// default value of 4096 is used.
ReadBufferSize, WriteBufferSize int
// Subprotocols specifies the client's requested subprotocols.
Subprotocols []string
}
var errMalformedURL = errors.New("malformed ws or wss URL")
// parseURL parses the URL. The url.Parse function is not used here because
// url.Parse mangles the path.
func parseURL(s string) (*url.URL, error) {
// From the RFC:
//
// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
//
// We don't use the net/url parser here because the dialer interface does
// not provide a way for applications to work around percent deocding in
// the net/url parser.
var u url.URL
switch {
case strings.HasPrefix(s, "ws://"):
u.Scheme = "ws"
s = s[len("ws://"):]
case strings.HasPrefix(s, "wss://"):
u.Scheme = "wss"
s = s[len("wss://"):]
default:
return nil, errMalformedURL
}
u.Host = s
u.Opaque = "/"
if i := strings.Index(s, "/"); i >= 0 {
u.Host = s[:i]
u.Opaque = s[i:]
}
return &u, nil
}
func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
hostPort = u.Host
hostNoPort = u.Host
if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
hostNoPort = hostNoPort[:i]
} else {
if u.Scheme == "wss" {
hostPort += ":443"
} else {
hostPort += ":80"
}
}
return hostPort, hostNoPort
}
// DefaultDialer is a dialer with all fields set to the default zero values.
var DefaultDialer *Dialer
// Dial creates a new client connection. Use requestHeader to specify the
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
// Use the response.Header to get the selected subprotocol
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
//
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,
// etc.
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
u, err := parseURL(urlStr)
if err != nil {
return nil, nil, err
}
hostPort, hostNoPort := hostPortNoPort(u)
if d == nil {
d = &Dialer{}
}
var deadline time.Time
if d.HandshakeTimeout != 0 {
deadline = time.Now().Add(d.HandshakeTimeout)
}
netDial := d.NetDial
if netDial == nil {
netDialer := &net.Dialer{Deadline: deadline}
netDial = netDialer.Dial
}
netConn, err := netDial("tcp", hostPort)
if err != nil {
return nil, nil, err
}
defer func() {
if netConn != nil {
netConn.Close()
}
}()
if err := netConn.SetDeadline(deadline); err != nil {
return nil, nil, err
}
if u.Scheme == "wss" {
cfg := d.TLSClientConfig
if cfg == nil {
cfg = &tls.Config{ServerName: hostNoPort}
} else if cfg.ServerName == "" {
shallowCopy := *cfg
cfg = &shallowCopy
cfg.ServerName = hostNoPort
}
tlsConn := tls.Client(netConn, cfg)
netConn = tlsConn
if err := tlsConn.Handshake(); err != nil {
return nil, nil, err
}
if !cfg.InsecureSkipVerify {
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
return nil, nil, err
}
}
}
if len(d.Subprotocols) > 0 {
h := http.Header{}
for k, v := range requestHeader {
h[k] = v
}
h.Set("Sec-Websocket-Protocol", strings.Join(d.Subprotocols, ", "))
requestHeader = h
}
conn, resp, err := NewClient(netConn, u, requestHeader, d.ReadBufferSize, d.WriteBufferSize)
if err != nil {
return nil, resp, err
}
netConn.SetDeadline(time.Time{})
netConn = nil // to avoid close in defer.
return conn, resp, nil
}

+ 0
- 249
Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go View File

@ -1,249 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"crypto/tls"
"crypto/x509"
"io"
"net"
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"testing"
"time"
)
var cstUpgrader = Upgrader{
Subprotocols: []string{"p0", "p1"},
ReadBufferSize: 1024,
WriteBufferSize: 1024,
Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
http.Error(w, reason.Error(), status)
},
}
var cstDialer = Dialer{
Subprotocols: []string{"p1", "p2"},
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
type cstHandler struct{ *testing.T }
type Server struct {
*httptest.Server
URL string
}
func newServer(t *testing.T) *Server {
var s Server
s.Server = httptest.NewServer(cstHandler{t})
s.URL = "ws" + s.Server.URL[len("http"):]
return &s
}
func newTLSServer(t *testing.T) *Server {
var s Server
s.Server = httptest.NewTLSServer(cstHandler{t})
s.URL = "ws" + s.Server.URL[len("http"):]
return &s
}
func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
t.Logf("method %s not allowed", r.Method)
http.Error(w, "method not allowed", 405)
return
}
subprotos := Subprotocols(r)
if !reflect.DeepEqual(subprotos, cstDialer.Subprotocols) {
t.Logf("subprotols=%v, want %v", subprotos, cstDialer.Subprotocols)
http.Error(w, "bad protocol", 400)
return
}
ws, err := cstUpgrader.Upgrade(w, r, http.Header{"Set-Cookie": {"sessionID=1234"}})
if err != nil {
t.Logf("Upgrade: %v", err)
return
}
defer ws.Close()
if ws.Subprotocol() != "p1" {
t.Logf("Subprotocol() = %s, want p1", ws.Subprotocol())
ws.Close()
return
}
op, rd, err := ws.NextReader()
if err != nil {
t.Logf("NextReader: %v", err)
return
}
wr, err := ws.NextWriter(op)
if err != nil {
t.Logf("NextWriter: %v", err)
return
}
if _, err = io.Copy(wr, rd); err != nil {
t.Logf("NextWriter: %v", err)
return
}
if err := wr.Close(); err != nil {
t.Logf("Close: %v", err)
return
}
}
func sendRecv(t *testing.T, ws *Conn) {
const message = "Hello World!"
if err := ws.SetWriteDeadline(time.Now().Add(time.Second)); err != nil {
t.Fatalf("SetWriteDeadline: %v", err)
}
if err := ws.WriteMessage(TextMessage, []byte(message)); err != nil {
t.Fatalf("WriteMessage: %v", err)
}
if err := ws.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
t.Fatalf("SetReadDeadline: %v", err)
}
_, p, err := ws.ReadMessage()
if err != nil {
t.Fatalf("ReadMessage: %v", err)
}
if string(p) != message {
t.Fatalf("message=%s, want %s", p, message)
}
}
func TestDial(t *testing.T) {
s := newServer(t)
defer s.Close()
ws, _, err := cstDialer.Dial(s.URL, nil)
if err != nil {
t.Fatalf("Dial: %v", err)
}
defer ws.Close()
sendRecv(t, ws)
}
func TestDialTLS(t *testing.T) {
s := newTLSServer(t)
defer s.Close()
certs := x509.NewCertPool()
for _, c := range s.TLS.Certificates {
roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
if err != nil {
t.Fatalf("error parsing server's root cert: %v", err)
}
for _, root := range roots {
certs.AddCert(root)
}
}
u, _ := url.Parse(s.URL)
d := cstDialer
d.NetDial = func(network, addr string) (net.Conn, error) { return net.Dial(network, u.Host) }
d.TLSClientConfig = &tls.Config{RootCAs: certs}
ws, _, err := d.Dial("wss://example.com/", nil)
if err != nil {
t.Fatalf("Dial: %v", err)
}
defer ws.Close()
sendRecv(t, ws)
}
func xTestDialTLSBadCert(t *testing.T) {
s := newTLSServer(t)
defer s.Close()
ws, _, err := cstDialer.Dial(s.URL, nil)
if err == nil {
ws.Close()
t.Fatalf("Dial: nil")
}
}
func xTestDialTLSNoVerify(t *testing.T) {
s := newTLSServer(t)
defer s.Close()
d := cstDialer
d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
ws, _, err := d.Dial(s.URL, nil)
if err != nil {
t.Fatalf("Dial: %v", err)
}
defer ws.Close()
sendRecv(t, ws)
}
func TestDialTimeout(t *testing.T) {
s := newServer(t)
defer s.Close()
d := cstDialer
d.HandshakeTimeout = -1
ws, _, err := d.Dial(s.URL, nil)
if err == nil {
ws.Close()
t.Fatalf("Dial: nil")
}
}
func TestDialBadScheme(t *testing.T) {
s := newServer(t)
defer s.Close()
ws, _, err := cstDialer.Dial(s.Server.URL, nil)
if err == nil {
ws.Close()
t.Fatalf("Dial: nil")
}
}
func TestDialBadOrigin(t *testing.T) {
s := newServer(t)
defer s.Close()
ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {"bad"}})
if err == nil {
ws.Close()
t.Fatalf("Dial: nil")
}
if resp == nil {
t.Fatalf("resp=nil, err=%v", err)
}
if resp.StatusCode != http.StatusForbidden {
t.Fatalf("status=%d, want %d", resp.StatusCode, http.StatusForbidden)
}
}
func TestHandshake(t *testing.T) {
s := newServer(t)
defer s.Close()
ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {s.URL}})
if err != nil {
t.Fatalf("Dial: %v", err)
}
defer ws.Close()
var sessionID string
for _, c := range resp.Cookies() {
if c.Name == "sessionID" {
sessionID = c.Value
}
}
if sessionID != "1234" {
t.Error("Set-Cookie not received from the server.")
}
if ws.Subprotocol() != "p1" {
t.Errorf("ws.Subprotocol() = %s, want p1", ws.Subprotocol())
}
sendRecv(t, ws)
}

+ 0
- 63
Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go View File

@ -1,63 +0,0 @@
// Copyright 2014 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"net/url"
"reflect"
"testing"
)
var parseURLTests = []struct {
s string
u *url.URL
}{
{"ws://example.com/", &url.URL{Scheme: "ws", Host: "example.com", Opaque: "/"}},
{"ws://example.com", &url.URL{Scheme: "ws", Host: "example.com", Opaque: "/"}},
{"ws://example.com:7777/", &url.URL{Scheme: "ws", Host: "example.com:7777", Opaque: "/"}},
{"wss://example.com/", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/"}},
{"wss://example.com/a/b", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/a/b"}},
{"ss://example.com/a/b", nil},
}
func TestParseURL(t *testing.T) {
for _, tt := range parseURLTests {
u, err := parseURL(tt.s)
if tt.u != nil && err != nil {
t.Errorf("parseURL(%q) returned error %v", tt.s, err)
continue
}
if tt.u == nil && err == nil {
t.Errorf("parseURL(%q) did not return error", tt.s)
continue
}
if !reflect.DeepEqual(u, tt.u) {
t.Errorf("parseURL(%q) returned %v, want %v", tt.s, u, tt.u)
continue
}
}
}
var hostPortNoPortTests = []struct {
u *url.URL
hostPort, hostNoPort string
}{
{&url.URL{Scheme: "ws", Host: "example.com"}, "example.com:80", "example.com"},
{&url.URL{Scheme: "wss", Host: "example.com"}, "example.com:443", "example.com"},
{&url.URL{Scheme: "ws", Host: "example.com:7777"}, "example.com:7777", "example.com"},
{&url.URL{Scheme: "wss", Host: "example.com:7777"}, "example.com:7777", "example.com"},
}
func TestHostPortNoPort(t *testing.T) {
for _, tt := range hostPortNoPortTests {
hostPort, hostNoPort := hostPortNoPort(tt.u)
if hostPort != tt.hostPort {
t.Errorf("hostPortNoPort(%v) returned hostPort %q, want %q", tt.u, hostPort, tt.hostPort)
}
if hostNoPort != tt.hostNoPort {
t.Errorf("hostPortNoPort(%v) returned hostNoPort %q, want %q", tt.u, hostNoPort, tt.hostNoPort)
}
}
}

+ 0
- 825
Godeps/_workspace/src/github.com/gorilla/websocket/conn.go View File

@ -1,825 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"bufio"
"encoding/binary"
"errors"
"io"
"io/ioutil"
"math/rand"
"net"
"strconv"
"time"
)
const (
maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask
maxControlFramePayloadSize = 125
finalBit = 1 << 7
maskBit = 1 << 7
writeWait = time.Second
defaultReadBufferSize = 4096
defaultWriteBufferSize = 4096
continuationFrame = 0
noFrame = -1
)
// Close codes defined in RFC 6455, section 11.7.
const (
CloseNormalClosure = 1000
CloseGoingAway = 1001
CloseProtocolError = 1002
CloseUnsupportedData = 1003
CloseNoStatusReceived = 1005
CloseAbnormalClosure = 1006
CloseInvalidFramePayloadData = 1007
ClosePolicyViolation = 1008
CloseMessageTooBig = 1009
CloseMandatoryExtension = 1010
CloseInternalServerErr = 1011
CloseTLSHandshake = 1015
)
// The message types are defined in RFC 6455, section 11.8.
const (
// TextMessage denotes a text data message. The text message payload is
// interpreted as UTF-8 encoded text data.
TextMessage = 1
// BinaryMessage denotes a binary data message.
BinaryMessage = 2
// CloseMessage denotes a close control message. The optional message
// payload contains a numeric code and text. Use the FormatCloseMessage
// function to format a close message payload.
CloseMessage = 8
// PingMessage denotes a ping control message. The optional message payload
// is UTF-8 encoded text.
PingMessage = 9
// PongMessage denotes a ping control message. The optional message payload
// is UTF-8 encoded text.
PongMessage = 10
)
// ErrCloseSent is returned when the application writes a message to the
// connection after sending a close message.
var ErrCloseSent = errors.New("websocket: close sent")
// ErrReadLimit is returned when reading a message that is larger than the
// read limit set for the connection.
var ErrReadLimit = errors.New("websocket: read limit exceeded")
// netError satisfies the net Error interface.
type netError struct {
msg string
temporary bool
timeout bool
}
func (e *netError) Error() string { return e.msg }
func (e *netError) Temporary() bool { return e.temporary }
func (e *netError) Timeout() bool { return e.timeout }
// closeError represents close frame.
type closeError struct {
code int
text string
}
func (e *closeError) Error() string {
return "websocket: close " + strconv.Itoa(e.code) + " " + e.text
}
var (
errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true}
errUnexpectedEOF = &closeError{code: CloseAbnormalClosure, text: io.ErrUnexpectedEOF.Error()}
errBadWriteOpCode = errors.New("websocket: bad write message type")
errWriteClosed = errors.New("websocket: write closed")
errInvalidControlFrame = errors.New("websocket: invalid control frame")
)
func hideTempErr(err error) error {
if e, ok := err.(net.Error); ok && e.Temporary() {
err = &netError{msg: e.Error(), timeout: e.Timeout()}
}
return err
}
func isControl(frameType int) bool {
return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
}
func isData(frameType int) bool {
return frameType == TextMessage || frameType == BinaryMessage
}
func maskBytes(key [4]byte, pos int, b []byte) int {
for i := range b {
b[i] ^= key[pos&3]
pos++
}
return pos & 3
}
func newMaskKey() [4]byte {
n := rand.Uint32()
return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
}
// Conn represents a WebSocket connection.
type Conn struct {
conn net.Conn
isServer bool
subprotocol string
// Write fields
mu chan bool // used as mutex to protect write to conn and closeSent
closeSent bool // true if close message was sent
// Message writer fields.
writeErr error
writeBuf []byte // frame is constructed in this buffer.
writePos int // end of data in writeBuf.
writeFrameType int // type of the current frame.
writeSeq int // incremented to invalidate message writers.
writeDeadline time.Time
// Read fields
readErr error
br *bufio.Reader
readRemaining int64 // bytes remaining in current frame.
readFinal bool // true the current message has more frames.
readSeq int // incremented to invalidate message readers.
readLength int64 // Message size.
readLimit int64 // Maximum message size.
readMaskPos int
readMaskKey [4]byte
handlePong func(string) error
handlePing func(string) error
}
func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
mu := make(chan bool, 1)
mu <- true
if readBufferSize == 0 {
readBufferSize = defaultReadBufferSize
}
if writeBufferSize == 0 {
writeBufferSize = defaultWriteBufferSize
}
c := &Conn{
isServer: isServer,
br: bufio.NewReaderSize(conn, readBufferSize),
conn: conn,
mu: mu,
readFinal: true,
writeBuf: make([]byte, writeBufferSize+maxFrameHeaderSize),
writeFrameType: noFrame,
writePos: maxFrameHeaderSize,
}
c.SetPingHandler(nil)
c.SetPongHandler(nil)
return c
}
// Subprotocol returns the negotiated protocol for the connection.
func (c *Conn) Subprotocol() string {
return c.subprotocol
}
// Close closes the underlying network connection without sending or waiting for a close frame.
func (c *Conn) Close() error {
return c.conn.Close()
}
// LocalAddr returns the local network address.
func (c *Conn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
// RemoteAddr returns the remote network address.
func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
// Write methods
func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
<-c.mu
defer func() { c.mu <- true }()
if c.closeSent {
return ErrCloseSent
} else if frameType == CloseMessage {
c.closeSent = true
}
c.conn.SetWriteDeadline(deadline)
for _, buf := range bufs {
if len(buf) > 0 {
n, err := c.conn.Write(buf)
if n != len(buf) {
// Close on partial write.
c.conn.Close()
}
if err != nil {
return err
}
}
}
return nil
}
// WriteControl writes a control message with the given deadline. The allowed
// message types are CloseMessage, PingMessage and PongMessage.
func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
if !isControl(messageType) {
return errBadWriteOpCode
}
if len(data) > maxControlFramePayloadSize {
return errInvalidControlFrame
}
b0 := byte(messageType) | finalBit
b1 := byte(len(data))
if !c.isServer {
b1 |= maskBit
}
buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
buf = append(buf, b0, b1)
if c.isServer {
buf = append(buf, data...)
} else {
key := newMaskKey()
buf = append(buf, key[:]...)
buf = append(buf, data...)
maskBytes(key, 0, buf[6:])
}
d := time.Hour * 1000
if !deadline.IsZero() {
d = deadline.Sub(time.Now())
if d < 0 {
return errWriteTimeout
}
}
timer := time.NewTimer(d)
select {
case <-c.mu:
timer.Stop()
case <-timer.C:
return errWriteTimeout
}
defer func() { c.mu <- true }()
if c.closeSent {
return ErrCloseSent
} else if messageType == CloseMessage {
c.closeSent = true
}
c.conn.SetWriteDeadline(deadline)
n, err := c.conn.Write(buf)
if n != 0 && n != len(buf) {
c.conn.Close()
}
return err
}
// NextWriter returns a writer for the next message to send. The writer's
// Close method flushes the complete message to the network.
//
// There can be at most one open writer on a connection. NextWriter closes the
// previous writer if the application has not already done so.
//
// The NextWriter method and the writers returned from the method cannot be
// accessed by more than one goroutine at a time.
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
if c.writeErr != nil {
return nil, c.writeErr
}
if c.writeFrameType != noFrame {
if err := c.flushFrame(true, nil); err != nil {
return nil, err
}
}
if !isControl(messageType) && !isData(messageType) {
return nil, errBadWriteOpCode
}
c.writeFrameType = messageType
return messageWriter{c, c.writeSeq}, nil
}
func (c *Conn) flushFrame(final bool, extra []byte) error {
length := c.writePos - maxFrameHeaderSize + len(extra)
// Check for invalid control frames.
if isControl(c.writeFrameType) &&
(!final || length > maxControlFramePayloadSize) {
c.writeSeq++
c.writeFrameType = noFrame
c.writePos = maxFrameHeaderSize
return errInvalidControlFrame
}
b0 := byte(c.writeFrameType)
if final {
b0 |= finalBit
}
b1 := byte(0)
if !c.isServer {
b1 |= maskBit
}
// Assume that the frame starts at beginning of c.writeBuf.
framePos := 0
if c.isServer {
// Adjust up if mask not included in the header.
framePos = 4
}
switch {
case length >= 65536:
c.writeBuf[framePos] = b0
c.writeBuf[framePos+1] = b1 | 127
binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
case length > 125:
framePos += 6
c.writeBuf[framePos] = b0
c.writeBuf[framePos+1] = b1 | 126
binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
default:
framePos += 8
c.writeBuf[framePos] = b0
c.writeBuf[framePos+1] = b1 | byte(length)
}
if !c.isServer {
key := newMaskKey()
copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:c.writePos])
if len(extra) > 0 {
c.writeErr = errors.New("websocket: internal error, extra used in client mode")
return c.writeErr
}
}
// Write the buffers to the connection.
c.writeErr = c.write(c.writeFrameType, c.writeDeadline, c.writeBuf[framePos:c.writePos], extra)
// Setup for next frame.
c.writePos = maxFrameHeaderSize
c.writeFrameType = continuationFrame
if final {
c.writeSeq++
c.writeFrameType = noFrame
}
return c.writeErr
}
type messageWriter struct {
c *Conn
seq int
}
func (w messageWriter) err() error {
c := w.c
if c.writeSeq != w.seq {
return errWriteClosed
}
if c.writeErr != nil {
return c.writeErr
}
return nil
}
func (w messageWriter) ncopy(max int) (int, error) {
n := len(w.c.writeBuf) - w.c.writePos
if n <= 0 {
if err := w.c.flushFrame(false, nil); err != nil {
return 0, err
}
n = len(w.c.writeBuf) - w.c.writePos
}
if n > max {
n = max
}
return n, nil
}
func (w messageWriter) write(final bool, p []byte) (int, error) {
if err := w.err(); err != nil {
return 0, err
}
if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
// Don't buffer large messages.
err := w.c.flushFrame(final, p)
if err != nil {
return 0, err
}
return len(p), nil
}
nn := len(p)
for len(p) > 0 {
n, err := w.ncopy(len(p))
if err != nil {
return 0, err
}
copy(w.c.writeBuf[w.c.writePos:], p[:n])
w.c.writePos += n
p = p[n:]
}
return nn, nil
}
func (w messageWriter) Write(p []byte) (int, error) {
return w.write(false, p)
}
func (w messageWriter) WriteString(p string) (int, error) {
if err := w.err(); err != nil {
return 0, err
}
nn := len(p)
for len(p) > 0 {
n, err := w.ncopy(len(p))
if err != nil {
return 0, err
}
copy(w.c.writeBuf[w.c.writePos:], p[:n])
w.c.writePos += n
p = p[n:]
}
return nn, nil
}
func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
if err := w.err(); err != nil {
return 0, err
}
for {
if w.c.writePos == len(w.c.writeBuf) {
err = w.c.flushFrame(false, nil)
if err != nil {
break
}
}
var n int
n, err = r.Read(w.c.writeBuf[w.c.writePos:])
w.c.writePos += n
nn += int64(n)
if err != nil {
if err == io.EOF {
err = nil
}
break
}
}
return nn, err
}
func (w messageWriter) Close() error {
if err := w.err(); err != nil {
return err
}
return w.c.flushFrame(true, nil)
}
// WriteMessage is a helper method for getting a writer using NextWriter,
// writing the message and closing the writer.
func (c *Conn) WriteMessage(messageType int, data []byte) error {
wr, err := c.NextWriter(messageType)
if err != nil {
return err
}
w := wr.(messageWriter)
if _, err := w.write(true, data); err != nil {
return err
}
if c.writeSeq == w.seq {
if err := c.flushFrame(true, nil); err != nil {
return err
}
}
return nil
}
// SetWriteDeadline sets the write deadline on the underlying network
// connection. After a write has timed out, the websocket state is corrupt and
// all future writes will return an error. A zero value for t means writes will
// not time out.
func (c *Conn) SetWriteDeadline(t time.Time) error {
c.writeDeadline = t
return nil
}
// Read methods
// readFull is like io.ReadFull except that io.EOF is never returned.
func (c *Conn) readFull(p []byte) (err error) {
var n int
for n < len(p) && err == nil {
var nn int
nn, err = c.br.Read(p[n:])
n += nn
}
if n == len(p) {
err = nil
} else if err == io.EOF {
err = errUnexpectedEOF
}
return
}
func (c *Conn) advanceFrame() (int, error) {
// 1. Skip remainder of previous frame.
if c.readRemaining > 0 {
if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
return noFrame, err
}
}
// 2. Read and parse first two bytes of frame header.
var b [8]byte
if err := c.readFull(b[:2]); err != nil {
return noFrame, err
}
final := b[0]&finalBit != 0
frameType := int(b[0] & 0xf)
reserved := int((b[0] >> 4) & 0x7)
mask := b[1]&maskBit != 0
c.readRemaining = int64(b[1] & 0x7f)
if reserved != 0 {
return noFrame, c.handleProtocolError("unexpected reserved bits " + strconv.Itoa(reserved))
}
switch frameType {
case CloseMessage, PingMessage, PongMessage:
if c.readRemaining > maxControlFramePayloadSize {
return noFrame, c.handleProtocolError("control frame length > 125")
}
if !final {
return noFrame, c.handleProtocolError("control frame not final")
}
case TextMessage, BinaryMessage:
if !c.readFinal {
return noFrame, c.handleProtocolError("message start before final message frame")
}
c.readFinal = final
case continuationFrame:
if c.readFinal {
return noFrame, c.handleProtocolError("continuation after final message frame")
}
c.readFinal = final
default:
return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
}
// 3. Read and parse frame length.
switch c.readRemaining {
case 126:
if err := c.readFull(b[:2]); err != nil {
return noFrame, err
}
c.readRemaining = int64(binary.BigEndian.Uint16(b[:2]))
case 127:
if err := c.readFull(b[:8]); err != nil {
return noFrame, err
}
c.readRemaining = int64(binary.BigEndian.Uint64(b[:8]))
}
// 4. Handle frame masking.
if mask != c.isServer {
return noFrame, c.handleProtocolError("incorrect mask flag")
}
if mask {
c.readMaskPos = 0
if err := c.readFull(c.readMaskKey[:]); err != nil {
return noFrame, err
}
}
// 5. For text and binary messages, enforce read limit and return.
if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
c.readLength += c.readRemaining
if c.readLimit > 0 && c.readLength > c.readLimit {
c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
return noFrame, ErrReadLimit
}
return frameType, nil
}
// 6. Read control frame payload.
var payload []byte
if c.readRemaining > 0 {
payload = make([]byte, c.readRemaining)
c.readRemaining = 0
if err := c.readFull(payload); err != nil {
return noFrame, err
}
if c.isServer {
maskBytes(c.readMaskKey, 0, payload)
}
}
// 7. Process control frame payload.
switch frameType {
case PongMessage:
if err := c.handlePong(string(payload)); err != nil {
return noFrame, err
}
case PingMessage:
if err := c.handlePing(string(payload)); err != nil {
return noFrame, err
}
case CloseMessage:
c.WriteControl(CloseMessage, []byte{}, time.Now().Add(writeWait))
closeCode := CloseNoStatusReceived
closeText := ""
if len(payload) >= 2 {
closeCode = int(binary.BigEndian.Uint16(payload))
closeText = string(payload[2:])
}
switch closeCode {
case CloseNormalClosure, CloseGoingAway:
return noFrame, io.EOF
default:
return noFrame, &closeError{code: closeCode, text: closeText}
}
}
return frameType, nil
}
func (c *Conn) handleProtocolError(message string) error {
c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
return errors.New("websocket: " + message)
}
// NextReader returns the next data message received from the peer. The
// returned messageType is either TextMessage or BinaryMessage.
//
// There can be at most one open reader on a connection. NextReader discards
// the previous message if the application has not already consumed it.
//
// The NextReader method and the readers returned from the method cannot be
// accessed by more than one goroutine at a time.
func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
c.readSeq++
c.readLength = 0
for c.readErr == nil {
frameType, err := c.advanceFrame()
if err != nil {
c.readErr = hideTempErr(err)
break
}
if frameType == TextMessage || frameType == BinaryMessage {
return frameType, messageReader{c, c.readSeq}, nil
}
}
return noFrame, nil, c.readErr
}
type messageReader struct {
c *Conn
seq int
}
func (r messageReader) Read(b []byte) (int, error) {
if r.seq != r.c.readSeq {
return 0, io.EOF
}
for r.c.readErr == nil {
if r.c.readRemaining > 0 {
if int64(len(b)) > r.c.readRemaining {
b = b[:r.c.readRemaining]
}
n, err := r.c.br.Read(b)
r.c.readErr = hideTempErr(err)
if r.c.isServer {
r.c.readMaskPos = maskBytes(r.c.readMaskKey, r.c.readMaskPos, b[:n])
}
r.c.readRemaining -= int64(n)
return n, r.c.readErr
}
if r.c.readFinal {
r.c.readSeq++
return 0, io.EOF
}
frameType, err := r.c.advanceFrame()
switch {
case err != nil:
r.c.readErr = hideTempErr(err)
case frameType == TextMessage || frameType == BinaryMessage:
r.c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
}
}
err := r.c.readErr
if err == io.EOF && r.seq == r.c.readSeq {
err = errUnexpectedEOF
}
return 0, err
}
// ReadMessage is a helper method for getting a reader using NextReader and
// reading from that reader to a buffer.
func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
var r io.Reader
messageType, r, err = c.NextReader()
if err != nil {
return messageType, nil, err
}
p, err = ioutil.ReadAll(r)
return messageType, p, err
}
// SetReadDeadline sets the read deadline on the underlying network connection.
// After a read has timed out, the websocket connection state is corrupt and
// all future reads will return an error. A zero value for t means reads will
// not time out.
func (c *Conn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
// SetReadLimit sets the maximum size for a message read from the peer. If a
// message exceeds the limit, the connection sends a close frame to the peer
// and returns ErrReadLimit to the application.
func (c *Conn) SetReadLimit(limit int64) {
c.readLimit = limit
}
// SetPingHandler sets the handler for ping messages received from the peer.
// The default ping handler sends a pong to the peer.
func (c *Conn) SetPingHandler(h func(string) error) {
if h == nil {
h = func(message string) error {
c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
return nil
}
}
c.handlePing = h
}
// SetPongHandler sets then handler for pong messages received from the peer.
// The default pong handler does nothing.
func (c *Conn) SetPongHandler(h func(string) error) {
if h == nil {
h = func(string) error { return nil }
}
c.handlePong = h
}
// UnderlyingConn returns the internal net.Conn. This can be used to further
// modifications to connection specific flags.
func (c *Conn) UnderlyingConn() net.Conn {
return c.conn
}
// FormatCloseMessage formats closeCode and text as a WebSocket close message.
func FormatCloseMessage(closeCode int, text string) []byte {
buf := make([]byte, 2+len(text))
binary.BigEndian.PutUint16(buf, uint16(closeCode))
copy(buf[2:], text)
return buf
}

+ 0
- 238
Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go View File

@ -1,238 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net"
"testing"
"testing/iotest"
"time"
)
var _ net.Error = errWriteTimeout
type fakeNetConn struct {
io.Reader
io.Writer
}
func (c fakeNetConn) Close() error { return nil }
func (c fakeNetConn) LocalAddr() net.Addr { return nil }
func (c fakeNetConn) RemoteAddr() net.Addr { return nil }
func (c fakeNetConn) SetDeadline(t time.Time) error { return nil }
func (c fakeNetConn) SetReadDeadline(t time.Time) error { return nil }
func (c fakeNetConn) SetWriteDeadline(t time.Time) error { return nil }
func TestFraming(t *testing.T) {
frameSizes := []int{0, 1, 2, 124, 125, 126, 127, 128, 129, 65534, 65535, 65536, 65537}
var readChunkers = []struct {
name string
f func(io.Reader) io.Reader
}{
{"half", iotest.HalfReader},
{"one", iotest.OneByteReader},
{"asis", func(r io.Reader) io.Reader { return r }},
}
writeBuf := make([]byte, 65537)
for i := range writeBuf {
writeBuf[i] = byte(i)
}
for _, isServer := range []bool{true, false} {
for _, chunker := range readChunkers {
var connBuf bytes.Buffer
wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
rc := newConn(fakeNetConn{Reader: chunker.f(&connBuf), Writer: nil}, !isServer, 1024, 1024)
for _, n := range frameSizes {
for _, iocopy := range []bool{true, false} {
name := fmt.Sprintf("s:%v, r:%s, n:%d c:%v", isServer, chunker.name, n, iocopy)
w, err := wc.NextWriter(TextMessage)
if err != nil {
t.Errorf("%s: wc.NextWriter() returned %v", name, err)
continue
}
var nn int
if iocopy {
var n64 int64
n64, err = io.Copy(w, bytes.NewReader(writeBuf[:n]))
nn = int(n64)
} else {
nn, err = w.Write(writeBuf[:n])
}
if err != nil || nn != n {
t.Errorf("%s: w.Write(writeBuf[:n]) returned %d, %v", name, nn, err)
continue
}
err = w.Close()
if err != nil {
t.Errorf("%s: w.Close() returned %v", name, err)
continue
}
opCode, r, err := rc.NextReader()
if err != nil || opCode != TextMessage {
t.Errorf("%s: NextReader() returned %d, r, %v", name, opCode, err)
continue
}
rbuf, err := ioutil.ReadAll(r)
if err != nil {
t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
continue
}
if len(rbuf) != n {
t.Errorf("%s: len(rbuf) is %d, want %d", name, len(rbuf), n)
continue
}
for i, b := range rbuf {
if byte(i) != b {
t.Errorf("%s: bad byte at offset %d", name, i)
break
}
}
}
}
}
}
}
func TestControl(t *testing.T) {
const message = "this is a ping/pong messsage"
for _, isServer := range []bool{true, false} {
for _, isWriteControl := range []bool{true, false} {
name := fmt.Sprintf("s:%v, wc:%v", isServer, isWriteControl)
var connBuf bytes.Buffer
wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
rc := newConn(fakeNetConn{Reader: &connBuf, Writer: nil}, !isServer, 1024, 1024)
if isWriteControl {
wc.WriteControl(PongMessage, []byte(message), time.Now().Add(time.Second))
} else {
w, err := wc.NextWriter(PongMessage)
if err != nil {
t.Errorf("%s: wc.NextWriter() returned %v", name, err)
continue
}
if _, err := w.Write([]byte(message)); err != nil {
t.Errorf("%s: w.Write() returned %v", name, err)
continue
}
if err := w.Close(); err != nil {
t.Errorf("%s: w.Close() returned %v", name, err)
continue
}
var actualMessage string
rc.SetPongHandler(func(s string) error { actualMessage = s; return nil })
rc.NextReader()
if actualMessage != message {
t.Errorf("%s: pong=%q, want %q", name, actualMessage, message)
continue
}
}
}
}
}
func TestCloseBeforeFinalFrame(t *testing.T) {
const bufSize = 512
var b1, b2 bytes.Buffer
wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
w, _ := wc.NextWriter(BinaryMessage)
w.Write(make([]byte, bufSize+bufSize/2))
wc.WriteControl(CloseMessage, FormatCloseMessage(CloseNormalClosure, ""), time.Now().Add(10*time.Second))
w.Close()
op, r, err := rc.NextReader()
if op != BinaryMessage || err != nil {
t.Fatalf("NextReader() returned %d, %v", op, err)
}
_, err = io.Copy(ioutil.Discard, r)
if err != errUnexpectedEOF {
t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
}
_, _, err = rc.NextReader()
if err != io.EOF {
t.Fatalf("NextReader() returned %v, want %v", err, io.EOF)
}
}
func TestEOFBeforeFinalFrame(t *testing.T) {
const bufSize = 512
var b1, b2 bytes.Buffer
wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
w, _ := wc.NextWriter(BinaryMessage)
w.Write(make([]byte, bufSize+bufSize/2))
op, r, err := rc.NextReader()
if op != BinaryMessage || err != nil {
t.Fatalf("NextReader() returned %d, %v", op, err)
}
_, err = io.Copy(ioutil.Discard, r)
if err != errUnexpectedEOF {
t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
}
_, _, err = rc.NextReader()
if err != errUnexpectedEOF {
t.Fatalf("NextReader() returned %v, want %v", err, errUnexpectedEOF)
}
}
func TestReadLimit(t *testing.T) {
const readLimit = 512
message := make([]byte, readLimit+1)
var b1, b2 bytes.Buffer
wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, readLimit-2)
rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
rc.SetReadLimit(readLimit)
// Send message at the limit with interleaved pong.
w, _ := wc.NextWriter(BinaryMessage)
w.Write(message[:readLimit-1])
wc.WriteControl(PongMessage, []byte("this is a pong"), time.Now().Add(10*time.Second))
w.Write(message[:1])
w.Close()
// Send message larger than the limit.
wc.WriteMessage(BinaryMessage, message[:readLimit+1])
op, _, err := rc.NextReader()
if op != BinaryMessage || err != nil {
t.Fatalf("1: NextReader() returned %d, %v", op, err)
}
op, r, err := rc.NextReader()
if op != BinaryMessage || err != nil {
t.Fatalf("2: NextReader() returned %d, %v", op, err)
}
_, err = io.Copy(ioutil.Discard, r)
if err != ErrReadLimit {
t.Fatalf("io.Copy() returned %v", err)
}
}
func TestUnderlyingConn(t *testing.T) {
var b1, b2 bytes.Buffer
fc := fakeNetConn{Reader: &b1, Writer: &b2}
c := newConn(fc, true, 1024, 1024)
ul := c.UnderlyingConn()
if ul != fc {
t.Fatalf("Underlying conn is not what it should be.")
}
}

+ 0
- 148
Godeps/_workspace/src/github.com/gorilla/websocket/doc.go View File

@ -1,148 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package websocket implements the WebSocket protocol defined in RFC 6455.
//
// Overview
//
// The Conn type represents a WebSocket connection. A server application uses
// the Upgrade function from an Upgrader object with a HTTP request handler
// to get a pointer to a Conn:
//
// var upgrader = websocket.Upgrader{
// ReadBufferSize: 1024,
// WriteBufferSize: 1024,
// }
//
// func handler(w http.ResponseWriter, r *http.Request) {
// conn, err := upgrader.Upgrade(w, r, nil)
// if err != nil {
// log.Println(err)
// return
// }
// ... Use conn to send and receive messages.
// }
//
// Call the connection WriteMessage and ReadMessages methods to send and
// receive messages as a slice of bytes. This snippet of code shows how to echo
// messages using these methods:
//
// for {
// messageType, p, err := conn.ReadMessage()
// if err != nil {
// return
// }
// if err = conn.WriteMessage(messageType, p); err != nil {
// return err
// }
// }
//
// In above snippet of code, p is a []byte and messageType is an int with value
// websocket.BinaryMessage or websocket.TextMessage.
//
// An application can also send and receive messages using the io.WriteCloser
// and io.Reader interfaces. To send a message, call the connection NextWriter
// method to get an io.WriteCloser, write the message to the writer and close
// the writer when done. To receive a message, call the connection NextReader
// method to get an io.Reader and read until io.EOF is returned. This snippet
// snippet shows how to echo messages using the NextWriter and NextReader
// methods:
//
// for {
// messageType, r, err := conn.NextReader()
// if err != nil {
// return
// }
// w, err := conn.NextWriter(messageType)
// if err != nil {
// return err
// }
// if _, err := io.Copy(w, r); err != nil {
// return err
// }
// if err := w.Close(); err != nil {
// return err
// }
// }
//
// Data Messages
//
// The WebSocket protocol distinguishes between text and binary data messages.
// Text messages are interpreted as UTF-8 encoded text. The interpretation of
// binary messages is left to the application.
//
// This package uses the TextMessage and BinaryMessage integer constants to
// identify the two data message types. The ReadMessage and NextReader methods
// return the type of the received message. The messageType argument to the
// WriteMessage and NextWriter methods specifies the type of a sent message.
//
// It is the application's responsibility to ensure that text messages are
// valid UTF-8 encoded text.
//
// Control Messages
//
// The WebSocket protocol defines three types of control messages: close, ping
// and pong. Call the connection WriteControl, WriteMessage or NextWriter
// methods to send a control message to the peer.
//
// Connections handle received ping and pong messages by invoking a callback
// function set with SetPingHandler and SetPongHandler methods. These callback
// functions can be invoked from the ReadMessage method, the NextReader method
// or from a call to the data message reader returned from NextReader.
//
// Connections handle received close messages by returning an error from the
// ReadMessage method, the NextReader method or from a call to the data message
// reader returned from NextReader.
//
// Concurrency
//
// Connections do not support concurrent calls to the write methods
// (NextWriter, SetWriteDeadline, WriteMessage) or concurrent calls to the read
// methods methods (NextReader, SetReadDeadline, ReadMessage). Connections do
// support a concurrent reader and writer.
//
// The Close and WriteControl methods can be called concurrently with all other
// methods.
//
// Read is Required
//
// The application must read the connection to process ping and close messages
// sent from the peer. If the application is not otherwise interested in
// messages from the peer, then the application should start a goroutine to read
// and discard messages from the peer. A simple example is:
//
// func readLoop(c *websocket.Conn) {
// for {
// if _, _, err := c.NextReader(); err != nil {
// c.Close()
// break
// }
// }
// }
//
// Origin Considerations
//
// Web browsers allow Javascript applications to open a WebSocket connection to
// any host. It's up to the server to enforce an origin policy using the Origin
// request header sent by the browser.
//
// The Upgrader calls the function specified in the CheckOrigin field to check
// the origin. If the CheckOrigin function returns false, then the Upgrade
// method fails the WebSocket handshake with HTTP status 403.
//
// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
// the handshake if the Origin request header is present and not equal to the
// Host request header.
//
// An application can allow connections from any origin by specifying a
// function that always returns true:
//
// var upgrader = websocket.Upgrader{
// CheckOrigin: func(r *http.Request) bool { return true },
// }
//
// The deprecated Upgrade function does not enforce an origin policy. It's the
// application's responsibility to check the Origin header before calling
// Upgrade.
package websocket

+ 0
- 13
Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md View File

@ -1,13 +0,0 @@
# Test Server
This package contains a server for the [Autobahn WebSockets Test Suite](http://autobahn.ws/testsuite).
To test the server, run
go run server.go
and start the client test driver
wstest -m fuzzingclient -s fuzzingclient.json
When the client completes, it writes a report to reports/clients/index.html.

+ 0
- 14
Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json View File

@ -1,14 +0,0 @@
{
"options": {"failByDrop": false},
"outdir": "./reports/clients",
"servers": [
{"agent": "ReadAllWriteMessage", "url": "ws://localhost:9000/m", "options": {"version": 18}},
{"agent": "ReadAllWrite", "url": "ws://localhost:9000/r", "options": {"version": 18}},
{"agent": "CopyFull", "url": "ws://localhost:9000/f", "options": {"version": 18}},
{"agent": "CopyWriterOnly", "url": "ws://localhost:9000/c", "options": {"version": 18}}
],
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

+ 0
- 246
Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go View File

@ -1,246 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Command server is a test server for the Autobahn WebSockets Test Suite.
package main
import (
"errors"
"flag"
"github.com/gorilla/websocket"
"io"
"log"
"net/http"
"time"
"unicode/utf8"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4096,
WriteBufferSize: 4096,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// echoCopy echoes messages from the client using io.Copy.
func echoCopy(w http.ResponseWriter, r *http.Request, writerOnly bool) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Upgrade:", err)
return
}
defer conn.Close()
for {
mt, r, err := conn.NextReader()
if err != nil {
if err != io.EOF {
log.Println("NextReader:", err)
}
return
}
if mt == websocket.TextMessage {
r = &validator{r: r}
}
w, err := conn.NextWriter(mt)
if err != nil {
log.Println("NextWriter:", err)
return
}
if mt == websocket.TextMessage {
r = &validator{r: r}
}
if writerOnly {
_, err = io.Copy(struct{ io.Writer }{w}, r)
} else {
_, err = io.Copy(w, r)
}
if err != nil {
if err == errInvalidUTF8 {
conn.WriteControl(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
time.Time{})
}
log.Println("Copy:", err)
return
}
err = w.Close()
if err != nil {
log.Println("Close:", err)
return
}
}
}
func echoCopyWriterOnly(w http.ResponseWriter, r *http.Request) {
echoCopy(w, r, true)
}
func echoCopyFull(w http.ResponseWriter, r *http.Request) {
echoCopy(w, r, false)
}
// echoReadAll echoes messages from the client by reading the entire message
// with ioutil.ReadAll.
func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage bool) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Upgrade:", err)
return
}
defer conn.Close()
for {
mt, b, err := conn.ReadMessage()
if err != nil {
if err != io.EOF {
log.Println("NextReader:", err)
}
return
}
if mt == websocket.TextMessage {
if !utf8.Valid(b) {
conn.WriteControl(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
time.Time{})
log.Println("ReadAll: invalid utf8")
}
}
if writeMessage {
err = conn.WriteMessage(mt, b)
if err != nil {
log.Println("WriteMessage:", err)
}
} else {
w, err := conn.NextWriter(mt)
if err != nil {
log.Println("NextWriter:", err)
return
}
if _, err := w.Write(b); err != nil {
log.Println("Writer:", err)
return
}
if err := w.Close(); err != nil {
log.Println("Close:", err)
return
}
}
}
}
func echoReadAllWriter(w http.ResponseWriter, r *http.Request) {
echoReadAll(w, r, false)
}
func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) {
echoReadAll(w, r, true)
}
func serveHome(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.Error(w, "Not found.", 404)
return
}
if r.Method != "GET" {
http.Error(w, "Method not allowed", 405)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
io.WriteString(w, "<html><body>Echo Server</body></html>")
}
var addr = flag.String("addr", ":9000", "http service address")
func main() {
flag.Parse()
http.HandleFunc("/", serveHome)
http.HandleFunc("/c", echoCopyWriterOnly)
http.HandleFunc("/f", echoCopyFull)
http.HandleFunc("/r", echoReadAllWriter)
http.HandleFunc("/m", echoReadAllWriteMessage)
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
type validator struct {
state int
x rune
r io.Reader
}
var errInvalidUTF8 = errors.New("invalid utf8")
func (r *validator) Read(p []byte) (int, error) {
n, err := r.r.Read(p)
state := r.state
x := r.x
for _, b := range p[:n] {
state, x = decode(state, x, b)
if state == utf8Reject {
break
}
}
r.state = state
r.x = x
if state == utf8Reject || (err == io.EOF && state != utf8Accept) {
return n, errInvalidUTF8
}
return n, err
}
// UTF-8 decoder from http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
//
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
//
// 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.
var utf8d = [...]byte{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7f
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9f
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // a0..bf
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0..df
0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // e0..ef
0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // f0..ff
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // s7..s8
}
const (
utf8Accept = 0
utf8Reject = 1
)
func decode(state int, x rune, b byte) (int, rune) {
t := utf8d[b]
if state != utf8Accept {
x = rune(b&0x3f) | (x << 6)
} else {
x = rune((0xff >> t) & b)
}
state = int(utf8d[256+state*16+int(t)])
return state, x
}

+ 0
- 19
Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md View File

@ -1,19 +0,0 @@
# Chat Example
This application shows how to use use the
[websocket](https://github.com/gorilla/websocket) package and
[jQuery](http://jquery.com) to implement a simple web chat application.
## Running the example
The example requires a working Go development environment. The [Getting
Started](http://golang.org/doc/install) page describes how to install the
development environment.
Once you have Go up and running, you can download, build and run the example
using the following commands.
$ go get github.com/gorilla/websocket
$ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat`
$ go run *.go

+ 0
- 106
Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go View File

@ -1,106 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"github.com/gorilla/websocket"
"log"
"net/http"
"time"
)
const (
// Time allowed to write a message to the peer.
writeWait = 10 * time.Second
// Time allowed to read the next pong message from the peer.
pongWait = 60 * time.Second
// Send pings to peer with this period. Must be less than pongWait.
pingPeriod = (pongWait * 9) / 10
// Maximum message size allowed from peer.
maxMessageSize = 512
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
// connection is an middleman between the websocket connection and the hub.
type connection struct {
// The websocket connection.
ws *websocket.Conn
// Buffered channel of outbound messages.
send chan []byte
}
// readPump pumps messages from the websocket connection to the hub.
func (c *connection) readPump() {
defer func() {
h.unregister <- c
c.ws.Close()
}()
c.ws.SetReadLimit(maxMessageSize)
c.ws.SetReadDeadline(time.Now().Add(pongWait))
c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
for {
_, message, err := c.ws.ReadMessage()
if err != nil {
break
}
h.broadcast <- message
}
}
// write writes a message with the given message type and payload.
func (c *connection) write(mt int, payload []byte) error {
c.ws.SetWriteDeadline(time.Now().Add(writeWait))
return c.ws.WriteMessage(mt, payload)
}
// writePump pumps messages from the hub to the websocket connection.
func (c *connection) writePump() {
ticker := time.NewTicker(pingPeriod)
defer func() {
ticker.Stop()
c.ws.Close()
}()
for {
select {
case message, ok := <-c.send:
if !ok {
c.write(websocket.CloseMessage, []byte{})
return
}
if err := c.write(websocket.TextMessage, message); err != nil {
return
}
case <-ticker.C:
if err := c.write(websocket.PingMessage, []byte{}); err != nil {
return
}
}
}
}
// serverWs handles websocket requests from the peer.
func serveWs(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, "Method not allowed", 405)
return
}
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
c := &connection{send: make(chan []byte, 256), ws: ws}
h.register <- c
go c.writePump()
c.readPump()
}

+ 0
- 92
Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/home.html View File

@ -1,92 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Chat Example</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var conn;
var msg = $("#msg");
var log = $("#log");
function appendLog(msg) {
var d = log[0]
var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
msg.appendTo(log)
if (doScroll) {
d.scrollTop = d.scrollHeight - d.clientHeight;
}
}
$("#form").submit(function() {
if (!conn) {
return false;
}
if (!msg.val()) {
return false;
}
conn.send(msg.val());
msg.val("");
return false
});
if (window["WebSocket"]) {
conn = new WebSocket("ws://{{$}}/ws");
conn.onclose = function(evt) {
appendLog($("<div><b>Connection closed.</b></div>"))
}
conn.onmessage = function(evt) {
appendLog($("<div/>").text(evt.data))
}
} else {
appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
}
});
</script>
<style type="text/css">
html {
overflow: hidden;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background: gray;
}
#log {
background: white;
margin: 0;
padding: 0.5em 0.5em 0.5em 0.5em;
position: absolute;
top: 0.5em;
left: 0.5em;
right: 0.5em;
bottom: 3em;
overflow: auto;
}
#form {
padding: 0 0.5em 0 0.5em;
margin: 0;
position: absolute;
bottom: 1em;
left: 0px;
width: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="log"></div>
<form id="form">
<input type="submit" value="Send" />
<input type="text" id="msg" size="64"/>
</form>
</body>
</html>

+ 0
- 51
Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/hub.go View File

@ -1,51 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// hub maintains the set of active connections and broadcasts messages to the
// connections.
type hub struct {
// Registered connections.
connections map[*connection]bool
// Inbound messages from the connections.
broadcast chan []byte
// Register requests from the connections.
register chan *connection
// Unregister requests from connections.
unregister chan *connection
}
var h = hub{
broadcast: make(chan []byte),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
}
func (h *hub) run() {
for {
select {
case c := <-h.register:
h.connections[c] = true
case c := <-h.unregister:
if _, ok := h.connections[c]; ok {
delete(h.connections, c)
close(c.send)
}
case m := <-h.broadcast:
for c := range h.connections {
select {
case c.send <- m:
default:
close(c.send)
delete(h.connections, c)
}
}
}
}
}

+ 0
- 39
Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/main.go View File

@ -1,39 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"flag"
"log"
"net/http"
"text/template"
)
var addr = flag.String("addr", ":8080", "http service address")
var homeTempl = template.Must(template.ParseFiles("home.html"))
func serveHome(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.Error(w, "Not found", 404)
return
}
if r.Method != "GET" {
http.Error(w, "Method not allowed", 405)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
homeTempl.Execute(w, r.Host)
}
func main() {
flag.Parse()
go h.run()
http.HandleFunc("/", serveHome)
http.HandleFunc("/ws", serveWs)
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}

+ 0
- 9
Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md View File

@ -1,9 +0,0 @@
# File Watch example.
This example sends a file to the browser client for display whenever the file is modified.
$ go get github.com/gorilla/websocket
$ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/filewatch`
$ go run main.go <name of file to watch>
# Open http://localhost:8080/ .
# Modify the file to see it update in the browser.

+ 0
- 193
Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go View File

@ -1,193 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"flag"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
"text/template"
"time"
"github.com/gorilla/websocket"
)
const (
// Time allowed to write the file to the client.
writeWait = 10 * time.Second
// Time allowed to read the next pong message from the client.
pongWait = 60 * time.Second
// Send pings to client with this period. Must be less than pongWait.
pingPeriod = (pongWait * 9) / 10
// Poll file for changes with this period.
filePeriod = 10 * time.Second
)
var (
addr = flag.String("addr", ":8080", "http service address")
homeTempl = template.Must(template.New("").Parse(homeHTML))
filename string
upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
)
func readFileIfModified(lastMod time.Time) ([]byte, time.Time, error) {
fi, err := os.Stat(filename)
if err != nil {
return nil, lastMod, err
}
if !fi.ModTime().After(lastMod) {
return nil, lastMod, nil
}
p, err := ioutil.ReadFile(filename)
if err != nil {
return nil, fi.ModTime(), err
}
return p, fi.ModTime(), nil
}
func reader(ws *websocket.Conn) {
defer ws.Close()
ws.SetReadLimit(512)
ws.SetReadDeadline(time.Now().Add(pongWait))
ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
for {
_, _, err := ws.ReadMessage()
if err != nil {
break
}
}
}
func writer(ws *websocket.Conn, lastMod time.Time) {
lastError := ""
pingTicker := time.NewTicker(pingPeriod)
fileTicker := time.NewTicker(filePeriod)
defer func() {
pingTicker.Stop()
fileTicker.Stop()
ws.Close()
}()
for {
select {
case <-fileTicker.C:
var p []byte
var err error
p, lastMod, err = readFileIfModified(lastMod)
if err != nil {
if s := err.Error(); s != lastError {
lastError = s
p = []byte(lastError)
}
} else {
lastError = ""
}
if p != nil {
ws.SetWriteDeadline(time.Now().Add(writeWait))
if err := ws.WriteMessage(websocket.TextMessage, p); err != nil {
return
}
}
case <-pingTicker.C:
ws.SetWriteDeadline(time.Now().Add(writeWait))
if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
return
}
}
}
}
func serveWs(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
if _, ok := err.(websocket.HandshakeError); !ok {
log.Println(err)
}
return
}
var lastMod time.Time
if n, err := strconv.ParseInt(r.FormValue("lastMod"), 16, 64); err != nil {
lastMod = time.Unix(0, n)
}
go writer(ws, lastMod)
reader(ws)
}
func serveHome(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.Error(w, "Not found", 404)
return
}
if r.Method != "GET" {
http.Error(w, "Method not allowed", 405)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
p, lastMod, err := readFileIfModified(time.Time{})
if err != nil {
p = []byte(err.Error())
lastMod = time.Unix(0, 0)
}
var v = struct {
Host string
Data string
LastMod string
}{
r.Host,
string(p),
strconv.FormatInt(lastMod.UnixNano(), 16),
}
homeTempl.Execute(w, &v)
}
func main() {
flag.Parse()
if flag.NArg() != 1 {
log.Fatal("filename not specified")
}
filename = flag.Args()[0]
http.HandleFunc("/", serveHome)
http.HandleFunc("/ws", serveWs)
if err := http.ListenAndServe(*addr, nil); err != nil {
log.Fatal(err)
}
}
const homeHTML = `<!DOCTYPE html>
<html lang="en">
<head>
<title>WebSocket Example</title>
</head>
<body>
<pre id="fileData">{{.Data}}</pre>
<script type="text/javascript">
(function() {
var data = document.getElementById("fileData");
var conn = new WebSocket("ws://{{.Host}}/ws?lastMod={{.LastMod}}");
conn.onclose = function(evt) {
data.textContent = 'Connection closed';
}
conn.onmessage = function(evt) {
console.log('file updated');
data.textContent = evt.data;
}
})();
</script>
</body>
</html>
`

+ 0
- 49
Godeps/_workspace/src/github.com/gorilla/websocket/json.go View File

@ -1,49 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"encoding/json"
)
// WriteJSON is deprecated, use c.WriteJSON instead.
func WriteJSON(c *Conn, v interface{}) error {
return c.WriteJSON(v)
}
// WriteJSON writes the JSON encoding of v to the connection.
//
// See the documentation for encoding/json Marshal for details about the
// conversion of Go values to JSON.
func (c *Conn) WriteJSON(v interface{}) error {
w, err := c.NextWriter(TextMessage)
if err != nil {
return err
}
err1 := json.NewEncoder(w).Encode(v)
err2 := w.Close()
if err1 != nil {
return err1
}
return err2
}
// ReadJSON is deprecated, use c.ReadJSON instead.
func ReadJSON(c *Conn, v interface{}) error {
return c.ReadJSON(v)
}
// ReadJSON reads the next JSON-encoded message from the connection and stores
// it in the value pointed to by v.
//
// See the documentation for the encoding/json Unmarshal function for details
// about the conversion of JSON to a Go value.
func (c *Conn) ReadJSON(v interface{}) error {
_, r, err := c.NextReader()
if err != nil {
return err
}
return json.NewDecoder(r).Decode(v)
}

+ 0
- 63
Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go View File

@ -1,63 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"bytes"
"reflect"
"testing"
)
func TestJSON(t *testing.T) {
var buf bytes.Buffer
c := fakeNetConn{&buf, &buf}
wc := newConn(c, true, 1024, 1024)
rc := newConn(c, false, 1024, 1024)
var actual, expect struct {
A int
B string
}
expect.A = 1
expect.B = "hello"
if err := wc.WriteJSON(&expect); err != nil {
t.Fatal("write", err)
}
if err := rc.ReadJSON(&actual); err != nil {
t.Fatal("read", err)
}
if !reflect.DeepEqual(&actual, &expect) {
t.Fatal("equal", actual, expect)
}
}
func TestDeprecatedJSON(t *testing.T) {
var buf bytes.Buffer
c := fakeNetConn{&buf, &buf}
wc := newConn(c, true, 1024, 1024)
rc := newConn(c, false, 1024, 1024)
var actual, expect struct {
A int
B string
}
expect.A = 1
expect.B = "hello"
if err := WriteJSON(wc, &expect); err != nil {
t.Fatal("write", err)
}
if err := ReadJSON(rc, &actual); err != nil {
t.Fatal("read", err)
}
if !reflect.DeepEqual(&actual, &expect) {
t.Fatal("equal", actual, expect)
}
}

+ 0
- 247
Godeps/_workspace/src/github.com/gorilla/websocket/server.go View File

@ -1,247 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"bufio"
"errors"
"net"
"net/http"
"net/url"
"strings"
"time"
)
// HandshakeError describes an error with the handshake from the peer.
type HandshakeError struct {
message string
}
func (e HandshakeError) Error() string { return e.message }
// Upgrader specifies parameters for upgrading an HTTP connection to a
// WebSocket connection.
type Upgrader struct {
// HandshakeTimeout specifies the duration for the handshake to complete.
HandshakeTimeout time.Duration
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
// size is zero, then a default value of 4096 is used. The I/O buffer sizes
// do not limit the size of the messages that can be sent or received.
ReadBufferSize, WriteBufferSize int
// Subprotocols specifies the server's supported protocols in order of
// preference. If this field is set, then the Upgrade method negotiates a
// subprotocol by selecting the first match in this list with a protocol
// requested by the client.
Subprotocols []string
// Error specifies the function for generating HTTP error responses. If Error
// is nil, then http.Error is used to generate the HTTP response.
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
// CheckOrigin returns true if the request Origin header is acceptable. If
// CheckOrigin is nil, the host in the Origin header must not be set or
// must match the host of the request.
CheckOrigin func(r *http.Request) bool
}
func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
err := HandshakeError{reason}
if u.Error != nil {
u.Error(w, r, status, err)
} else {
http.Error(w, http.StatusText(status), status)
}
return nil, err
}
// checkSameOrigin returns true if the origin is not set or is equal to the request host.
func checkSameOrigin(r *http.Request) bool {
origin := r.Header["Origin"]
if len(origin) == 0 {
return true
}
u, err := url.Parse(origin[0])
if err != nil {
return false
}
return u.Host == r.Host
}
func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
if u.Subprotocols != nil {
clientProtocols := Subprotocols(r)
for _, serverProtocol := range u.Subprotocols {
for _, clientProtocol := range clientProtocols {
if clientProtocol == serverProtocol {
return clientProtocol
}
}
}
} else if responseHeader != nil {
return responseHeader.Get("Sec-Websocket-Protocol")
}
return ""
}
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
//
// The responseHeader is included in the response to the client's upgrade
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
// application negotiated subprotocol (Sec-Websocket-Protocol).
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
if values := r.Header["Sec-Websocket-Version"]; len(values) == 0 || values[0] != "13" {
return u.returnError(w, r, http.StatusBadRequest, "websocket: version != 13")
}
if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
return u.returnError(w, r, http.StatusBadRequest, "websocket: connection header != upgrade")
}
if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
return u.returnError(w, r, http.StatusBadRequest, "websocket: upgrade != websocket")
}
checkOrigin := u.CheckOrigin
if checkOrigin == nil {
checkOrigin = checkSameOrigin
}
if !checkOrigin(r) {
return u.returnError(w, r, http.StatusForbidden, "websocket: origin not allowed")
}
challengeKey := r.Header.Get("Sec-Websocket-Key")
if challengeKey == "" {
return u.returnError(w, r, http.StatusBadRequest, "websocket: key missing or blank")
}
subprotocol := u.selectSubprotocol(r, responseHeader)
var (
netConn net.Conn
br *bufio.Reader
err error
)
h, ok := w.(http.Hijacker)
if !ok {
return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
}
var rw *bufio.ReadWriter
netConn, rw, err = h.Hijack()
if err != nil {
return u.returnError(w, r, http.StatusInternalServerError, err.Error())
}
br = rw.Reader
if br.Buffered() > 0 {
netConn.Close()
return nil, errors.New("websocket: client sent data before handshake is complete")
}
c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize)
c.subprotocol = subprotocol
p := c.writeBuf[:0]
p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
p = append(p, computeAcceptKey(challengeKey)...)
p = append(p, "\r\n"...)
if c.subprotocol != "" {
p = append(p, "Sec-Websocket-Protocol: "...)
p = append(p, c.subprotocol...)
p = append(p, "\r\n"...)
}
for k, vs := range responseHeader {
if k == "Sec-Websocket-Protocol" {
continue
}
for _, v := range vs {
p = append(p, k...)
p = append(p, ": "...)
for i := 0; i < len(v); i++ {
b := v[i]
if b <= 31 {
// prevent response splitting.
b = ' '
}
p = append(p, b)
}
p = append(p, "\r\n"...)
}
}
p = append(p, "\r\n"...)
// Clear deadlines set by HTTP server.
netConn.SetDeadline(time.Time{})
if u.HandshakeTimeout > 0 {
netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
}
if _, err = netConn.Write(p); err != nil {
netConn.Close()
return nil, err
}
if u.HandshakeTimeout > 0 {
netConn.SetWriteDeadline(time.Time{})
}
return c, nil
}
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
//
// This function is deprecated, use websocket.Upgrader instead.
//
// The application is responsible for checking the request origin before
// calling Upgrade. An example implementation of the same origin policy is:
//
// if req.Header.Get("Origin") != "http://"+req.Host {
// http.Error(w, "Origin not allowed", 403)
// return
// }
//
// If the endpoint supports subprotocols, then the application is responsible
// for negotiating the protocol used on the connection. Use the Subprotocols()
// function to get the subprotocols requested by the client. Use the
// Sec-Websocket-Protocol response header to specify the subprotocol selected
// by the application.
//
// The responseHeader is included in the response to the client's upgrade
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
// negotiated subprotocol (Sec-Websocket-Protocol).
//
// The connection buffers IO to the underlying network connection. The
// readBufSize and writeBufSize parameters specify the size of the buffers to
// use. Messages can be larger than the buffers.
//
// If the request is not a valid WebSocket handshake, then Upgrade returns an
// error of type HandshakeError. Applications should handle this error by
// replying to the client with an HTTP error response.
func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {
u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}
u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {
// don't return errors to maintain backwards compatibility
}
u.CheckOrigin = func(r *http.Request) bool {
// allow all connections by default
return true
}
return u.Upgrade(w, r, responseHeader)
}
// Subprotocols returns the subprotocols requested by the client in the
// Sec-Websocket-Protocol header.
func Subprotocols(r *http.Request) []string {
h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol"))
if h == "" {
return nil
}
protocols := strings.Split(h, ",")
for i := range protocols {
protocols[i] = strings.TrimSpace(protocols[i])
}
return protocols
}

+ 0
- 33
Godeps/_workspace/src/github.com/gorilla/websocket/server_test.go View File

@ -1,33 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"net/http"
"reflect"
"testing"
)
var subprotocolTests = []struct {
h string
protocols []string
}{
{"", nil},
{"foo", []string{"foo"}},
{"foo,bar", []string{"foo", "bar"}},
{"foo, bar", []string{"foo", "bar"}},
{" foo, bar", []string{"foo", "bar"}},
{" foo, bar ", []string{"foo", "bar"}},
}
func TestSubprotocols(t *testing.T) {
for _, st := range subprotocolTests {
r := http.Request{Header: http.Header{"Sec-Websocket-Protocol": {st.h}}}
protocols := Subprotocols(&r)
if !reflect.DeepEqual(st.protocols, protocols) {
t.Errorf("SubProtocols(%q) returned %#v, want %#v", st.h, protocols, st.protocols)
}
}
}

+ 0
- 44
Godeps/_workspace/src/github.com/gorilla/websocket/util.go View File

@ -1,44 +0,0 @@
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"crypto/rand"
"crypto/sha1"
"encoding/base64"
"io"
"net/http"
"strings"
)
// tokenListContainsValue returns true if the 1#token header with the given
// name contains token.
func tokenListContainsValue(header http.Header, name string, value string) bool {
for _, v := range header[name] {
for _, s := range strings.Split(v, ",") {
if strings.EqualFold(value, strings.TrimSpace(s)) {
return true
}
}
}
return false
}
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
func computeAcceptKey(challengeKey string) string {
h := sha1.New()
h.Write([]byte(challengeKey))
h.Write(keyGUID)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func generateChallengeKey() (string, error) {
p := make([]byte, 16)
if _, err := io.ReadFull(rand.Reader, p); err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(p), nil
}

+ 0
- 34
Godeps/_workspace/src/github.com/gorilla/websocket/util_test.go View File

@ -1,34 +0,0 @@
// Copyright 2014 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"net/http"
"testing"
)
var tokenListContainsValueTests = []struct {
value string
ok bool
}{
{"WebSocket", true},
{"WEBSOCKET", true},
{"websocket", true},
{"websockets", false},
{"x websocket", false},
{"websocket x", false},
{"other,websocket,more", true},
{"other, websocket, more", true},
}
func TestTokenListContainsValue(t *testing.T) {
for _, tt := range tokenListContainsValueTests {
h := http.Header{"Upgrade": {tt.value}}
ok := tokenListContainsValue(h, "Upgrade", "websocket")
if ok != tt.ok {
t.Errorf("tokenListContainsValue(h, n, %q) = %v, want %v", tt.value, ok, tt.ok)
}
}
}

+ 0
- 225
Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack.go View File

@ -1,225 +0,0 @@
// Package stack implements utilities to capture, manipulate, and format call
// stacks.
package stack
import (
"fmt"
"path/filepath"
"runtime"
"strings"
)
// Call records a single function invocation from a goroutine stack. It is a
// wrapper for the program counter values returned by runtime.Caller and
// runtime.Callers and consumed by runtime.FuncForPC.
type Call uintptr
// Format implements fmt.Formatter with support for the following verbs.
//
// %s source file
// %d line number
// %n function name
// %v equivalent to %s:%d
//
// It accepts the '+' and '#' flags for most of the verbs as follows.
//
// %+s path of source file relative to the compile time GOPATH
// %#s full path of source file
// %+n import path qualified function name
// %+v equivalent to %+s:%d
// %#v equivalent to %#s:%d
func (pc Call) Format(s fmt.State, c rune) {
// BUG(ChrisHines): Subtracting one from pc is a work around for
// https://code.google.com/p/go/issues/detail?id=7690. The idea for this
// work around comes from rsc's initial patch at
// https://codereview.appspot.com/84100043/#ps20001, but as noted in the
// issue discussion, it is not a complete fix since it doesn't handle some
// cases involving signals. Just the same, it handles all of the other
// cases I have tested.
pcFix := uintptr(pc) - 1
fn := runtime.FuncForPC(pcFix)
if fn == nil {
fmt.Fprintf(s, "%%!%c(NOFUNC)", c)
return
}
switch c {
case 's', 'v':
file, line := fn.FileLine(pcFix)
switch {
case s.Flag('#'):
// done
case s.Flag('+'):
// Here we want to get the source file path relative to the
// compile time GOPATH. As of Go 1.3.x there is no direct way to
// know the compiled GOPATH at runtime, but we can infer the
// number of path segments in the GOPATH. We note that fn.Name()
// returns the function name qualified by the import path, which
// does not include the GOPATH. Thus we can trim segments from the
// beginning of the file path until the number of path separators
// remaining is one more than the number of path separators in the
// function name. For example, given:
//
// GOPATH /home/user
// file /home/user/src/pkg/sub/file.go
// fn.Name() pkg/sub.Type.Method
//
// We want to produce:
//
// pkg/sub/file.go
//
// From this we can easily see that fn.Name() has one less path
// separator than our desired output.
const sep = "/"
impCnt := strings.Count(fn.Name(), sep) + 1
pathCnt := strings.Count(file, sep)
for pathCnt > impCnt {
i := strings.Index(file, sep)
if i == -1 {
break
}
file = file[i+len(sep):]
pathCnt--
}
default:
const sep = "/"
if i := strings.LastIndex(file, sep); i != -1 {
file = file[i+len(sep):]
}
}
fmt.Fprint(s, file)
if c == 'v' {
fmt.Fprint(s, ":", line)
}
case 'd':
_, line := fn.FileLine(pcFix)
fmt.Fprint(s, line)
case 'n':
name := fn.Name()
if !s.Flag('+') {
const pathSep = "/"
if i := strings.LastIndex(name, pathSep); i != -1 {
name = name[i+len(pathSep):]
}
const pkgSep = "."
if i := strings.Index(name, pkgSep); i != -1 {
name = name[i+len(pkgSep):]
}
}
fmt.Fprint(s, name)
}
}
// Callers returns a Trace for the current goroutine with element 0
// identifying the calling function.
func Callers() Trace {
pcs := poolBuf()
pcs = pcs[:cap(pcs)]
n := runtime.Callers(2, pcs)
cs := make([]Call, n)
for i, pc := range pcs[:n] {
cs[i] = Call(pc)
}
putPoolBuf(pcs)
return cs
}
// name returns the import path qualified name of the function containing the
// call.
func (pc Call) name() string {
pcFix := uintptr(pc) - 1 // work around for go issue #7690
fn := runtime.FuncForPC(pcFix)
if fn == nil {
return "???"
}
return fn.Name()
}
func (pc Call) file() string {
pcFix := uintptr(pc) - 1 // work around for go issue #7690
fn := runtime.FuncForPC(pcFix)
if fn == nil {
return "???"
}
file, _ := fn.FileLine(pcFix)
return file
}
// Trace records a sequence of function invocations from a goroutine stack.
type Trace []Call
// Format implements fmt.Formatter by printing the Trace as square brackes ([,
// ]) surrounding a space separated list of Calls each formatted with the
// supplied verb and options.
func (pcs Trace) Format(s fmt.State, c rune) {
s.Write([]byte("["))
for i, pc := range pcs {
if i > 0 {
s.Write([]byte(" "))
}
pc.Format(s, c)
}
s.Write([]byte("]"))
}
// TrimBelow returns a slice of the Trace with all entries below pc removed.
func (pcs Trace) TrimBelow(pc Call) Trace {
for len(pcs) > 0 && pcs[0] != pc {
pcs = pcs[1:]
}
return pcs
}
// TrimAbove returns a slice of the Trace with all entries above pc removed.
func (pcs Trace) TrimAbove(pc Call) Trace {
for len(pcs) > 0 && pcs[len(pcs)-1] != pc {
pcs = pcs[:len(pcs)-1]
}
return pcs
}
// TrimBelowName returns a slice of the Trace with all entries below the
// lowest with function name name removed.
func (pcs Trace) TrimBelowName(name string) Trace {
for len(pcs) > 0 && pcs[0].name() != name {
pcs = pcs[1:]
}
return pcs
}
// TrimAboveName returns a slice of the Trace with all entries above the
// highest with function name name removed.
func (pcs Trace) TrimAboveName(name string) Trace {
for len(pcs) > 0 && pcs[len(pcs)-1].name() != name {
pcs = pcs[:len(pcs)-1]
}
return pcs
}
var goroot string
func init() {
goroot = filepath.ToSlash(runtime.GOROOT())
if runtime.GOOS == "windows" {
goroot = strings.ToLower(goroot)
}
}
func inGoroot(path string) bool {
if runtime.GOOS == "windows" {
path = strings.ToLower(path)
}
return strings.HasPrefix(path, goroot)
}
// TrimRuntime returns a slice of the Trace with the topmost entries from the
// go runtime removed. It considers any calls originating from files under
// GOROOT as part of the runtime.
func (pcs Trace) TrimRuntime() Trace {
for len(pcs) > 0 && inGoroot(pcs[len(pcs)-1].file()) {
pcs = pcs[:len(pcs)-1]
}
return pcs
}

+ 0
- 19
Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_pool.go View File

@ -1,19 +0,0 @@
// +build go1.3
package stack
import (
"sync"
)
var pcStackPool = sync.Pool{
New: func() interface{} { return make([]uintptr, 1000) },
}
func poolBuf() []uintptr {
return pcStackPool.Get().([]uintptr)
}
func putPoolBuf(p []uintptr) {
pcStackPool.Put(p)
}

+ 0
- 27
Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_pool_chan.go View File

@ -1,27 +0,0 @@
// +build !go1.3 appengine
package stack
const (
stackPoolSize = 64
)
var (
pcStackPool = make(chan []uintptr, stackPoolSize)
)
func poolBuf() []uintptr {
select {
case p := <-pcStackPool:
return p
default:
return make([]uintptr, 1000)
}
}
func putPoolBuf(p []uintptr) {
select {
case pcStackPool <- p:
default:
}
}

+ 0
- 231
Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_test.go View File

@ -1,231 +0,0 @@
package stack_test
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
"testing"
"github.com/inconshreveable/log15/stack"
)
type testType struct{}
func (tt testType) testMethod() (pc uintptr, file string, line int, ok bool) {
return runtime.Caller(0)
}
func TestCallFormat(t *testing.T) {
t.Parallel()
pc, file, line, ok := runtime.Caller(0)
if !ok {
t.Fatal("runtime.Caller(0) failed")
}
gopathSrc := filepath.Join(os.Getenv("GOPATH"), "src")
relFile, err := filepath.Rel(gopathSrc, file)
if err != nil {
t.Fatalf("failed to determine path relative to GOPATH: %v", err)
}
relFile = filepath.ToSlash(relFile)
pc2, file2, line2, ok2 := testType{}.testMethod()
if !ok2 {
t.Fatal("runtime.Caller(0) failed")
}
relFile2, err := filepath.Rel(gopathSrc, file)
if err != nil {
t.Fatalf("failed to determine path relative to GOPATH: %v", err)
}
relFile2 = filepath.ToSlash(relFile2)
data := []struct {
pc uintptr
desc string
fmt string
out string
}{
{0, "error", "%s", "%!s(NOFUNC)"},
{pc, "func", "%s", path.Base(file)},
{pc, "func", "%+s", relFile},
{pc, "func", "%#s", file},
{pc, "func", "%d", fmt.Sprint(line)},
{pc, "func", "%n", "TestCallFormat"},
{pc, "func", "%+n", runtime.FuncForPC(pc).Name()},
{pc, "func", "%v", fmt.Sprint(path.Base(file), ":", line)},
{pc, "func", "%+v", fmt.Sprint(relFile, ":", line)},
{pc, "func", "%#v", fmt.Sprint(file, ":", line)},
{pc, "func", "%v|%[1]n()", fmt.Sprint(path.Base(file), ":", line, "|", "TestCallFormat()")},
{pc2, "meth", "%s", path.Base(file2)},
{pc2, "meth", "%+s", relFile2},
{pc2, "meth", "%#s", file2},
{pc2, "meth", "%d", fmt.Sprint(line2)},
{pc2, "meth", "%n", "testType.testMethod"},
{pc2, "meth", "%+n", runtime.FuncForPC(pc2).Name()},
{pc2, "meth", "%v", fmt.Sprint(path.Base(file2), ":", line2)},
{pc2, "meth", "%+v", fmt.Sprint(relFile2, ":", line2)},
{pc2, "meth", "%#v", fmt.Sprint(file2, ":", line2)},
{pc2, "meth", "%v|%[1]n()", fmt.Sprint(path.Base(file2), ":", line2, "|", "testType.testMethod()")},
}
for _, d := range data {
got := fmt.Sprintf(d.fmt, stack.Call(d.pc))
if got != d.out {
t.Errorf("fmt.Sprintf(%q, Call(%s)) = %s, want %s", d.fmt, d.desc, got, d.out)
}
}
}
func BenchmarkCallVFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprint(ioutil.Discard, stack.Call(pc))
}
}
func BenchmarkCallPlusVFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%+v", stack.Call(pc))
}
}
func BenchmarkCallSharpVFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%#v", stack.Call(pc))
}
}
func BenchmarkCallSFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%s", stack.Call(pc))
}
}
func BenchmarkCallPlusSFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%+s", stack.Call(pc))
}
}
func BenchmarkCallSharpSFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%#s", stack.Call(pc))
}
}
func BenchmarkCallDFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%d", stack.Call(pc))
}
}
func BenchmarkCallNFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%n", stack.Call(pc))
}
}
func BenchmarkCallPlusNFmt(b *testing.B) {
pc, _, _, ok := runtime.Caller(0)
if !ok {
b.Fatal("runtime.Caller(0) failed")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Fprintf(ioutil.Discard, "%+n", stack.Call(pc))
}
}
func BenchmarkCallers(b *testing.B) {
for i := 0; i < b.N; i++ {
stack.Callers()
}
}
func deepStack(depth int, b *testing.B) stack.Trace {
if depth > 0 {
return deepStack(depth-1, b)
}
b.StartTimer()
s := stack.Callers()
b.StopTimer()
return s
}
func BenchmarkCallers10(b *testing.B) {
b.StopTimer()
for i := 0; i < b.N; i++ {
deepStack(10, b)
}
}
func BenchmarkCallers50(b *testing.B) {
b.StopTimer()
for i := 0; i < b.N; i++ {
deepStack(50, b)
}
}
func BenchmarkCallers100(b *testing.B) {
b.StopTimer()
for i := 0; i < b.N; i++ {
deepStack(100, b)
}
}

+ 0
- 21
Godeps/_workspace/src/github.com/inconshreveable/log15/term/LICENSE View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Simon Eskildsen
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.

+ 0
- 13
Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_appengine.go View File

@ -1,13 +0,0 @@
// Based on ssh/terminal:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build appengine
package term
// IsTty always returns false on AppEngine.
func IsTty(fd uintptr) bool {
return false
}

+ 0
- 12
Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_darwin.go View File

@ -1,12 +0,0 @@
// Based on ssh/terminal:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package term
import "syscall"
const ioctlReadTermios = syscall.TIOCGETA
type Termios syscall.Termios

+ 0
- 18
Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_freebsd.go View File

@ -1,18 +0,0 @@
package term
import (
"syscall"
)
const ioctlReadTermios = syscall.TIOCGETA
// Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin.
type Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed uint32
Ospeed uint32
}

+ 0
- 14
Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_linux.go View File

@ -1,14 +0,0 @@
// Based on ssh/terminal:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !appengine
package term
import "syscall"
const ioctlReadTermios = syscall.TCGETS
type Termios syscall.Termios

+ 0
- 20
Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_notwindows.go View File

@ -1,20 +0,0 @@
// Based on ssh/terminal:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!appengine darwin freebsd
package term
import (
"syscall"
"unsafe"
)
// IsTty returns true if the given file descriptor is a terminal.
func IsTty(fd uintptr) bool {
var termios Termios
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0
}

+ 0
- 26
Godeps/_workspace/src/github.com/inconshreveable/log15/term/terminal_windows.go View File

@ -1,26 +0,0 @@
// Based on ssh/terminal:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package term
import (
"syscall"
"unsafe"
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var (
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
)
// IsTty returns true if the given file descriptor is a terminal.
func IsTty(fd uintptr) bool {
var st uint32
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
}

+ 0
- 42
Godeps/_workspace/src/github.com/mattn/go-colorable/README.md View File

@ -1,42 +0,0 @@
# 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.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)

+ 0
- 16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go View File

@ -1,16 +0,0 @@
// +build !windows
package colorable
import (
"io"
"os"
)
func NewColorableStdout() io.Writer {
return os.Stdout
}
func NewColorableStderr() io.Writer {
return os.Stderr
}

+ 0
- 594
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_windows.go View File

@ -1,594 +0,0 @@
package colorable
import (
"bytes"
"fmt"
"io"
"os"
"strconv"
"strings"
"syscall"
"unsafe"
"github.com/mattn/go-isatty"
)
const (
foregroundBlue = 0x1
foregroundGreen = 0x2
foregroundRed = 0x4
foregroundIntensity = 0x8
foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
backgroundBlue = 0x10
backgroundGreen = 0x20
backgroundRed = 0x40
backgroundIntensity = 0x80
backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
)
type wchar uint16
type short int16
type dword uint32
type word uint16
type coord struct {
x short
y short
}
type smallRect struct {
left short
top short
right short
bottom short
}
type consoleScreenBufferInfo struct {
size coord
cursorPosition coord
attributes word
window smallRect
maximumWindowSize coord
}
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
)
type Writer struct {
out io.Writer
handle syscall.Handle
lastbuf bytes.Buffer
oldattr word
}
func NewColorableStdout() io.Writer {
var csbi consoleScreenBufferInfo
out := os.Stdout
if !isatty.IsTerminal(out.Fd()) {
return out
}
handle := syscall.Handle(out.Fd())
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
}
func NewColorableStderr() io.Writer {
var csbi consoleScreenBufferInfo
out := os.Stderr
if !isatty.IsTerminal(out.Fd()) {
return out
}
handle := syscall.Handle(out.Fd())
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
}
var color256 = map[int]int{
0: 0x000000,
1: 0x800000,
2: 0x008000,
3: 0x808000,
4: 0x000080,
5: 0x800080,
6: 0x008080,
7: 0xc0c0c0,
8: 0x808080,
9: 0xff0000,
10: 0x00ff00,
11: 0xffff00,
12: 0x0000ff,
13: 0xff00ff,
14: 0x00ffff,
15: 0xffffff,
16: 0x000000,
17: 0x00005f,
18: 0x000087,
19: 0x0000af,
20: 0x0000d7,
21: 0x0000ff,
22: 0x005f00,
23: 0x005f5f,
24: 0x005f87,
25: 0x005faf,
26: 0x005fd7,
27: 0x005fff,
28: 0x008700,
29: 0x00875f,
30: 0x008787,
31: 0x0087af,
32: 0x0087d7,
33: 0x0087ff,
34: 0x00af00,
35: 0x00af5f,
36: 0x00af87,
37: 0x00afaf,
38: 0x00afd7,
39: 0x00afff,
40: 0x00d700,
41: 0x00d75f,
42: 0x00d787,
43: 0x00d7af,
44: 0x00d7d7,
45: 0x00d7ff,
46: 0x00ff00,
47: 0x00ff5f,
48: 0x00ff87,
49: 0x00ffaf,
50: 0x00ffd7,
51: 0x00ffff,
52: 0x5f0000,
53: 0x5f005f,
54: 0x5f0087,
55: 0x5f00af,
56: 0x5f00d7,
57: 0x5f00ff,
58: 0x5f5f00,
59: 0x5f5f5f,
60: 0x5f5f87,
61: 0x5f5faf,
62: 0x5f5fd7,
63: 0x5f5fff,
64: 0x5f8700,
65: 0x5f875f,
66: 0x5f8787,
67: 0x5f87af,
68: 0x5f87d7,
69: 0x5f87ff,
70: 0x5faf00,
71: 0x5faf5f,
72: 0x5faf87,
73: 0x5fafaf,
74: 0x5fafd7,
75: 0x5fafff,
76: 0x5fd700,
77: 0x5fd75f,
78: 0x5fd787,
79: 0x5fd7af,
80: 0x5fd7d7,
81: 0x5fd7ff,
82: 0x5fff00,
83: 0x5fff5f,
84: 0x5fff87,
85: 0x5fffaf,
86: 0x5fffd7,
87: 0x5fffff,
88: 0x870000,
89: 0x87005f,
90: 0x870087,
91: 0x8700af,
92: 0x8700d7,
93: 0x8700ff,
94: 0x875f00,
95: 0x875f5f,
96: 0x875f87,
97: 0x875faf,
98: 0x875fd7,
99: 0x875fff,
100: 0x878700,
101: 0x87875f,
102: 0x878787,
103: 0x8787af,
104: 0x8787d7,
105: 0x8787ff,
106: 0x87af00,
107: 0x87af5f,
108: 0x87af87,
109: 0x87afaf,
110: 0x87afd7,
111: 0x87afff,
112: 0x87d700,
113: 0x87d75f,
114: 0x87d787,
115: 0x87d7af,
116: 0x87d7d7,
117: 0x87d7ff,
118: 0x87ff00,
119: 0x87ff5f,
120: 0x87ff87,
121: 0x87ffaf,
122: 0x87ffd7,
123: 0x87ffff,
124: 0xaf0000,
125: 0xaf005f,
126: 0xaf0087,
127: 0xaf00af,
128: 0xaf00d7,
129: 0xaf00ff,
130: 0xaf5f00,
131: 0xaf5f5f,
132: 0xaf5f87,
133: 0xaf5faf,
134: 0xaf5fd7,
135: 0xaf5fff,
136: 0xaf8700,
137: 0xaf875f,
138: 0xaf8787,
139: 0xaf87af,
140: 0xaf87d7,
141: 0xaf87ff,
142: 0xafaf00,
143: 0xafaf5f,
144: 0xafaf87,
145: 0xafafaf,
146: 0xafafd7,
147: 0xafafff,
148: 0xafd700,
149: 0xafd75f,
150: 0xafd787,
151: 0xafd7af,
152: 0xafd7d7,
153: 0xafd7ff,
154: 0xafff00,
155: 0xafff5f,
156: 0xafff87,
157: 0xafffaf,
158: 0xafffd7,
159: 0xafffff,
160: 0xd70000,
161: 0xd7005f,
162: 0xd70087,
163: 0xd700af,
164: 0xd700d7,
165: 0xd700ff,
166: 0xd75f00,
167: 0xd75f5f,
168: 0xd75f87,
169: 0xd75faf,
170: 0xd75fd7,
171: 0xd75fff,
172: 0xd78700,
173: 0xd7875f,
174: 0xd78787,
175: 0xd787af,
176: 0xd787d7,
177: 0xd787ff,
178: 0xd7af00,
179: 0xd7af5f,
180: 0xd7af87,
181: 0xd7afaf,
182: 0xd7afd7,
183: 0xd7afff,
184: 0xd7d700,
185: 0xd7d75f,
186: 0xd7d787,
187: 0xd7d7af,
188: 0xd7d7d7,
189: 0xd7d7ff,
190: 0xd7ff00,
191: 0xd7ff5f,
192: 0xd7ff87,
193: 0xd7ffaf,
194: 0xd7ffd7,
195: 0xd7ffff,
196: 0xff0000,
197: 0xff005f,
198: 0xff0087,
199: 0xff00af,
200: 0xff00d7,
201: 0xff00ff,
202: 0xff5f00,
203: 0xff5f5f,
204: 0xff5f87,
205: 0xff5faf,
206: 0xff5fd7,
207: 0xff5fff,
208: 0xff8700,
209: 0xff875f,
210: 0xff8787,
211: 0xff87af,
212: 0xff87d7,
213: 0xff87ff,
214: 0xffaf00,
215: 0xffaf5f,
216: 0xffaf87,
217: 0xffafaf,
218: 0xffafd7,
219: 0xffafff,
220: 0xffd700,
221: 0xffd75f,
222: 0xffd787,
223: 0xffd7af,
224: 0xffd7d7,
225: 0xffd7ff,
226: 0xffff00,
227: 0xffff5f,
228: 0xffff87,
229: 0xffffaf,
230: 0xffffd7,
231: 0xffffff,
232: 0x080808,
233: 0x121212,
234: 0x1c1c1c,
235: 0x262626,
236: 0x303030,
237: 0x3a3a3a,
238: 0x444444,
239: 0x4e4e4e,
240: 0x585858,
241: 0x626262,
242: 0x6c6c6c,
243: 0x767676,
244: 0x808080,
245: 0x8a8a8a,
246: 0x949494,
247: 0x9e9e9e,
248: 0xa8a8a8,
249: 0xb2b2b2,
250: 0xbcbcbc,
251: 0xc6c6c6,
252: 0xd0d0d0,
253: 0xdadada,
254: 0xe4e4e4,
255: 0xeeeeee,
}
func (w *Writer) Write(data []byte) (n int, err error) {
var csbi consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
er := bytes.NewBuffer(data)
loop:
for {
r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
if r1 == 0 {
break loop
}
c1, _, err := er.ReadRune()
if err != nil {
break loop
}
if c1 != 0x1b {
fmt.Fprint(w.out, string(c1))
continue
}
c2, _, err := er.ReadRune()
if err != nil {
w.lastbuf.WriteRune(c1)
break loop
}
if c2 != 0x5b {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
continue
}
var buf bytes.Buffer
var m rune
for {
c, _, err := er.ReadRune()
if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.Write(buf.Bytes())
break loop
}
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
m = c
break
}
buf.Write([]byte(string(c)))
}
switch m {
case 'm':
attr := csbi.attributes
cs := buf.String()
if cs == "" {
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
continue
}
token := strings.Split(cs, ";")
for i, ns := range token {
if n, err = strconv.Atoi(ns); err == nil {
switch {
case n == 0 || n == 100:
attr = w.oldattr
case 1 <= n && n <= 5:
attr |= foregroundIntensity
case n == 7:
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
case 22 == n || n == 25 || n == 25:
attr |= foregroundIntensity
case n == 27:
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
case 30 <= n && n <= 37:
attr = (attr & backgroundMask)
if (n-30)&1 != 0 {
attr |= foregroundRed
}
if (n-30)&2 != 0 {
attr |= foregroundGreen
}
if (n-30)&4 != 0 {
attr |= foregroundBlue
}
case n == 38: // set foreground color.
if i < len(token)-2 && token[i+1] == "5" {
if n256, err := strconv.Atoi(token[i+2]); err == nil {
if n256foreAttr == nil {
n256setup()
}
attr &= backgroundMask
attr |= n256foreAttr[n256]
i += 2
}
} else {
attr = attr & (w.oldattr & backgroundMask)
}
case n == 39: // reset foreground color.
attr &= backgroundMask
attr |= w.oldattr & foregroundMask
case 40 <= n && n <= 47:
attr = (attr & foregroundMask)
if (n-40)&1 != 0 {
attr |= backgroundRed
}
if (n-40)&2 != 0 {
attr |= backgroundGreen
}
if (n-40)&4 != 0 {
attr |= backgroundBlue
}
case n == 48: // set background color.
if i < len(token)-2 && token[i+1] == "5" {
if n256, err := strconv.Atoi(token[i+2]); err == nil {
if n256backAttr == nil {
n256setup()
}
attr &= foregroundMask
attr |= n256backAttr[n256]
i += 2
}
} else {
attr = attr & (w.oldattr & foregroundMask)
}
case n == 49: // reset foreground color.
attr &= foregroundMask
attr |= w.oldattr & backgroundMask
}
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
}
}
}
}
return len(data) - w.lastbuf.Len(), nil
}
type consoleColor struct {
red bool
green bool
blue bool
intensity bool
}
func minmax3(a, b, c int) (min, max int) {
if a < b {
if b < c {
return a, c
} else if a < c {
return a, b
} else {
return c, b
}
} else {
if a < c {
return b, c
} else if b < c {
return b, a
} else {
return c, a
}
}
}
func toConsoleColor(rgb int) (c consoleColor) {
r, g, b := (rgb&0xFF0000)>>16, (rgb&0x00FF00)>>8, rgb&0x0000FF
min, max := minmax3(r, g, b)
a := (min + max) / 2
if r < 128 && g < 128 && b < 128 {
if r >= a {
c.red = true
}
if g >= a {
c.green = true
}
if b >= a {
c.blue = true
}
// non-intensed white is lighter than intensed black, so swap those.
if c.red && c.green && c.blue {
c.red, c.green, c.blue = false, false, false
c.intensity = true
}
} else {
if min < 128 {
min = 128
a = (min + max) / 2
}
if r >= a {
c.red = true
}
if g >= a {
c.green = true
}
if b >= a {
c.blue = true
}
c.intensity = true
// intensed black is darker than non-intensed white, so swap those.
if !c.red && !c.green && !c.blue {
c.red, c.green, c.blue = true, true, true
c.intensity = false
}
}
return c
}
func (c consoleColor) foregroundAttr() (attr word) {
if c.red {
attr |= foregroundRed
}
if c.green {
attr |= foregroundGreen
}
if c.blue {
attr |= foregroundBlue
}
if c.intensity {
attr |= foregroundIntensity
}
return
}
func (c consoleColor) backgroundAttr() (attr word) {
if c.red {
attr |= backgroundRed
}
if c.green {
attr |= backgroundGreen
}
if c.blue {
attr |= backgroundBlue
}
if c.intensity {
attr |= backgroundIntensity
}
return
}
var n256foreAttr []word
var n256backAttr []word
func n256setup() {
n256foreAttr = make([]word, 256)
n256backAttr = make([]word, 256)
for i, rgb := range color256 {
c := toConsoleColor(rgb)
n256foreAttr[i] = c.foregroundAttr()
n256backAttr[i] = c.backgroundAttr()
}
}

+ 0
- 9
Godeps/_workspace/src/github.com/naoina/go-stringutil/.travis.yml View File

@ -1,9 +0,0 @@
language: go
go:
- 1.3
- 1.4
- tip
install:
- go get -v github.com/naoina/go-stringutil
script:
- go test -v ./... -bench . -benchmem

+ 0
- 19
Godeps/_workspace/src/github.com/naoina/go-stringutil/LICENSE View File

@ -1,19 +0,0 @@
Copyright (c) 2015 Naoya Inada <naoina@kuune.org>
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.

+ 0
- 13
Godeps/_workspace/src/github.com/naoina/go-stringutil/README.md View File

@ -1,13 +0,0 @@
# stringutil [![Build Status](https://travis-ci.org/naoina/go-stringutil.png?branch=master)](https://travis-ci.org/naoina/go-stringutil)
## Installation
go get -u github.com/naoina/go-stringutil
## Documentation
See https://godoc.org/github.com/naoina/go-stringutil
## License
MIT

+ 0
- 120
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings.go View File

@ -1,120 +0,0 @@
package stringutil
import (
"bytes"
"unicode"
)
// ToUpperCamelCase returns a copy of the string s with all Unicode letters mapped to their camel case.
// It will convert to upper case previous letter of '_' and first letter, and remove letter of '_'.
func ToUpperCamelCase(s string) string {
if s == "" {
return ""
}
upper := true
var result bytes.Buffer
for _, c := range s {
if c == '_' {
upper = true
continue
}
if upper {
result.WriteRune(unicode.ToUpper(c))
upper = false
continue
}
result.WriteRune(c)
}
return result.String()
}
// ToUpperCamelCaseASCII is similar to ToUpperCamelCase, but optimized for
// only the ASCII characters.
// ToUpperCamelCaseASCII is faster than ToUpperCamelCase, but doesn't work if
// contains non-ASCII characters.
func ToUpperCamelCaseASCII(s string) string {
if s == "" {
return ""
}
upper := true
result := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
if c == '_' {
upper = true
continue
}
if upper {
result = append(result, toUpperASCII(c))
upper = false
continue
}
result = append(result, c)
}
return string(result)
}
// ToSnakeCase returns a copy of the string s with all Unicode letters mapped to their snake case.
// It will insert letter of '_' at position of previous letter of uppercase and all
// letters convert to lower case.
func ToSnakeCase(s string) string {
if s == "" {
return ""
}
var result bytes.Buffer
for _, c := range s {
if unicode.IsUpper(c) {
result.WriteByte('_')
}
result.WriteRune(unicode.ToLower(c))
}
s = result.String()
if s[0] == '_' {
return s[1:]
}
return s
}
// ToSnakeCaseASCII is similar to ToSnakeCase, but optimized for only the ASCII
// characters.
// ToSnakeCaseASCII is faster than ToSnakeCase, but doesn't work correctly if
// contains non-ASCII characters.
func ToSnakeCaseASCII(s string) string {
if s == "" {
return ""
}
result := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
if isUpperASCII(c) {
result = append(result, '_')
}
result = append(result, toLowerASCII(c))
}
if result[0] == '_' {
return string(result[1:])
}
return string(result)
}
func isUpperASCII(c byte) bool {
return 'A' <= c && c <= 'Z'
}
func isLowerASCII(c byte) bool {
return 'a' <= c && c <= 'z'
}
func toUpperASCII(c byte) byte {
if isLowerASCII(c) {
return c - ('a' - 'A')
}
return c
}
func toLowerASCII(c byte) byte {
if isUpperASCII(c) {
return c + 'a' - 'A'
}
return c
}

+ 0
- 35
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go View File

@ -1,35 +0,0 @@
package stringutil_test
import (
"testing"
"github.com/naoina/go-stringutil"
)
var benchcaseForCamelCase = "the_quick_brown_fox_jumps_over_the_lazy_dog"
func BenchmarkToUpperCamelCase(b *testing.B) {
for i := 0; i < b.N; i++ {
stringutil.ToUpperCamelCase(benchcaseForCamelCase)
}
}
func BenchmarkToUpperCamelCaseASCII(b *testing.B) {
for i := 0; i < b.N; i++ {
stringutil.ToUpperCamelCaseASCII(benchcaseForCamelCase)
}
}
var benchcaseForSnakeCase = "TheQuickBrownFoxJumpsOverTheLazyDog"
func BenchmarkToSnakeCase(b *testing.B) {
for i := 0; i < b.N; i++ {
stringutil.ToSnakeCase(benchcaseForSnakeCase)
}
}
func BenchmarkToSnakeCaseASCII(b *testing.B) {
for i := 0; i < b.N; i++ {
stringutil.ToSnakeCaseASCII(benchcaseForSnakeCase)
}
}

+ 0
- 88
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go View File

@ -1,88 +0,0 @@
package stringutil_test
import (
"reflect"
"testing"
"github.com/naoina/go-stringutil"
)
func TestToUpperCamelCase(t *testing.T) {
for _, v := range []struct {
input, expect string
}{
{"", ""},
{"thequickbrownfoxoverthelazydog", "Thequickbrownfoxoverthelazydog"},
{"thequickbrownfoxoverthelazydoG", "ThequickbrownfoxoverthelazydoG"},
{"thequickbrownfoxoverthelazydo_g", "ThequickbrownfoxoverthelazydoG"},
{"TheQuickBrownFoxJumpsOverTheLazyDog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
{"the_Quick_Brown_Fox_Jumps_Over_The_Lazy_Dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
{"the_quick_brown_fox_over_the_lazy_dog", "TheQuickBrownFoxOverTheLazyDog"},
} {
actual := stringutil.ToUpperCamelCase(v.input)
expect := v.expect
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`stringutil.ToUpperCamelCase(%#v) => %#v; want %#v`, v.input, actual, expect)
}
}
}
func TestToUpperCamelCaseASCII(t *testing.T) {
for _, v := range []struct {
input, expect string
}{
{"", ""},
{"thequickbrownfoxoverthelazydog", "Thequickbrownfoxoverthelazydog"},
{"thequickbrownfoxoverthelazydoG", "ThequickbrownfoxoverthelazydoG"},
{"thequickbrownfoxoverthelazydo_g", "ThequickbrownfoxoverthelazydoG"},
{"TheQuickBrownFoxJumpsOverTheLazyDog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
{"the_Quick_Brown_Fox_Jumps_Over_The_Lazy_Dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
} {
actual := stringutil.ToUpperCamelCaseASCII(v.input)
expect := v.expect
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`stringutil.ToUpperCamelCaseASCII(%#v) => %#v; want %#v`, v.input, actual, expect)
}
}
}
func TestToSnakeCase(t *testing.T) {
for _, v := range []struct {
input, expect string
}{
{"", ""},
{"thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
{"Thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
{"ThequickbrownfoxjumpsoverthelazydoG", "thequickbrownfoxjumpsoverthelazydo_g"},
{"TheQuickBrownFoxJumpsOverTheLazyDog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
{"TheQuickBrownFoxOverTheLazyDog", "the_quick_brown_fox_over_the_lazy_dog"},
} {
actual := stringutil.ToSnakeCase(v.input)
expect := v.expect
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`stringutil.ToSnakeCase(%#v) => %#v; want %#v`, v.input, actual, expect)
}
}
}
func TestToSnakeCaseASCII(t *testing.T) {
for _, v := range []struct {
input, expect string
}{
{"", ""},
{"thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
{"Thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
{"ThequickbrownfoxjumpsoverthelazydoG", "thequickbrownfoxjumpsoverthelazydo_g"},
{"TheQuickBrownFoxJumpsOverTheLazyDog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
} {
actual := stringutil.ToSnakeCaseASCII(v.input)
expect := v.expect
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`stringutil.ToSnakeCaseASCII(%#v) => %#v; want %#v`, v.input, actual, expect)
}
}
}

+ 0
- 11
Godeps/_workspace/src/github.com/naoina/toml/.travis.yml View File

@ -1,11 +0,0 @@
language: go
go:
- 1.3
- tip
install:
- go get -v ./...
script:
- go test ./...

+ 0
- 19
Godeps/_workspace/src/github.com/naoina/toml/LICENSE View File

@ -1,19 +0,0 @@
Copyright (c) 2014 Naoya Inada <naoina@kuune.org>
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.

+ 0
- 16
Godeps/_workspace/src/github.com/naoina/toml/Makefile View File

@ -1,16 +0,0 @@
GO = go
PEG = peg
.SUFFIXES: .peg .peg.go
.PHONY: all test clean
all: parse.peg.go
.peg.peg.go:
$(PEG) -switch -inline $<
test: all
$(GO) test ./...
clean:
$(RM) *.peg.go

+ 0
- 364
Godeps/_workspace/src/github.com/naoina/toml/README.md View File

@ -1,364 +0,0 @@
# TOML parser and encoder library for Golang [![Build Status](https://travis-ci.org/naoina/toml.png?branch=master)](https://travis-ci.org/naoina/toml)
[TOML](https://github.com/toml-lang/toml) parser and encoder library for [Golang](http://golang.org/).
This library is compatible with TOML version [v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md).
## Installation
go get -u github.com/naoina/toml
## Usage
The following TOML save as `example.toml`.
```toml
# This is a TOML document. Boom.
title = "TOML Example"
[owner]
name = "Lance Uppercut"
dob = 1979-05-27T07:32:00-08:00 # First class dates? Why not?
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
[servers]
# You can indent as you please. Tabs or spaces. TOML don't care.
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
[clients]
data = [ ["gamma", "delta"], [1, 2] ]
# Line breaks are OK when inside arrays
hosts = [
"alpha",
"omega"
]
```
Then above TOML will mapping to `tomlConfig` struct using `toml.Unmarshal`.
```go
package main
import (
"io/ioutil"
"os"
"time"
"github.com/naoina/toml"
)
type tomlConfig struct {
Title string
Owner struct {
Name string
Dob time.Time
}
Database struct {
Server string
Ports []int
ConnectionMax uint
Enabled bool
}
Servers map[string]Server
Clients struct {
Data [][]interface{}
Hosts []string
}
}
type Server struct {
IP string
DC string
}
func main() {
f, err := os.Open("example.toml")
if err != nil {
panic(err)
}
defer f.Close()
buf, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
var config tomlConfig
if err := toml.Unmarshal(buf, &config); err != nil {
panic(err)
}
// then to use the unmarshaled config...
}
```
## Mappings
A key and value of TOML will map to the corresponding field.
The fields of struct for mapping must be exported.
The rules of the mapping of key are following:
#### Exact matching
```toml
timeout_seconds = 256
```
```go
type Config struct {
Timeout_seconds int
}
```
#### Camelcase matching
```toml
server_name = "srv1"
```
```go
type Config struct {
ServerName string
}
```
#### Uppercase matching
```toml
ip = "10.0.0.1"
```
```go
type Config struct {
IP string
}
```
See the following examples for the value mappings.
### String
```toml
val = "string"
```
```go
type Config struct {
Val string
}
```
### Integer
```toml
val = 100
```
```go
type Config struct {
Val int
}
```
All types that can be used are following:
* int8 (from `-128` to `127`)
* int16 (from `-32768` to `32767`)
* int32 (from `-2147483648` to `2147483647`)
* int64 (from `-9223372036854775808` to `9223372036854775807`)
* int (same as `int32` on 32bit environment, or `int64` on 64bit environment)
* uint8 (from `0` to `255`)
* uint16 (from `0` to `65535`)
* uint32 (from `0` to `4294967295`)
* uint64 (from `0` to `18446744073709551615`)
* uint (same as `uint` on 32bit environment, or `uint64` on 64bit environment)
### Float
```toml
val = 3.1415
```
```go
type Config struct {
Val float32
}
```
All types that can be used are following:
* float32
* float64
### Boolean
```toml
val = true
```
```go
type Config struct {
Val bool
}
```
### Datetime
```toml
val = 2014-09-28T21:27:39Z
```
```go
type Config struct {
Val time.Time
}
```
### Array
```toml
val = ["a", "b", "c"]
```
```go
type Config struct {
Val []string
}
```
Also following examples all can be mapped:
```toml
val1 = [1, 2, 3]
val2 = [["a", "b"], ["c", "d"]]
val3 = [[1, 2, 3], ["a", "b", "c"]]
val4 = [[1, 2, 3], [["a", "b"], [true, false]]]
```
```go
type Config struct {
Val1 []int
Val2 [][]string
Val3 [][]interface{}
Val4 [][]interface{}
}
```
### Table
```toml
[server]
type = "app"
[server.development]
ip = "10.0.0.1"
[server.production]
ip = "10.0.0.2"
```
```go
type Config struct {
Server map[string]Server
}
type Server struct {
IP string
}
```
You can also use the following struct instead of map of struct.
```go
type Config struct {
Server struct {
Development Server
Production Server
}
}
type Server struct {
IP string
}
```
### Array of Tables
```toml
[[fruit]]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"
[[fruit.variety]]
name = "red delicious"
[[fruit.variety]]
name = "granny smith"
[[fruit]]
name = "banana"
[[fruit.variety]]
name = "plantain"
```
```go
type Config struct {
Fruit []struct {
Name string
Physical struct {
Color string
Shape string
}
Variety []struct {
Name string
}
}
}
```
### Using `toml.UnmarshalTOML` interface
```toml
duration = "10s"
```
```go
import time
type Config struct {
Duration Duration
}
type Duration struct {
time.Duration
}
func (d *Duration) UnmarshalTOML(data []byte) error {
d.Duration, err := time.ParseDuration(string(data))
return err
}
```
## API documentation
See [Godoc](http://godoc.org/github.com/naoina/toml).
## License
MIT

+ 0
- 184
Godeps/_workspace/src/github.com/naoina/toml/ast/ast.go View File

@ -1,184 +0,0 @@
package ast
import (
"strconv"
"time"
)
type Position struct {
Begin int
End int
}
type Value interface {
Pos() int
End() int
Source() string
}
type String struct {
Position Position
Value string
Data []rune
}
func (s *String) Pos() int {
return s.Position.Begin
}
func (s *String) End() int {
return s.Position.End
}
func (s *String) Source() string {
return string(s.Data)
}
type Integer struct {
Position Position
Value string
Data []rune
}
func (i *Integer) Pos() int {
return i.Position.Begin
}
func (i *Integer) End() int {
return i.Position.End
}
func (i *Integer) Source() string {
return string(i.Data)
}
func (i *Integer) Int() (int64, error) {
return strconv.ParseInt(i.Value, 10, 64)
}
type Float struct {
Position Position
Value string
Data []rune
}
func (f *Float) Pos() int {
return f.Position.Begin
}
func (f *Float) End() int {
return f.Position.End
}
func (f *Float) Source() string {
return string(f.Data)
}
func (f *Float) Float() (float64, error) {
return strconv.ParseFloat(f.Value, 64)
}
type Boolean struct {
Position Position
Value string
Data []rune
}
func (b *Boolean) Pos() int {
return b.Position.Begin
}
func (b *Boolean) End() int {
return b.Position.End
}
func (b *Boolean) Source() string {
return string(b.Data)
}
func (b *Boolean) Boolean() (bool, error) {
return strconv.ParseBool(b.Value)
}
type Datetime struct {
Position Position
Value string
Data []rune
}
func (d *Datetime) Pos() int {
return d.Position.Begin
}
func (d *Datetime) End() int {
return d.Position.End
}
func (d *Datetime) Source() string {
return string(d.Data)
}
func (d *Datetime) Time() (time.Time, error) {
return time.Parse(time.RFC3339Nano, d.Value)
}
type Array struct {
Position Position
Value []Value
Data []rune
}
func (a *Array) Pos() int {
return a.Position.Begin
}
func (a *Array) End() int {
return a.Position.End
}
func (a *Array) Source() string {
return string(a.Data)
}
type TableType uint8
const (
TableTypeNormal TableType = iota
TableTypeArray
)
var tableTypes = [...]string{
"normal",
"array",
}
func (t TableType) String() string {
return tableTypes[t]
}
type Table struct {
Position Position
Line int
Name string
Fields map[string]interface{}
Type TableType
Data []rune
}
func (t *Table) Pos() int {
return t.Position.Begin
}
func (t *Table) End() int {
return t.Position.End
}
func (t *Table) Source() string {
return string(t.Data)
}
type KeyValue struct {
Key string
Value Value
Line int
}

+ 0
- 649
Godeps/_workspace/src/github.com/naoina/toml/decode.go View File

@ -1,649 +0,0 @@
package toml
import (
"fmt"
"reflect"
"strconv"
"strings"
"github.com/naoina/toml/ast"
)
const (
tableSeparator = '.'
)
var (
escapeReplacer = strings.NewReplacer(
"\b", "\\n",
"\f", "\\f",
"\n", "\\n",
"\r", "\\r",
"\t", "\\t",
)
underscoreReplacer = strings.NewReplacer(
"_", "",
)
)
// Unmarshal parses the TOML data and stores the result in the value pointed to by v.
//
// Unmarshal will mapped to v that according to following rules:
//
// TOML strings to string
// TOML integers to any int type
// TOML floats to float32 or float64
// TOML booleans to bool
// TOML datetimes to time.Time
// TOML arrays to any type of slice or []interface{}
// TOML tables to struct
// TOML array of tables to slice of struct
func Unmarshal(data []byte, v interface{}) error {
table, err := Parse(data)
if err != nil {
return err
}
if err := UnmarshalTable(table, v); err != nil {
return fmt.Errorf("toml: unmarshal: %v", err)
}
return nil
}
// Unmarshaler is the interface implemented by objects that can unmarshal a
// TOML description of themselves.
// The input can be assumed to be a valid encoding of a TOML value.
// UnmarshalJSON must copy the TOML data if it wishes to retain the data after
// returning.
type Unmarshaler interface {
UnmarshalTOML([]byte) error
}
// UnmarshalTable applies the contents of an ast.Table to the value pointed at by v.
//
// UnmarshalTable will mapped to v that according to following rules:
//
// TOML strings to string
// TOML integers to any int type
// TOML floats to float32 or float64
// TOML booleans to bool
// TOML datetimes to time.Time
// TOML arrays to any type of slice or []interface{}
// TOML tables to struct
// TOML array of tables to slice of struct
func UnmarshalTable(t *ast.Table, v interface{}) (err error) {
if v == nil {
return fmt.Errorf("v must not be nil")
}
rv := reflect.ValueOf(v)
if kind := rv.Kind(); kind != reflect.Ptr && kind != reflect.Map {
return fmt.Errorf("v must be a pointer or map")
}
for rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
for key, val := range t.Fields {
switch av := val.(type) {
case *ast.KeyValue:
fv, fieldName, found := findField(rv, key)
if !found {
return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v)
}
switch fv.Kind() {
case reflect.Map:
mv := reflect.New(fv.Type().Elem()).Elem()
if err := UnmarshalTable(t, mv.Addr().Interface()); err != nil {
return err
}
fv.SetMapIndex(reflect.ValueOf(fieldName), mv)
default:
if err := setValue(fv, av.Value); err != nil {
return fmt.Errorf("line %d: %v.%s: %v", av.Line, rv.Type(), fieldName, err)
}
if rv.Kind() == reflect.Map {
rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
}
}
case *ast.Table:
fv, fieldName, found := findField(rv, key)
if !found {
return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v)
}
if err, ok := setUnmarshaler(fv, string(av.Data)); ok {
if err != nil {
return err
}
continue
}
for fv.Kind() == reflect.Ptr {
fv.Set(reflect.New(fv.Type().Elem()))
fv = fv.Elem()
}
switch fv.Kind() {
case reflect.Struct:
vv := reflect.New(fv.Type()).Elem()
if err := UnmarshalTable(av, vv.Addr().Interface()); err != nil {
return err
}
fv.Set(vv)
if rv.Kind() == reflect.Map {
rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
}
case reflect.Map:
mv := reflect.MakeMap(fv.Type())
if err := UnmarshalTable(av, mv.Interface()); err != nil {
return err
}
fv.Set(mv)
default:
return fmt.Errorf("line %d: `%v.%s' must be struct or map, but %v given", av.Line, rv.Type(), fieldName, fv.Kind())
}
case []*ast.Table:
fv, fieldName, found := findField(rv, key)
if !found {
return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av[0].Line, key, v)
}
data := make([]string, 0, len(av))
for _, tbl := range av {
data = append(data, string(tbl.Data))
}
if err, ok := setUnmarshaler(fv, strings.Join(data, "\n")); ok {
if err != nil {
return err
}
continue
}
t := fv.Type().Elem()
pc := 0
for ; t.Kind() == reflect.Ptr; pc++ {
t = t.Elem()
}
if fv.Kind() != reflect.Slice {
return fmt.Errorf("line %d: `%v.%s' must be slice type, but %v given", av[0].Line, rv.Type(), fieldName, fv.Kind())
}
for _, tbl := range av {
var vv reflect.Value
switch t.Kind() {
case reflect.Map:
vv = reflect.MakeMap(t)
if err := UnmarshalTable(tbl, vv.Interface()); err != nil {
return err
}
default:
vv = reflect.New(t).Elem()
if err := UnmarshalTable(tbl, vv.Addr().Interface()); err != nil {
return err
}
}
for i := 0; i < pc; i++ {
vv = vv.Addr()
pv := reflect.New(vv.Type()).Elem()
pv.Set(vv)
vv = pv
}
fv.Set(reflect.Append(fv, vv))
}
if rv.Kind() == reflect.Map {
rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
}
default:
return fmt.Errorf("BUG: unknown type `%T'", t)
}
}
return nil
}
func setUnmarshaler(lhs reflect.Value, data string) (error, bool) {
for lhs.Kind() == reflect.Ptr {
lhs.Set(reflect.New(lhs.Type().Elem()))
lhs = lhs.Elem()
}
if lhs.CanAddr() {
if u, ok := lhs.Addr().Interface().(Unmarshaler); ok {
return u.UnmarshalTOML([]byte(data)), true
}
}
return nil, false
}
func setValue(lhs reflect.Value, val ast.Value) error {
for lhs.Kind() == reflect.Ptr {
lhs.Set(reflect.New(lhs.Type().Elem()))
lhs = lhs.Elem()
}
if err, ok := setUnmarshaler(lhs, val.Source()); ok {
return err
}
switch v := val.(type) {
case *ast.Integer:
if err := setInt(lhs, v); err != nil {
return err
}
case *ast.Float:
if err := setFloat(lhs, v); err != nil {
return err
}
case *ast.String:
if err := setString(lhs, v); err != nil {
return err
}
case *ast.Boolean:
if err := setBoolean(lhs, v); err != nil {
return err
}
case *ast.Datetime:
if err := setDatetime(lhs, v); err != nil {
return err
}
case *ast.Array:
if err := setArray(lhs, v); err != nil {
return err
}
}
return nil
}
func setInt(fv reflect.Value, v *ast.Integer) error {
i, err := v.Int()
if err != nil {
return err
}
switch fv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if fv.OverflowInt(i) {
return &errorOutOfRange{fv.Kind(), i}
}
fv.SetInt(i)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
fv.SetUint(uint64(i))
case reflect.Interface:
fv.Set(reflect.ValueOf(i))
default:
return fmt.Errorf("`%v' is not any types of int", fv.Type())
}
return nil
}
func setFloat(fv reflect.Value, v *ast.Float) error {
f, err := v.Float()
if err != nil {
return err
}
switch fv.Kind() {
case reflect.Float32, reflect.Float64:
if fv.OverflowFloat(f) {
return &errorOutOfRange{fv.Kind(), f}
}
fv.SetFloat(f)
case reflect.Interface:
fv.Set(reflect.ValueOf(f))
default:
return fmt.Errorf("`%v' is not float32 or float64", fv.Type())
}
return nil
}
func setString(fv reflect.Value, v *ast.String) error {
return set(fv, v.Value)
}
func setBoolean(fv reflect.Value, v *ast.Boolean) error {
b, err := v.Boolean()
if err != nil {
return err
}
return set(fv, b)
}
func setDatetime(fv reflect.Value, v *ast.Datetime) error {
tm, err := v.Time()
if err != nil {
return err
}
return set(fv, tm)
}
func setArray(fv reflect.Value, v *ast.Array) error {
if len(v.Value) == 0 {
return nil
}
typ := reflect.TypeOf(v.Value[0])
for _, vv := range v.Value[1:] {
if typ != reflect.TypeOf(vv) {
return fmt.Errorf("array cannot contain multiple types")
}
}
sliceType := fv.Type()
if fv.Kind() == reflect.Interface {
sliceType = reflect.SliceOf(sliceType)
}
slice := reflect.MakeSlice(sliceType, 0, len(v.Value))
t := sliceType.Elem()
for _, vv := range v.Value {
tmp := reflect.New(t).Elem()
if err := setValue(tmp, vv); err != nil {
return err
}
slice = reflect.Append(slice, tmp)
}
fv.Set(slice)
return nil
}
func set(fv reflect.Value, v interface{}) error {
rhs := reflect.ValueOf(v)
if !rhs.Type().AssignableTo(fv.Type()) {
return fmt.Errorf("`%v' type is not assignable to `%v' type", rhs.Type(), fv.Type())
}
fv.Set(rhs)
return nil
}
type stack struct {
key string
table *ast.Table
}
type toml struct {
table *ast.Table
line int
currentTable *ast.Table
s string
key string
val ast.Value
arr *array
tableMap map[string]*ast.Table
stack []*stack
skip bool
}
func (p *toml) init() {
p.line = 1
p.table = &ast.Table{
Line: p.line,
Type: ast.TableTypeNormal,
}
p.tableMap = map[string]*ast.Table{
"": p.table,
}
p.currentTable = p.table
}
func (p *toml) Error(err error) {
panic(convertError{fmt.Errorf("toml: line %d: %v", p.line, err)})
}
func (p *tomlParser) SetTime(begin, end int) {
p.val = &ast.Datetime{
Position: ast.Position{Begin: begin, End: end},
Data: p.buffer[begin:end],
Value: string(p.buffer[begin:end]),
}
}
func (p *tomlParser) SetFloat64(begin, end int) {
p.val = &ast.Float{
Position: ast.Position{Begin: begin, End: end},
Data: p.buffer[begin:end],
Value: underscoreReplacer.Replace(string(p.buffer[begin:end])),
}
}
func (p *tomlParser) SetInt64(begin, end int) {
p.val = &ast.Integer{
Position: ast.Position{Begin: begin, End: end},
Data: p.buffer[begin:end],
Value: underscoreReplacer.Replace(string(p.buffer[begin:end])),
}
}
func (p *tomlParser) SetString(begin, end int) {
p.val = &ast.String{
Position: ast.Position{Begin: begin, End: end},
Data: p.buffer[begin:end],
Value: p.s,
}
p.s = ""
}
func (p *tomlParser) SetBool(begin, end int) {
p.val = &ast.Boolean{
Position: ast.Position{Begin: begin, End: end},
Data: p.buffer[begin:end],
Value: string(p.buffer[begin:end]),
}
}
func (p *tomlParser) StartArray() {
if p.arr == nil {
p.arr = &array{line: p.line, current: &ast.Array{}}
return
}
p.arr.child = &array{parent: p.arr, line: p.line, current: &ast.Array{}}
p.arr = p.arr.child
}
func (p *tomlParser) AddArrayVal() {
if p.arr.current == nil {
p.arr.current = &ast.Array{}
}
p.arr.current.Value = append(p.arr.current.Value, p.val)
}
func (p *tomlParser) SetArray(begin, end int) {
p.arr.current.Position = ast.Position{Begin: begin, End: end}
p.arr.current.Data = p.buffer[begin:end]
p.val = p.arr.current
p.arr = p.arr.parent
}
func (p *toml) SetTable(buf []rune, begin, end int) {
p.setTable(p.table, buf, begin, end)
}
func (p *toml) setTable(t *ast.Table, buf []rune, begin, end int) {
name := string(buf[begin:end])
names := splitTableKey(name)
if t, exists := p.tableMap[name]; exists {
if lt := p.tableMap[names[len(names)-1]]; t.Type == ast.TableTypeArray || lt != nil && lt.Type == ast.TableTypeNormal {
p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line))
}
}
t, err := p.lookupTable(t, names)
if err != nil {
p.Error(err)
}
p.currentTable = t
p.tableMap[name] = p.currentTable
}
func (p *tomlParser) SetTableString(begin, end int) {
p.currentTable.Data = p.buffer[begin:end]
p.currentTable.Position.Begin = begin
p.currentTable.Position.End = end
}
func (p *toml) SetArrayTable(buf []rune, begin, end int) {
p.setArrayTable(p.table, buf, begin, end)
}
func (p *toml) setArrayTable(t *ast.Table, buf []rune, begin, end int) {
name := string(buf[begin:end])
if t, exists := p.tableMap[name]; exists && t.Type == ast.TableTypeNormal {
p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line))
}
names := splitTableKey(name)
t, err := p.lookupTable(t, names[:len(names)-1])
if err != nil {
p.Error(err)
}
last := names[len(names)-1]
tbl := &ast.Table{
Position: ast.Position{begin, end},
Line: p.line,
Name: last,
Type: ast.TableTypeArray,
}
switch v := t.Fields[last].(type) {
case nil:
if t.Fields == nil {
t.Fields = make(map[string]interface{})
}
t.Fields[last] = []*ast.Table{tbl}
case []*ast.Table:
t.Fields[last] = append(v, tbl)
case *ast.KeyValue:
p.Error(fmt.Errorf("key `%s' is in conflict with line %d", last, v.Line))
default:
p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", last, v))
}
p.currentTable = tbl
p.tableMap[name] = p.currentTable
}
func (p *toml) StartInlineTable() {
p.skip = false
p.stack = append(p.stack, &stack{p.key, p.currentTable})
buf := []rune(p.key)
if p.arr == nil {
p.setTable(p.currentTable, buf, 0, len(buf))
} else {
p.setArrayTable(p.currentTable, buf, 0, len(buf))
}
}
func (p *toml) EndInlineTable() {
st := p.stack[len(p.stack)-1]
p.key, p.currentTable = st.key, st.table
p.stack[len(p.stack)-1] = nil
p.stack = p.stack[:len(p.stack)-1]
p.skip = true
}
func (p *toml) AddLineCount(i int) {
p.line += i
}
func (p *toml) SetKey(buf []rune, begin, end int) {
p.key = string(buf[begin:end])
}
func (p *toml) AddKeyValue() {
if p.skip {
p.skip = false
return
}
if val, exists := p.currentTable.Fields[p.key]; exists {
switch v := val.(type) {
case *ast.Table:
p.Error(fmt.Errorf("key `%s' is in conflict with %v table in line %d", p.key, v.Type, v.Line))
case *ast.KeyValue:
p.Error(fmt.Errorf("key `%s' is in conflict with line %d", p.key, v.Line))
default:
p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", p.key, v))
}
}
if p.currentTable.Fields == nil {
p.currentTable.Fields = make(map[string]interface{})
}
p.currentTable.Fields[p.key] = &ast.KeyValue{
Key: p.key,
Value: p.val,
Line: p.line,
}
}
func (p *toml) SetBasicString(buf []rune, begin, end int) {
p.s = p.unquote(string(buf[begin:end]))
}
func (p *toml) SetMultilineString() {
p.s = p.unquote(`"` + escapeReplacer.Replace(strings.TrimLeft(p.s, "\r\n")) + `"`)
}
func (p *toml) AddMultilineBasicBody(buf []rune, begin, end int) {
p.s += string(buf[begin:end])
}
func (p *toml) SetLiteralString(buf []rune, begin, end int) {
p.s = string(buf[begin:end])
}
func (p *toml) SetMultilineLiteralString(buf []rune, begin, end int) {
p.s = strings.TrimLeft(string(buf[begin:end]), "\r\n")
}
func (p *toml) unquote(s string) string {
s, err := strconv.Unquote(s)
if err != nil {
p.Error(err)
}
return s
}
func (p *toml) lookupTable(t *ast.Table, keys []string) (*ast.Table, error) {
for _, s := range keys {
val, exists := t.Fields[s]
if !exists {
tbl := &ast.Table{
Line: p.line,
Name: s,
Type: ast.TableTypeNormal,
}
if t.Fields == nil {
t.Fields = make(map[string]interface{})
}
t.Fields[s] = tbl
t = tbl
continue
}
switch v := val.(type) {
case *ast.Table:
t = v
case []*ast.Table:
t = v[len(v)-1]
case *ast.KeyValue:
return nil, fmt.Errorf("key `%s' is in conflict with line %d", s, v.Line)
default:
return nil, fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", s, v)
}
}
return t, nil
}
func splitTableKey(tk string) []string {
key := make([]byte, 0, 1)
keys := make([]string, 0, 1)
inQuote := false
for i := 0; i < len(tk); i++ {
k := tk[i]
switch {
case k == tableSeparator && !inQuote:
keys = append(keys, string(key))
key = key[:0] // reuse buffer.
case k == '"':
inQuote = !inQuote
case (k == ' ' || k == '\t') && !inQuote:
// skip.
default:
key = append(key, k)
}
}
keys = append(keys, string(key))
return keys
}
type convertError struct {
err error
}
func (e convertError) Error() string {
return e.err.Error()
}
type array struct {
parent *array
child *array
current *ast.Array
line int
}

+ 0
- 49
Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go View File

@ -1,49 +0,0 @@
package toml_test
import (
"testing"
"time"
"github.com/naoina/toml"
)
func BenchmarkUnmarshal(b *testing.B) {
var v struct {
Title string
Owner struct {
Name string
Organization string
Bio string
Dob time.Time
}
Database struct {
Server string
Ports []int
ConnectionMax int
Enabled bool
}
Servers struct {
Alpha struct {
IP string
DC string
}
Beta struct {
IP string
DC string
}
}
Clients struct {
Data []interface{}
Hosts []string
}
}
data, err := loadTestData()
if err != nil {
b.Fatal(err)
}
for i := 0; i < b.N; i++ {
if err := toml.Unmarshal(data, &v); err != nil {
b.Fatal(err)
}
}
}

+ 0
- 1083
Godeps/_workspace/src/github.com/naoina/toml/decode_test.go
File diff suppressed because it is too large
View File


+ 0
- 211
Godeps/_workspace/src/github.com/naoina/toml/encode.go View File

@ -1,211 +0,0 @@
package toml
import (
"fmt"
"reflect"
"strconv"
"time"
"go/ast"
"github.com/naoina/go-stringutil"
)
const (
tagOmitempty = "omitempty"
tagSkip = "-"
)
// Marshal returns the TOML encoding of v.
//
// Struct values encode as TOML. Each exported struct field becomes a field of
// the TOML structure unless
// - the field's tag is "-", or
// - the field is empty and its tag specifies the "omitempty" option.
// The "toml" key in the struct field's tag value is the key name, followed by
// an optional comma and options. Examples:
//
// // Field is ignored by this package.
// Field int `toml:"-"`
//
// // Field appears in TOML as key "myName".
// Field int `toml:"myName"`
//
// // Field appears in TOML as key "myName" and the field is omitted from the
// // result of encoding if its value is empty.
// Field int `toml:"myName,omitempty"`
//
// // Field appears in TOML as key "field", but the field is skipped if
// // empty.
// // Note the leading comma.
// Field int `toml:",omitempty"`
func Marshal(v interface{}) ([]byte, error) {
return marshal(nil, "", reflect.ValueOf(v), false, false)
}
// Marshaler is the interface implemented by objects that can marshal themshelves into valid TOML.
type Marshaler interface {
MarshalTOML() ([]byte, error)
}
func marshal(buf []byte, prefix string, rv reflect.Value, inArray, arrayTable bool) ([]byte, error) {
rt := rv.Type()
for i := 0; i < rv.NumField(); i++ {
ft := rt.Field(i)
if !ast.IsExported(ft.Name) {
continue
}
colName, rest := extractTag(rt.Field(i).Tag.Get(fieldTagName))
if colName == tagSkip {
continue
}
if colName == "" {
colName = stringutil.ToSnakeCase(ft.Name)
}
fv := rv.Field(i)
switch rest {
case tagOmitempty:
if fv.Interface() == reflect.Zero(ft.Type).Interface() {
continue
}
}
var err error
if buf, err = encodeValue(buf, prefix, colName, fv, inArray, arrayTable); err != nil {
return nil, err
}
}
return buf, nil
}
func encodeValue(buf []byte, prefix, name string, fv reflect.Value, inArray, arrayTable bool) ([]byte, error) {
switch t := fv.Interface().(type) {
case Marshaler:
b, err := t.MarshalTOML()
if err != nil {
return nil, err
}
return appendNewline(append(appendKey(buf, name, inArray, arrayTable), b...), inArray, arrayTable), nil
case time.Time:
return appendNewline(encodeTime(appendKey(buf, name, inArray, arrayTable), t), inArray, arrayTable), nil
}
switch fv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return appendNewline(encodeInt(appendKey(buf, name, inArray, arrayTable), fv.Int()), inArray, arrayTable), nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return appendNewline(encodeUint(appendKey(buf, name, inArray, arrayTable), fv.Uint()), inArray, arrayTable), nil
case reflect.Float32, reflect.Float64:
return appendNewline(encodeFloat(appendKey(buf, name, inArray, arrayTable), fv.Float()), inArray, arrayTable), nil
case reflect.Bool:
return appendNewline(encodeBool(appendKey(buf, name, inArray, arrayTable), fv.Bool()), inArray, arrayTable), nil
case reflect.String:
return appendNewline(encodeString(appendKey(buf, name, inArray, arrayTable), fv.String()), inArray, arrayTable), nil
case reflect.Slice, reflect.Array:
ft := fv.Type().Elem()
for ft.Kind() == reflect.Ptr {
ft = ft.Elem()
}
if ft.Kind() == reflect.Struct {
name := tableName(prefix, name)
var err error
for i := 0; i < fv.Len(); i++ {
if buf, err = marshal(append(append(append(buf, '[', '['), name...), ']', ']', '\n'), name, fv.Index(i), false, true); err != nil {
return nil, err
}
}
return buf, nil
}
buf = append(appendKey(buf, name, inArray, arrayTable), '[')
var err error
for i := 0; i < fv.Len(); i++ {
if i != 0 {
buf = append(buf, ',')
}
if buf, err = encodeValue(buf, prefix, name, fv.Index(i), true, false); err != nil {
return nil, err
}
}
return appendNewline(append(buf, ']'), inArray, arrayTable), nil
case reflect.Struct:
name := tableName(prefix, name)
return marshal(append(append(append(buf, '['), name...), ']', '\n'), name, fv, inArray, arrayTable)
case reflect.Interface:
var err error
if buf, err = encodeInterface(appendKey(buf, name, inArray, arrayTable), fv.Interface()); err != nil {
return nil, err
}
return appendNewline(buf, inArray, arrayTable), nil
}
return nil, fmt.Errorf("toml: marshal: unsupported type %v", fv.Kind())
}
func appendKey(buf []byte, key string, inArray, arrayTable bool) []byte {
if !inArray {
return append(append(buf, key...), '=')
}
return buf
}
func appendNewline(buf []byte, inArray, arrayTable bool) []byte {
if !inArray {
return append(buf, '\n')
}
return buf
}
func encodeInterface(buf []byte, v interface{}) ([]byte, error) {
switch v := v.(type) {
case int:
return encodeInt(buf, int64(v)), nil
case int8:
return encodeInt(buf, int64(v)), nil
case int16:
return encodeInt(buf, int64(v)), nil
case int32:
return encodeInt(buf, int64(v)), nil
case int64:
return encodeInt(buf, v), nil
case uint:
return encodeUint(buf, uint64(v)), nil
case uint8:
return encodeUint(buf, uint64(v)), nil
case uint16:
return encodeUint(buf, uint64(v)), nil
case uint32:
return encodeUint(buf, uint64(v)), nil
case uint64:
return encodeUint(buf, v), nil
case float32:
return encodeFloat(buf, float64(v)), nil
case float64:
return encodeFloat(buf, v), nil
case bool:
return encodeBool(buf, v), nil
case string:
return encodeString(buf, v), nil
}
return nil, fmt.Errorf("toml: marshal: unable to detect a type of value `%v'", v)
}
func encodeInt(buf []byte, i int64) []byte {
return strconv.AppendInt(buf, i, 10)
}
func encodeUint(buf []byte, u uint64) []byte {
return strconv.AppendUint(buf, u, 10)
}
func encodeFloat(buf []byte, f float64) []byte {
return strconv.AppendFloat(buf, f, 'e', -1, 64)
}
func encodeBool(buf []byte, b bool) []byte {
return strconv.AppendBool(buf, b)
}
func encodeString(buf []byte, s string) []byte {
return strconv.AppendQuote(buf, s)
}
func encodeTime(buf []byte, t time.Time) []byte {
return append(buf, t.Format(time.RFC3339Nano)...)
}

+ 0
- 298
Godeps/_workspace/src/github.com/naoina/toml/encode_test.go View File

@ -1,298 +0,0 @@
package toml_test
import (
"reflect"
"testing"
"time"
"github.com/naoina/toml"
)
func TestMarshal(t *testing.T) {
for _, v := range []struct {
v interface{}
expect string
}{
{struct{ Name string }{"alice"}, "name=\"alice\"\n"},
{struct{ Age int }{7}, "age=7\n"},
{struct {
Name string
Age int
}{"alice", 7}, "name=\"alice\"\nage=7\n"},
{struct {
Name string `toml:"-"`
Age int
}{"alice", 7}, "age=7\n"},
{struct {
Name string `toml:"my_name"`
}{"bob"}, "my_name=\"bob\"\n"},
{struct {
Name string `toml:"my_name,omitempty"`
}{"bob"}, "my_name=\"bob\"\n"},
{struct {
Name string `toml:",omitempty"`
}{"bob"}, "name=\"bob\"\n"},
{struct {
Name string `toml:",omitempty"`
}{""}, ""},
} {
b, err := toml.Marshal(v.v)
var actual interface{} = err
var expect interface{} = nil
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`Marshal(%#v) => %#v; want %#v`, v.v, actual, expect)
}
actual = string(b)
expect = v.expect
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`Marshal(%#v); v => %#v; want %#v`, v, actual, expect)
}
}
}
func TestMarshalWhole(t *testing.T) {
for _, v := range []struct {
v interface{}
expect string
}{
{
testStruct{
Table: Table{
Key: "value",
Subtable: Subtable{
Key: "another value",
},
Inline: Inline{
Name: Name{
First: "Tom",
Last: "Preston-Werner",
},
Point: Point{
X: 1,
Y: 2,
},
},
},
X: X{},
String: String{
Basic: Basic{
Basic: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.",
},
Multiline: Multiline{
Key1: "One\nTwo",
Continued: Continued{
Key1: "The quick brown fox jumps over the lazy dog.",
},
},
Literal: Literal{
Winpath: `C:\Users\nodejs\templates`,
Winpath2: `\\ServerX\admin$\system32\`,
Quoted: `Tom "Dubs" Preston-Werner`,
Regex: `<\i\c*\s*>`,
Multiline: LiteralMultiline{
Regex2: `I [dw]on't need \d{2} apples`,
Lines: "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n",
},
},
},
Integer: Integer{
Key1: 99,
Key2: 42,
Key3: 0,
Key4: -17,
Underscores: IntegerUnderscores{
Key1: 1000,
Key2: 5349221,
Key3: 12345,
},
},
Float: Float{
Fractional: Fractional{
Key1: 1.0,
Key2: 3.1415,
Key3: -0.01,
},
Exponent: Exponent{
Key1: 5e22,
Key2: 1e6,
Key3: -2e-2,
},
Both: Both{
Key: 6.626e-34,
},
Underscores: FloatUnderscores{
Key1: 9224617.445991228313,
Key2: 1e100,
},
},
Boolean: Boolean{
True: true,
False: false,
},
Datetime: Datetime{
Key1: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T07:32:00Z")),
Key2: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00-07:00")),
Key3: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00.999999-07:00")),
},
Array: Array{
Key1: []int{1, 2, 3},
Key2: []string{"red", "yellow", "green"},
Key3: [][]int{{1, 2}, {3, 4, 5}},
Key4: [][]interface{}{{int64(1), int64(2)}, {"a", "b", "c"}},
Key5: []int{1, 2, 3},
Key6: []int{1, 2},
},
Products: []Product{
{Name: "Hammer", Sku: 738594937},
{},
{Name: "Nail", Sku: 284758393, Color: "gray"},
},
Fruit: []Fruit{
{
Name: "apple",
Physical: Physical{
Color: "red",
Shape: "round",
},
Variety: []Variety{
{Name: "red delicious"},
{Name: "granny smith"},
},
},
{
Name: "banana",
Variety: []Variety{
{Name: "plantain"},
},
},
},
},
`[table]
key="value"
[table.subtable]
key="another value"
[table.inline]
[table.inline.name]
first="Tom"
last="Preston-Werner"
[table.inline.point]
x=1
y=2
[x]
[x.y]
[x.y.z]
[x.y.z.w]
[string]
[string.basic]
basic="I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."
[string.multiline]
key1="One\nTwo"
key2=""
key3=""
[string.multiline.continued]
key1="The quick brown fox jumps over the lazy dog."
key2=""
key3=""
[string.literal]
winpath="C:\\Users\\nodejs\\templates"
winpath2="\\\\ServerX\\admin$\\system32\\"
quoted="Tom \"Dubs\" Preston-Werner"
regex="<\\i\\c*\\s*>"
[string.literal.multiline]
regex2="I [dw]on't need \\d{2} apples"
lines="The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n"
[integer]
key1=99
key2=42
key3=0
key4=-17
[integer.underscores]
key1=1000
key2=5349221
key3=12345
[float]
[float.fractional]
key1=1e+00
key2=3.1415e+00
key3=-1e-02
[float.exponent]
key1=5e+22
key2=1e+06
key3=-2e-02
[float.both]
key=6.626e-34
[float.underscores]
key1=9.224617445991227e+06
key2=1e+100
[boolean]
true=true
false=false
[datetime]
key1=1979-05-27T07:32:00Z
key2=1979-05-27T00:32:00-07:00
key3=1979-05-27T00:32:00.999999-07:00
[array]
key1=[1,2,3]
key2=["red","yellow","green"]
key3=[[1,2],[3,4,5]]
key4=[[1,2],["a","b","c"]]
key5=[1,2,3]
key6=[1,2]
[[products]]
name="Hammer"
sku=738594937
color=""
[[products]]
name=""
sku=0
color=""
[[products]]
name="Nail"
sku=284758393
color="gray"
[[fruit]]
name="apple"
[fruit.physical]
color="red"
shape="round"
[[fruit.variety]]
name="red delicious"
[[fruit.variety]]
name="granny smith"
[[fruit]]
name="banana"
[fruit.physical]
color=""
shape=""
[[fruit.variety]]
name="plantain"
`,
},
} {
b, err := toml.Marshal(v.v)
var actual interface{} = err
var expect interface{} = nil
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`Marshal(%#v) => %#v; want %#v`, v.v, actual, expect)
}
actual = string(b)
expect = v.expect
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`Marshal(%#v); v => %#v; want %#v`, v.v, actual, expect)
}
// test for reversible.
dest := testStruct{}
actual = toml.Unmarshal(b, &dest)
expect = nil
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`Unmarshal after Marshal => %#v; want %#v`, actual, expect)
}
actual = dest
expect = v.v
if !reflect.DeepEqual(actual, expect) {
t.Errorf(`Unmarshal after Marshal => %#v; want %#v`, v, actual, expect)
}
}
}

+ 0
- 31
Godeps/_workspace/src/github.com/naoina/toml/error.go View File

@ -1,31 +0,0 @@
package toml
import (
"fmt"
"reflect"
)
func (e *parseError) Line() int {
tokens := e.p.tokenTree.Error()
positions := make([]int, len(tokens)*2)
p := 0
for _, token := range tokens {
positions[p], p = int(token.begin), p+1
positions[p], p = int(token.end), p+1
}
for _, t := range translatePositions(e.p.Buffer, positions) {
if e.p.line < t.line {
e.p.line = t.line
}
}
return e.p.line
}
type errorOutOfRange struct {
kind reflect.Kind
v interface{}
}
func (err *errorOutOfRange) Error() string {
return fmt.Sprintf("value %d is out of range for `%v` type", err.v, err.kind)
}

+ 0
- 54
Godeps/_workspace/src/github.com/naoina/toml/parse.go View File

@ -1,54 +0,0 @@
package toml
import (
"fmt"
"github.com/naoina/toml/ast"
)
// Parse returns an AST representation of TOML.
// The toplevel is represented by a table.
func Parse(data []byte) (*ast.Table, error) {
d := &parseState{p: &tomlParser{Buffer: string(data)}}
d.init()
if err := d.parse(); err != nil {
return nil, err
}
return d.p.toml.table, nil
}
type parseState struct {
p *tomlParser
}
func (d *parseState) init() {
d.p.Init()
d.p.toml.init()
}
func (d *parseState) parse() error {
if err := d.p.Parse(); err != nil {
if err, ok := err.(*parseError); ok {
return fmt.Errorf("toml: line %d: parse error", err.Line())
}
return err
}
return d.execute()
}
func (d *parseState) execute() (err error) {
defer func() {
e := recover()
if e != nil {
cerr, ok := e.(convertError)
if !ok {
panic(e)
}
err = cerr.err
}
}()
d.p.Execute()
return nil
}

+ 0
- 138
Godeps/_workspace/src/github.com/naoina/toml/parse.peg View File

@ -1,138 +0,0 @@
package toml
type tomlParser Peg {
toml
}
TOML <- Expression (newline Expression)* newline? !. { _ = buffer }
Expression <- (
<ws table ws comment? (wsnl keyval ws comment?)*> { p.SetTableString(begin, end) }
/ ws keyval ws comment?
/ ws comment?
/ ws
)
newline <- <[\r\n]+> { p.AddLineCount(end - begin) }
ws <- [ \t]*
wsnl <- (
[ \t]
/ <[\r\n]> { p.AddLineCount(end - begin) }
)*
comment <- '#' <[\t -\0x10FFFF]*>
keyval <- key ws '=' ws val { p.AddKeyValue() }
key <- bareKey / quotedKey
bareKey <- <[0-9A-Za-z\-_]+> { p.SetKey(p.buffer, begin, end) }
quotedKey <- '"' <basicChar+> '"' { p.SetKey(p.buffer, begin, end) }
val <- (
<datetime> { p.SetTime(begin, end) }
/ <float> { p.SetFloat64(begin, end) }
/ <integer> { p.SetInt64(begin, end) }
/ <string> { p.SetString(begin, end) }
/ <boolean> { p.SetBool(begin, end) }
/ <array> { p.SetArray(begin, end) }
/ inlineTable
)
table <- stdTable / arrayTable
stdTable <- '[' ws <tableKey> ws ']' { p.SetTable(p.buffer, begin, end) }
arrayTable <- '[[' ws <tableKey> ws ']]' { p.SetArrayTable(p.buffer, begin, end) }
inlineTable <- (
'{' { p.StartInlineTable() }
ws inlineTableKeyValues ws
'}' { p.EndInlineTable() }
)
inlineTableKeyValues <- (keyval inlineTableValSep?)*
tableKey <- key (tableKeySep key)*
tableKeySep <- ws '.' ws
inlineTableValSep <- ws ',' ws
integer <- [\-+]? int
int <- [1-9] (digit / '_' digit)+ / digit
float <- integer (frac exp? / frac? exp)
frac <- '.' digit (digit / '_' digit)*
exp <- [eE] [\-+]? digit (digit / '_' digit)*
string <- (
mlLiteralString
/ literalString
/ mlBasicString
/ basicString
)
basicString <- <'"' basicChar* '"'> { p.SetBasicString(p.buffer, begin, end) }
basicChar <- basicUnescaped / escaped
escaped <- escape ([btnfr"/\\] / 'u' hexQuad / 'U' hexQuad hexQuad)
basicUnescaped <- [ -!#-\[\]-\0x10FFFF]
escape <- '\\'
mlBasicString <- '"""' mlBasicBody '"""' { p.SetMultilineString() }
mlBasicBody <- (
<basicChar / newline> { p.AddMultilineBasicBody(p.buffer, begin, end) }
/ escape newline wsnl
)*
literalString <- "'" <literalChar*> "'" { p.SetLiteralString(p.buffer, begin, end) }
literalChar <- [\t -&(-\0x10FFFF]
mlLiteralString <- "'''" <mlLiteralBody> "'''" { p.SetMultilineLiteralString(p.buffer, begin, end) }
mlLiteralBody <- (!"'''" (mlLiteralChar / newline))*
mlLiteralChar <- [\t -\0x10FFFF]
hexdigit <- [0-9A-Fa-f]
hexQuad <- hexdigit hexdigit hexdigit hexdigit
boolean <- 'true' / 'false'
dateFullYear <- digitQuad
dateMonth <- digitDual
dateMDay <- digitDual
timeHour <- digitDual
timeMinute <- digitDual
timeSecond <- digitDual
timeSecfrac <- '.' digit+
timeNumoffset <- [\-+] timeHour ':' timeMinute
timeOffset <- 'Z' / timeNumoffset
partialTime <- timeHour ':' timeMinute ':' timeSecond timeSecfrac?
fullDate <- dateFullYear '-' dateMonth '-' dateMDay
fullTime <- partialTime timeOffset
datetime <- fullDate 'T' fullTime
digit <- [0-9]
digitDual <- digit digit
digitQuad <- digitDual digitDual
array <- (
'[' { p.StartArray() }
wsnl arrayValues wsnl
']'
)
arrayValues <- (
val { p.AddArrayVal() }
arraySep? (comment? newline)?
)*
arraySep <- ws ',' wsnl

+ 0
- 3065
Godeps/_workspace/src/github.com/naoina/toml/parse.peg.go
File diff suppressed because it is too large
View File


+ 0
- 244
Godeps/_workspace/src/github.com/naoina/toml/testdata/test.toml View File

@ -1,244 +0,0 @@
################################################################################
## Comment
# Speak your mind with the hash symbol. They go from the symbol to the end of
# the line.
################################################################################
## Table
# Tables (also known as hash tables or dictionaries) are collections of
# key/value pairs. They appear in square brackets on a line by themselves.
[table]
key = "value" # Yeah, you can do this.
# Nested tables are denoted by table names with dots in them. Name your tables
# whatever crap you please, just don't use #, ., [ or ].
[table.subtable]
key = "another value"
# You don't need to specify all the super-tables if you don't want to. TOML
# knows how to do it for you.
# [x] you
# [x.y] don't
# [x.y.z] need these
[x.y.z.w] # for this to work
################################################################################
## Inline Table
# Inline tables provide a more compact syntax for expressing tables. They are
# especially useful for grouped data that can otherwise quickly become verbose.
# Inline tables are enclosed in curly braces `{` and `}`. No newlines are
# allowed between the curly braces unless they are valid within a value.
[table.inline]
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
################################################################################
## String
# There are four ways to express strings: basic, multi-line basic, literal, and
# multi-line literal. All strings must contain only valid UTF-8 characters.
[string.basic]
basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
[string.multiline]
# The following strings are byte-for-byte equivalent:
key1 = "One\nTwo"
key2 = """One\nTwo"""
key3 = """
One
Two"""
[string.multiline.continued]
# The following strings are byte-for-byte equivalent:
key1 = "The quick brown fox jumps over the lazy dog."
key2 = """
The quick brown \
fox jumps over \
the lazy dog."""
key3 = """\
The quick brown \
fox jumps over \
the lazy dog.\
"""
[string.literal]
# What you see is what you get.
winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted = 'Tom "Dubs" Preston-Werner'
regex = '<\i\c*\s*>'
[string.literal.multiline]
regex2 = '''I [dw]on't need \d{2} apples'''
lines = '''
The first newline is
trimmed in raw strings.
All other whitespace
is preserved.
'''
################################################################################
## Integer
# Integers are whole numbers. Positive numbers may be prefixed with a plus sign.
# Negative numbers are prefixed with a minus sign.
[integer]
key1 = +99
key2 = 42
key3 = 0
key4 = -17
[integer.underscores]
# For large numbers, you may use underscores to enhance readability. Each
# underscore must be surrounded by at least one digit.
key1 = 1_000
key2 = 5_349_221
key3 = 1_2_3_4_5 # valid but inadvisable
################################################################################
## Float
# A float consists of an integer part (which may be prefixed with a plus or
# minus sign) followed by a fractional part and/or an exponent part.
[float.fractional]
key1 = +1.0
key2 = 3.1415
key3 = -0.01
[float.exponent]
key1 = 5e+22
key2 = 1e6
key3 = -2E-2
[float.both]
key = 6.626e-34
[float.underscores]
key1 = 9_224_617.445_991_228_313
key2 = 1e1_00
################################################################################
## Boolean
# Booleans are just the tokens you're used to. Always lowercase.
[boolean]
True = true
False = false
################################################################################
## Datetime
# Datetimes are RFC 3339 dates.
[datetime]
key1 = 1979-05-27T07:32:00Z
key2 = 1979-05-27T00:32:00-07:00
key3 = 1979-05-27T00:32:00.999999-07:00
################################################################################
## Array
# Arrays are square brackets with other primitives inside. Whitespace is
# ignored. Elements are separated by commas. Data types may not be mixed.
[array]
key1 = [ 1, 2, 3 ]
key2 = [ "red", "yellow", "green" ]
key3 = [ [ 1, 2 ], [3, 4, 5] ]
key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok
# Arrays can also be multiline. So in addition to ignoring whitespace, arrays
# also ignore newlines between the brackets. Terminating commas are ok before
# the closing bracket.
key5 = [
1, 2, 3
]
key6 = [
1,
2, # this is ok
]
################################################################################
## Array of Tables
# These can be expressed by using a table name in double brackets. Each table
# with the same double bracketed name will be an element in the array. The
# tables are inserted in the order encountered.
[[products]]
name = "Hammer"
sku = 738594937
[[products]]
[[products]]
name = "Nail"
sku = 284758393
color = "gray"
# You can create nested arrays of tables as well.
[[fruit]]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"
[[fruit.variety]]
name = "red delicious"
[[fruit.variety]]
name = "granny smith"
[[fruit]]
name = "banana"
[[fruit.variety]]
name = "plantain"

+ 0
- 79
Godeps/_workspace/src/github.com/naoina/toml/util.go View File

@ -1,79 +0,0 @@
package toml
import (
"go/ast"
"reflect"
"strings"
"unicode"
)
// toCamelCase returns a copy of the string s with all Unicode letters mapped to their camel case.
// It will convert to upper case previous letter of '_' and first letter, and remove letter of '_'.
func toCamelCase(s string) string {
if s == "" {
return ""
}
result := make([]rune, 0, len(s))
upper := false
for _, r := range s {
if r == '_' {
upper = true
continue
}
if upper {
result = append(result, unicode.ToUpper(r))
upper = false
continue
}
result = append(result, r)
}
result[0] = unicode.ToUpper(result[0])
return string(result)
}
const (
fieldTagName = "toml"
)
func findField(rv reflect.Value, name string) (field reflect.Value, fieldName string, found bool) {
switch rv.Kind() {
case reflect.Struct:
rt := rv.Type()
for i := 0; i < rt.NumField(); i++ {
ft := rt.Field(i)
if !ast.IsExported(ft.Name) {
continue
}
if col, _ := extractTag(ft.Tag.Get(fieldTagName)); col == name {
return rv.Field(i), ft.Name, true
}
}
for _, name := range []string{
strings.Title(name),
toCamelCase(name),
strings.ToUpper(name),
} {
if field := rv.FieldByName(name); field.IsValid() {
return field, name, true
}
}
case reflect.Map:
return reflect.New(rv.Type().Elem()).Elem(), name, true
}
return field, "", false
}
func extractTag(tag string) (col, rest string) {
tags := strings.SplitN(tag, ",", 2)
if len(tags) == 2 {
return strings.TrimSpace(tags[0]), strings.TrimSpace(tags[1])
}
return strings.TrimSpace(tags[0]), ""
}
func tableName(prefix, name string) string {
if prefix != "" {
return prefix + string(tableSeparator) + name
}
return name
}

+ 0
- 9
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/LICENSE View File

@ -1,9 +0,0 @@
Copyright (c) 2012, Sam Freiberg
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.
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.

+ 0
- 65
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/README.md View File

@ -1,65 +0,0 @@
## Overview
This is the start of a library for [Twilio](http://www.twilio.com/). Gotwilio supports making voice calls and sending text messages.
## License
Gotwilio is licensed under a BSD license.
## Installation
To install gotwilio, simply run `go get github.com/sfreiberg/gotwilio`.
## SMS Example
package main
import (
"github.com/sfreiberg/gotwilio"
)
func main() {
accountSid := "ABC123..........ABC123"
authToken := "ABC123..........ABC123"
twilio := gotwilio.NewTwilioClient(accountSid, authToken)
from := "+15555555555"
to := "+15555555555"
message := "Welcome to gotwilio!"
twilio.SendSMS(from, to, message, "", "")
}
## MMS Example
package main
import (
"github.com/sfreiberg/gotwilio"
)
func main() {
accountSid := "ABC123..........ABC123"
authToken := "ABC123..........ABC123"
twilio := gotwilio.NewTwilioClient(accountSid, authToken)
from := "+15555555555"
to := "+15555555555"
message := "Welcome to gotwilio!"
twilio.SendMMS(from, to, message, "http://host/myimage.gif", "", "")
}
## Voice Example
package main
import (
"github.com/sfreiberg/gotwilio"
)
func main() {
accountSid := "ABC123..........ABC123"
authToken := "ABC123..........ABC123"
twilio := gotwilio.NewTwilioClient(accountSid, authToken)
from := "+15555555555"
to := "+15555555555"
callbackParams := gotwilio.NewCallbackParameters("http://example.com")
twilio.CallWithUrlCallbacks(from, to, callbackParams)
}

+ 0
- 57
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/gotwilio.go View File

@ -1,57 +0,0 @@
// Package gotwilio is a library for interacting with http://www.twilio.com/ API.
package gotwilio
import (
"net/http"
"net/url"
"strings"
)
// Twilio stores basic information important for connecting to the
// twilio.com REST api such as AccountSid and AuthToken.
type Twilio struct {
AccountSid string
AuthToken string
BaseUrl string
HTTPClient *http.Client
}
// Exception is a representation of a twilio exception.
type Exception struct {
Status int `json:"status"` // HTTP specific error code
Message string `json:"message"` // HTTP error message
Code int `json:"code"` // Twilio specific error code
MoreInfo string `json:"more_info"` // Additional info from Twilio
}
// Create a new Twilio struct.
func NewTwilioClient(accountSid, authToken string) *Twilio {
return NewTwilioClientCustomHTTP(accountSid, authToken, nil)
}
// Create a new Twilio client, optionally using a custom http.Client
func NewTwilioClientCustomHTTP(accountSid, authToken string, HTTPClient *http.Client) *Twilio {
twilioUrl := "https://api.twilio.com/2010-04-01" // Should this be moved into a constant?
if HTTPClient == nil {
HTTPClient = http.DefaultClient
}
return &Twilio{accountSid, authToken, twilioUrl, HTTPClient}
}
func (twilio *Twilio) post(formValues url.Values, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequest("POST", twilioUrl, strings.NewReader(formValues.Encode()))
if err != nil {
return nil, err
}
req.SetBasicAuth(twilio.AccountSid, twilio.AuthToken)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := twilio.HTTPClient
if client == nil {
client = http.DefaultClient
}
return client.Do(req)
}

+ 0
- 54
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/gotwilio_test.go View File

@ -1,54 +0,0 @@
package gotwilio
import (
"testing"
)
var params map[string]string
func init() {
params = make(map[string]string)
params["SID"] = "AC0f30491286ab4abb4a108abefbd05d8a"
params["TOKEN"] = "1dcf52d7a1f3853ed78f0ee20d056dd0"
params["FROM"] = "+15005550006"
params["TO"] = "+19135551234"
}
func TestSMS(t *testing.T) {
msg := "Welcome to gotwilio"
twilio := NewTwilioClient(params["SID"], params["TOKEN"])
_, exc, err := twilio.SendSMS(params["FROM"], params["TO"], msg, "", "")
if err != nil {
t.Fatal(err)
}
if exc != nil {
t.Fatal(exc)
}
}
func TestMMS(t *testing.T) {
msg := "Welcome to gotwilio"
twilio := NewTwilioClient(params["SID"], params["TOKEN"])
_, exc, err := twilio.SendMMS(params["FROM"], params["TO"], msg, "http://www.google.com/images/logo.png", "", "")
if err != nil {
t.Fatal(err)
}
if exc != nil {
t.Fatal(exc)
}
}
func TestVoice(t *testing.T) {
callback := NewCallbackParameters("http://example.com")
twilio := NewTwilioClient(params["SID"], params["TOKEN"])
_, exc, err := twilio.CallWithUrlCallbacks(params["FROM"], params["TO"], callback)
if err != nil {
t.Fatal(err)
}
if exc != nil {
t.Fatal(exc)
}
}

+ 0
- 112
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/sms.go View File

@ -1,112 +0,0 @@
package gotwilio
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"time"
)
// SmsResponse is returned after a text/sms message is posted to Twilio
type SmsResponse struct {
Sid string `json:"sid"`
DateCreated string `json:"date_created"`
DateUpdate string `json:"date_updated"`
DateSent string `json:"date_sent"`
AccountSid string `json:"account_sid"`
To string `json:"to"`
From string `json:"from"`
MediaUrl string `json:"media_url"`
Body string `json:"body"`
Status string `json:"status"`
Direction string `json:"direction"`
ApiVersion string `json:"api_version"`
Price *float32 `json:"price,omitempty"`
Url string `json:"uri"`
}
// Returns SmsResponse.DateCreated as a time.Time object
// instead of a string.
func (sms *SmsResponse) DateCreatedAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, sms.DateCreated)
}
// Returns SmsResponse.DateUpdate as a time.Time object
// instead of a string.
func (sms *SmsResponse) DateUpdateAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, sms.DateUpdate)
}
// Returns SmsResponse.DateSent as a time.Time object
// instead of a string.
func (sms *SmsResponse) DateSentAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, sms.DateSent)
}
// SendTextMessage uses Twilio to send a text message.
// See http://www.twilio.com/docs/api/rest/sending-sms for more information.
func (twilio *Twilio) SendSMS(from, to, body, statusCallback, applicationSid string) (smsResponse *SmsResponse, exception *Exception, err error) {
formValues := initFormValues(from, to, body, "", statusCallback, applicationSid)
smsResponse, exception, err = twilio.sendMessage(formValues)
return
}
// SendMultimediaMessage uses Twilio to send a multimedia message.
func (twilio *Twilio) SendMMS(from, to, body, mediaUrl, statusCallback, applicationSid string) (smsResponse *SmsResponse, exception *Exception, err error) {
formValues := initFormValues(from, to, body, mediaUrl, statusCallback, applicationSid)
smsResponse, exception, err = twilio.sendMessage(formValues)
return
}
// Core method to send message
func (twilio *Twilio) sendMessage(formValues url.Values) (smsResponse *SmsResponse, exception *Exception, err error) {
twilioUrl := twilio.BaseUrl + "/Accounts/" + twilio.AccountSid + "/Messages.json"
res, err := twilio.post(formValues, twilioUrl)
if err != nil {
return smsResponse, exception, err
}
defer res.Body.Close()
responseBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return smsResponse, exception, err
}
if res.StatusCode != http.StatusCreated {
exception = new(Exception)
err = json.Unmarshal(responseBody, exception)
// We aren't checking the error because we don't actually care.
// It's going to be passed to the client either way.
return smsResponse, exception, err
}
smsResponse = new(SmsResponse)
err = json.Unmarshal(responseBody, smsResponse)
return smsResponse, exception, err
}
// Form values initialization
func initFormValues(from, to, body, mediaUrl, statusCallback, applicationSid string) url.Values {
formValues := url.Values{}
formValues.Set("From", from)
formValues.Set("To", to)
formValues.Set("Body", body)
if mediaUrl != "" {
formValues.Set("MediaUrl", mediaUrl)
}
if statusCallback != "" {
formValues.Set("StatusCallback", statusCallback)
}
if applicationSid != "" {
formValues.Set("ApplicationSid", applicationSid)
}
return formValues
}

+ 0
- 84
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/util.go View File

@ -1,84 +0,0 @@
package gotwilio
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"errors"
"net/http"
"net/url"
"sort"
)
// GenerateSignature computes the Twilio signature for verifying the
// authenticity of a request. It is based on the specification at:
// https://www.twilio.com/docs/security#validating-requests
func (twilio *Twilio) GenerateSignature(url string, form url.Values) ([]byte, error) {
var buf bytes.Buffer
buf.WriteString(url)
keys := make(sort.StringSlice, 0, len(form))
for k := range form {
keys = append(keys, k)
}
keys.Sort()
for _, k := range keys {
buf.WriteString(k)
for _, v := range form[k] {
buf.WriteString(v)
}
}
mac := hmac.New(sha1.New, []byte(twilio.AuthToken))
mac.Write(buf.Bytes())
var expected bytes.Buffer
coder := base64.NewEncoder(base64.StdEncoding, &expected)
_, err := coder.Write(mac.Sum(nil))
if err != nil {
return nil, err
}
err = coder.Close()
if err != nil {
return nil, err
}
return expected.Bytes(), nil
}
// CheckRequestSignature checks that the X-Twilio-Signature header on a request
// matches the expected signature defined by the GenerateSignature function.
//
// The baseUrl parameter will be prepended to the request URL. It is useful for
// specifying the protocol and host parts of the server URL hosting your endpoint.
//
// Passing a non-POST request or a request without the X-Twilio-Signature
// header is an error.
func (twilio *Twilio) CheckRequestSignature(r *http.Request, baseURL string) (bool, error) {
if r.Method != "POST" {
return false, errors.New("Checking signatures on non-POST requests is not implemented")
}
if err := r.ParseForm(); err != nil {
return false, err
}
url := baseURL + r.URL.String()
expected, err := twilio.GenerateSignature(url, r.PostForm)
if err != nil {
return false, err
}
actual := r.Header.Get("X-Twilio-Signature")
if actual == "" {
return false, errors.New("Request does not have a twilio signature header")
}
return hmac.Equal(expected, []byte(actual)), nil
}

+ 0
- 70
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/util_test.go View File

@ -1,70 +0,0 @@
package gotwilio
import (
"bytes"
"io/ioutil"
"net/http"
"net/url"
"testing"
)
const (
// Magic strings from https://github.com/twilio/twilio-python
testServerURL = "http://www.postbin.org"
testAuthToken = "1c892n40nd03kdnc0112slzkl3091j20"
testValidSignature = "fF+xx6dTinOaCdZ0aIeNkHr/ZAA="
)
func TestCheckSignature(t *testing.T) {
twilio := Twilio{
AuthToken: testAuthToken,
}
// Magic strings from https://github.com/twilio/twilio-python
u, err := url.Parse("/1ed898x")
if err != nil {
t.Fatal(err)
}
h := http.Header{
"Content-Type": []string{"application/x-www-form-urlencoded"},
"X-Twilio-Signature": []string{testValidSignature},
}
b := bytes.NewBufferString(`FromZip=89449&From=%2B15306666666&` +
`FromCity=SOUTH+LAKE+TAHOE&ApiVersion=2010-04-01&To=%2B15306384866&` +
`CallStatus=ringing&CalledState=CA&FromState=CA&Direction=inbound&` +
`ToCity=OAKLAND&ToZip=94612&CallerCity=SOUTH+LAKE+TAHOE&FromCountry=US&` +
`CallerName=CA+Wireless+Call&CalledCity=OAKLAND&CalledCountry=US&` +
`Caller=%2B15306666666&CallerZip=89449&AccountSid=AC9a9f9392lad99kla0sklakjs90j092j3&` +
`Called=%2B15306384866&CallerCountry=US&CalledZip=94612&CallSid=CAd800bb12c0426a7ea4230e492fef2a4f&` +
`CallerState=CA&ToCountry=US&ToState=CA`)
r := http.Request{
Method: "POST",
URL: u,
Header: h,
Body: ioutil.NopCloser(b),
}
valid, err := twilio.CheckRequestSignature(&r, testServerURL)
if err != nil {
t.Fatal(err)
}
if !valid {
t.Fatal("Expected signature to be valid")
}
h["X-Twilio-Signature"] = []string{"foo"}
valid, err = twilio.CheckRequestSignature(&r, testServerURL)
if err != nil {
t.Fatal(err)
}
if valid {
t.Fatal("Expected signature to be invalid")
}
delete(h, "X-Twilio-Signature")
valid, err = twilio.CheckRequestSignature(&r, testServerURL)
if err == nil {
t.Fatal("Expected an error verifying a request without a signature header")
}
}

+ 0
- 161
Godeps/_workspace/src/github.com/sfreiberg/gotwilio/voice.go View File

@ -1,161 +0,0 @@
package gotwilio
import (
"encoding/json"
"net/http"
"net/url"
"strconv"
"time"
)
// These are the paramters to use when you want Twilio to use callback urls.
// See http://www.twilio.com/docs/api/rest/making-calls for more info.
type CallbackParameters struct {
Url string // Required
Method string // Optional
FallbackUrl string // Optional
FallbackMethod string // Optional
StatusCallback string // Optional
StatusCallbackMethod string // Optional
SendDigits string // Optional
IfMachine string // False, Continue or Hangup; http://www.twilio.com/docs/errors/21207
Timeout int // Optional
Record bool // Optional
}
// VoiceResponse contains the details about successful voice calls.
type VoiceResponse struct {
Sid string `json:"sid"`
DateCreated string `json:"date_created"`
DateUpdated string `json:"date_updated"`
ParentCallSid string `json:"parent_call_sid"`
AccountSid string `json:"account_sid"`
To string `json:"to"`
ToFormatted string `json:"to_formatted"`
From string `json:"from"`
FromFormatted string `json:"from_formatted"`
PhoneNumberSid string `json:"phone_number_sid"`
Status string `json:"status"`
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
Duration int `json:"duration"`
Price *float32 `json:"price,omitempty"`
Direction string `json:"direction"`
AnsweredBy string `json:"answered_by"`
ApiVersion string `json:"api_version"`
Annotation string `json:"annotation"`
ForwardedFrom string `json:"forwarded_from"`
GroupSid string `json:"group_sid"`
CallerName string `json:"caller_name"`
Uri string `json:"uri"`
// TODO: handle SubresourceUris
}
// Returns VoiceResponse.DateCreated as a time.Time object
// instead of a string.
func (vr *VoiceResponse) DateCreatedAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, vr.DateCreated)
}
// Returns VoiceResponse.DateUpdated as a time.Time object
// instead of a string.
func (vr *VoiceResponse) DateUpdatedAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, vr.DateUpdated)
}
// Returns VoiceResponse.StartTime as a time.Time object
// instead of a string.
func (vr *VoiceResponse) StartTimeAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, vr.StartTime)
}
// Returns VoiceResponse.EndTime as a time.Time object
// instead of a string.
func (vr *VoiceResponse) EndTimeAsTime() (time.Time, error) {
return time.Parse(time.RFC1123Z, vr.EndTime)
}
// Returns a CallbackParameters type with the specified url and
// CallbackParameters.Timeout set to 60.
func NewCallbackParameters(url string) *CallbackParameters {
return &CallbackParameters{Url: url, Timeout: 60}
}
// Place a voice call with a list of callbacks specified.
func (twilio *Twilio) CallWithUrlCallbacks(from, to string, callbackParameters *CallbackParameters) (*VoiceResponse, *Exception, error) {
formValues := url.Values{}
formValues.Set("From", from)
formValues.Set("To", to)
formValues.Set("Url", callbackParameters.Url)
// Optional values
if callbackParameters.Method != "" {
formValues.Set("Method", callbackParameters.Method)
}
if callbackParameters.FallbackUrl != "" {
formValues.Set("FallbackUrl", callbackParameters.FallbackUrl)
}
if callbackParameters.FallbackMethod != "" {
formValues.Set("FallbackMethod", callbackParameters.FallbackMethod)
}
if callbackParameters.StatusCallback != "" {
formValues.Set("StatusCallback", callbackParameters.StatusCallback)
}
if callbackParameters.StatusCallbackMethod != "" {
formValues.Set("StatusCallbackMethod", callbackParameters.StatusCallbackMethod)
}
if callbackParameters.SendDigits != "" {
formValues.Set("SendDigits", callbackParameters.SendDigits)
}
if callbackParameters.IfMachine != "" {
formValues.Set("IfMachine", callbackParameters.IfMachine)
}
if callbackParameters.Timeout != 0 {
formValues.Set("Timeout", strconv.Itoa(callbackParameters.Timeout))
}
if callbackParameters.Record {
formValues.Set("Record", "true")
} else {
formValues.Set("Record", "false")
}
return twilio.voicePost(formValues)
}
// Place a voice call with an ApplicationSid specified.
func (twilio *Twilio) CallWithApplicationCallbacks(from, to, applicationSid string) (*VoiceResponse, *Exception, error) {
formValues := url.Values{}
formValues.Set("From", from)
formValues.Set("To", to)
formValues.Set("ApplicationSid", applicationSid)
return twilio.voicePost(formValues)
}
// This is a private method that has the common bits for making a voice call.
func (twilio *Twilio) voicePost(formValues url.Values) (*VoiceResponse, *Exception, error) {
var voiceResponse *VoiceResponse
var exception *Exception
twilioUrl := twilio.BaseUrl + "/Accounts/" + twilio.AccountSid + "/Calls.json"
res, err := twilio.post(formValues, twilioUrl)
if err != nil {
return voiceResponse, exception, err
}
defer res.Body.Close()
decoder := json.NewDecoder(res.Body)
if res.StatusCode != http.StatusCreated {
exception = new(Exception)
err = decoder.Decode(exception)
// We aren't checking the error because we don't actually care.
// It's going to be passed to the client either way.
return voiceResponse, exception, err
}
voiceResponse = new(VoiceResponse)
err = decoder.Decode(voiceResponse)
return voiceResponse, exception, err
}

+ 0
- 8
Godeps/_workspace/src/github.com/spf13/pflag/.travis.yml View File

@ -1,8 +0,0 @@
sudo: false
language: go
go:
- 1.3
- 1.4
- tip

+ 0
- 28
Godeps/_workspace/src/github.com/spf13/pflag/LICENSE View File

@ -1,28 +0,0 @@
Copyright (c) 2012 Alex Ogier. All rights reserved.
Copyright (c) 2012 The Go Authors. 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 Google Inc. 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
OWNER 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.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save