Compare commits
358 Commits
release/1.
...
v1.2.3
Author | SHA1 | Date | |
---|---|---|---|
6962eda19d | |||
619b37ca37 | |||
465e810c66 | |||
274f86cd86 | |||
b527c9c718 | |||
9666db2a44 | |||
e3ac56d502 | |||
32dda97602 | |||
631bf36102 | |||
b4374436f3 | |||
46ad5a5f5b | |||
9b94076717 | |||
b8b996be74 | |||
b9359981f4 | |||
7977e87ce1 | |||
69d86442a5 | |||
36f46a61a7 | |||
6e1dc321f4 | |||
7a2a918067 | |||
f459a3f0ae | |||
e456f27795 | |||
90cd8ae9f2 | |||
70b6174748 | |||
bfde1a4305 | |||
e56cbc225e | |||
7bf8e949e7 | |||
6a05c569f2 | |||
eaa4473dbd | |||
be76a68aea | |||
12c0afe4fe | |||
5621308949 | |||
399c920380 | |||
e40b447fea | |||
b94b9b0158 | |||
47ca6904b3 | |||
075815e5ff | |||
b60a27627b | |||
216c486a3a | |||
ac6248ed7a | |||
bdf4fd6091 | |||
69f48e4689 | |||
6f3cb12924 | |||
58fbcaa750 | |||
1a1a1ee4ff | |||
985b5f29ed | |||
2f65ddc501 | |||
1cc2f08041 | |||
821619e1c3 | |||
e9a80518c7 | |||
321733ab23 | |||
d4d3fc6a70 | |||
99b62f36b6 | |||
0a7d059b6a | |||
55bdcfaeac | |||
3a5e7ed9a6 | |||
b252589960 | |||
d581dfee5f | |||
8b32f10f16 | |||
8c4dab77ba | |||
071e2cd08e | |||
47b9c640f5 | |||
a9c809b441 | |||
0d40727775 | |||
17b729759b | |||
55ed8d108d | |||
f1a4b330dd | |||
0eac601b5b | |||
cdc2662c40 | |||
2b339cbbd8 | |||
3e6964b841 | |||
c6013725a8 | |||
4e075e4013 | |||
b81a6e6ab8 | |||
62bbf8a09e | |||
4ce3dfe9c8 | |||
fc8b246109 | |||
24bb68e7cf | |||
bc17dba8fb | |||
ac32f52ca6 | |||
90f1fe0ed2 | |||
28b13a4d1e | |||
f04b3a6f29 | |||
bf879ef230 | |||
004ed786b4 | |||
652eea71fe | |||
618065895b | |||
edaea69817 | |||
6fe46cc743 | |||
4ea81f170a | |||
f69121357d | |||
e2d7c1a523 | |||
ebbe25ee71 | |||
1a86adc5a2 | |||
e98854588b | |||
0fda4c4e15 | |||
b2c17a5a63 | |||
e9b031b88b | |||
00b45acb9e | |||
1ffc5b0cfd | |||
5e4cd599eb | |||
1f1d73ab74 | |||
67225de255 | |||
540eb3d02d | |||
fe8093b71f | |||
9dc23ce284 | |||
1801748ccd | |||
8b12bcc0ac | |||
e1037bd0cf | |||
2d1ced8759 | |||
39e9560600 | |||
d9addf79fa | |||
cfd84a6ad9 | |||
6ec13e7e2b | |||
79b644c7a3 | |||
14370a2260 | |||
3df6f3fc14 | |||
847794a321 | |||
829201382b | |||
5dd2462816 | |||
f448310eef | |||
101418b275 | |||
a1d8015817 | |||
17f65cd1e5 | |||
47a7fe5d22 | |||
abce09954b | |||
a219159e7e | |||
7324176f70 | |||
ca88e18f59 | |||
42f44dda54 | |||
d910148a96 | |||
c51e153b5c | |||
d51d0022ce | |||
3793991c0e | |||
b884d6ebaa | |||
36f7fe61c3 | |||
54088b0b8b | |||
9fb7bc7443 | |||
e2d44814a5 | |||
bd3a44cac9 | |||
61a6911eeb | |||
9bf17eb05a | |||
269c5c7107 | |||
382d35bf40 | |||
dd54fef898 | |||
edccc7ae34 | |||
7d5ff770e2 | |||
c6a11fe372 | |||
941920f2aa | |||
3b997c3e16 | |||
0737cbc5c1 | |||
227ff4d2d6 | |||
18d450b2d0 | |||
cc87551edc | |||
d0dc1b4a60 | |||
b4369e1015 | |||
4d5501c46a | |||
d4da2f630e | |||
e1da124415 | |||
36081505c4 | |||
2497f28aa9 | |||
49ece3155c | |||
8839fee415 | |||
ff1f6fa09d | |||
7ea30f18f9 | |||
12805c738c | |||
80b294c3c7 | |||
8884f856ef | |||
309788de37 | |||
f6367548e4 | |||
1c3ca3ce6a | |||
8603ec7055 | |||
1086e2f298 | |||
49703bea0a | |||
59b28cfa31 | |||
5c5c3930b7 | |||
7bb5ac045e | |||
cd81356ace | |||
c472b8f725 | |||
3a66c4ed47 | |||
29181003d4 | |||
87d1cde7e4 | |||
28b14d3e6d | |||
73c4e6005c | |||
b8ca0a830e | |||
a89cfe92cc | |||
0b0b31c7d2 | |||
1d2420323c | |||
0dd6911c62 | |||
28feafe7af | |||
0d10d5a0a5 | |||
31a2793662 | |||
f9cbd16f27 | |||
0ef80bb3d0 | |||
05c66529b2 | |||
9cacec70f9 | |||
94b6f38869 | |||
bf6ea2919d | |||
c32d6fdf74 | |||
67c8ccc309 | |||
590c99a98f | |||
01ed3fa1a9 | |||
32395ddb89 | |||
2fcf7f1241 | |||
07cb8092e7 | |||
1cbd53add8 | |||
eec38c5853 | |||
c93f0b9f4b | |||
a23478c0be | |||
312128384b | |||
3ccab5a1e8 | |||
dcb23bc3ab | |||
b6c5b3b4a7 | |||
d7580f21f6 | |||
b1fac4270d | |||
ac697326a6 | |||
184e9ae9a8 | |||
846f34f78b | |||
a33726b7db | |||
132df860d9 | |||
785b3e7a57 | |||
e89536ca0b | |||
ac10c9352e | |||
cf7cef4293 | |||
698e98d981 | |||
a3b8169938 | |||
46c9594081 | |||
7baa5977c8 | |||
803096ca0f | |||
6ee908848c | |||
3832019964 | |||
eae1191904 | |||
78b101e15d | |||
74f6d90153 | |||
c32073b11f | |||
b23b4dbd79 | |||
c1d516546d | |||
82ef26f600 | |||
ee5728ec03 | |||
9a02f53726 | |||
98100f472c | |||
80e5f50713 | |||
26f838796b | |||
35f271b264 | |||
f12e0161ca | |||
71d32f54f7 | |||
1f4ac6b05a | |||
d8590d9790 | |||
56219a5e7a | |||
26c6e3b206 | |||
b01f2c29ae | |||
ff66e8fa29 | |||
17b481e3c3 | |||
5c949d3b3b | |||
dcdb7059cc | |||
bf48ed32dd | |||
ba14957cf3 | |||
97cdf84899 | |||
98db08c42f | |||
cc6c5846e5 | |||
db988a46dd | |||
7a75da63c6 | |||
33efb3381c | |||
5aec1d94ad | |||
a8b39b5cc0 | |||
acd2c4e520 | |||
ab85a3593a | |||
c1c06fffcb | |||
6628eeb6ca | |||
0d3a8ad6dd | |||
4231de3914 | |||
3f07afbbd2 | |||
64e2f52c2e | |||
d261c3f455 | |||
e7f4232b10 | |||
f715547fc7 | |||
fa286688ab | |||
03c39d4fc0 | |||
6adbaabc65 | |||
81e2124ea2 | |||
cc27be9d44 | |||
7065ebd2ed | |||
a281df783d | |||
1fad8798ec | |||
7e31df3987 | |||
572e78cee0 | |||
453d2c9ce1 | |||
1356daad27 | |||
d18d256442 | |||
3530acb9e2 | |||
8a5ea466e4 | |||
1e241e84f7 | |||
e86233abc9 | |||
c1c895a36b | |||
73a576c9af | |||
665eaff9b9 | |||
9afda6ab8c | |||
3adaeb1dbc | |||
0efcd7ed05 | |||
4019e2a6f2 | |||
f6097f4a0a | |||
d4428cc77f | |||
ba15f9d282 | |||
0c718afe90 | |||
036e6301af | |||
6cffa743ee | |||
5001f778aa | |||
cd657b9878 | |||
67598d9d08 | |||
fd2356c620 | |||
bfbcfbe4a9 | |||
adc7ab0dd6 | |||
8f56eea77d | |||
8fc9830971 | |||
0cff61beda | |||
b403b9e4c3 | |||
26a269ea09 | |||
04bb89604e | |||
0428cae226 | |||
3f047be5aa | |||
f4acdea402 | |||
c7e7778f2a | |||
d1d45aa839 | |||
d103af5dd4 | |||
ed1d2f858e | |||
482cc4957d | |||
f1daed65b1 | |||
cf5313f13e | |||
06d5898d6a | |||
7662dd9bbb | |||
8160b8618d | |||
3029349761 | |||
02c5022742 | |||
3642441ca3 | |||
12bb743b35 | |||
26c0fa1cb0 | |||
a38f3740d6 | |||
345590f27f | |||
5a41326521 | |||
cefd948267 | |||
593b1b65e7 | |||
5da82077d1 | |||
1b9ef0e52d | |||
a75b95b876 | |||
e954375109 | |||
618991f136 | |||
bc6b6932d0 | |||
1909d26fe2 | |||
b1d0d3c0ed | |||
9addb3df3a | |||
e870e61bc9 | |||
cecc9cdd2f | |||
e17d8ddbeb | |||
37efd08b42 | |||
afba798357 | |||
796c18db93 | |||
a32c51effd | |||
5a810758db | |||
6f9377475c |
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
13
.travis.yml
13
.travis.yml
@ -1,14 +1,11 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.4.2
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -yqq libgmp3-dev
|
||||
install:
|
||||
# - go get code.google.com/p/go.tools/cmd/goimports
|
||||
# - go get github.com/golang/lint/golint
|
||||
# - go get golang.org/x/tools/cmd/vet
|
||||
- go get golang.org/x/tools/cmd/cover github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
before_script:
|
||||
# - gofmt -l -w .
|
||||
# - goimports -l -w .
|
||||
@ -18,11 +15,15 @@ before_script:
|
||||
script:
|
||||
- make travis-test-with-coverage
|
||||
after_success:
|
||||
- if [ "$COVERALLS_TOKEN" ]; then goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
env:
|
||||
global:
|
||||
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
|
||||
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libgmp3-dev
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
|
9
CONTRIBUTING.md
Normal file
9
CONTRIBUTING.md
Normal file
@ -0,0 +1,9 @@
|
||||
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
||||
send a pull request. Commits who do not comply with the coding standards
|
||||
are ignored (use gofmt!). If you send pull requests make absolute sure that you
|
||||
commit on the `develop` branch and that you do not merge to master.
|
||||
Commits that are directly based on master are simply ignored.
|
||||
|
||||
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
|
||||
for more details on configuring your environment, testing, and
|
||||
dependency management.
|
43
Godeps/Godeps.json
generated
43
Godeps/Godeps.json
generated
@ -5,11 +5,6 @@
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go-uuid/uuid",
|
||||
"Comment": "null-12",
|
||||
"Rev": "7dda39b2e7d5e265014674c5af696ba4186679e9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/codegangsta/cli",
|
||||
"Comment": "1.2.0-95-g9b2bd2b",
|
||||
@ -21,17 +16,21 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ethereum/ethash",
|
||||
"Comment": "v23.1-227-g8f6ccaa",
|
||||
"Rev": "8f6ccaaef9b418553807a73a95cb5f49cd3ea39f"
|
||||
"Comment": "v23.1-234-g062e40a",
|
||||
"Rev": "062e40a1a1671f5a5102862b56e4c56f68a732f5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fatih/color",
|
||||
"Comment": "v0.1-5-gf773d4c",
|
||||
"Rev": "f773d4c806cc8e4a5749d6a35e2a4bbcd71443d6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gizak/termui",
|
||||
"Rev": "bab8dce01c193d82bc04888a0a9a7814d505f532"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/howeyc/fsnotify",
|
||||
"Comment": "v0.9.0-11-g6b1ef89",
|
||||
"Rev": "6b1ef893dc11e0447abda6da20a5203481878dda"
|
||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||
"Rev": "7f9ef20a0256f494e24126014135cf893ab71e9e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/huin/goupnp",
|
||||
@ -45,13 +44,9 @@
|
||||
"ImportPath": "github.com/kardianos/osext",
|
||||
"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-colorable",
|
||||
"Rev": "043ae16291351db8465272edf465c9f388161627"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-isatty",
|
||||
"Rev": "fdbe02a1b44e75977b2690062b83cf507d70c013"
|
||||
"Rev": "7fcbc72f853b92b5720db4a6b8482be612daef24"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-runewidth",
|
||||
@ -62,18 +57,14 @@
|
||||
"ImportPath": "github.com/nsf/termbox-go",
|
||||
"Rev": "675ffd907b7401b8a709a5ef2249978af5616bb2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pborman/uuid",
|
||||
"Rev": "cccd189d45f7ac3368a0d127efb7f4d08ae0b655"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/peterh/liner",
|
||||
"Rev": "29f6a646557d83e2b6e9ba05c45fbea9c006dbe8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rakyll/globalconf",
|
||||
"Rev": "415abc325023f1a00cd2d9fa512e0e71745791a2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rakyll/goini",
|
||||
"Rev": "907cca0f578a5316fb864ec6992dc3d9730ec58c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rcrowley/go-metrics",
|
||||
"Rev": "a5cfc242a56ba7fa70b785f678d6214837bf93b9"
|
||||
@ -86,6 +77,10 @@
|
||||
"ImportPath": "github.com/rs/cors",
|
||||
"Rev": "6e0c3cb65fc0fdb064c743d176a620e3ca446dfb"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shiena/ansicolor",
|
||||
"Rev": "a5e2b567a4dd6cc74545b8a4f27c9d63b9e7735b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
||||
"Rev": "4875955338b0a434238a31165cb87255ab6e9e4a"
|
||||
@ -129,7 +124,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/karalabe/cookiejar.v2/collections/prque",
|
||||
"Rev": "0b2e270613f5d7ba262a5749b9e32270131497a2"
|
||||
"Rev": "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h
generated
vendored
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h
generated
vendored
@ -35,10 +35,14 @@
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
|
||||
#define ethash_swap_u32(input_) bswap32(input_)
|
||||
#define ethash_swap_u64(input_) bswap64(input_)
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <endian.h>
|
||||
#define ethash_swap_u32(input_) swap32(input_)
|
||||
#define ethash_swap_u64(input_) swap64(input_)
|
||||
#else // posix
|
||||
#include <byteswap.h>
|
||||
#define ethash_swap_u32(input_) __bswap_32(input_)
|
||||
#define ethash_swap_u64(input_) __bswap_64(input_)
|
||||
#define ethash_swap_u32(input_) bswap_32(input_)
|
||||
#define ethash_swap_u64(input_) bswap_64(input_)
|
||||
#endif
|
||||
|
||||
|
||||
|
4
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/fnv.h
generated
vendored
4
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/fnv.h
generated
vendored
@ -29,6 +29,10 @@ extern "C" {
|
||||
|
||||
#define FNV_PRIME 0x01000193
|
||||
|
||||
/* The FNV-1 spec multiplies the prime with the input one byte (octet) in turn.
|
||||
We instead multiply it with the full 32-bit input.
|
||||
This gives a different result compared to a canonical FNV-1 implementation.
|
||||
*/
|
||||
static inline uint32_t fnv_hash(uint32_t const x, uint32_t const y)
|
||||
{
|
||||
return x * FNV_PRIME ^ y;
|
||||
|
@ -1,2 +1,3 @@
|
||||
language: go
|
||||
go: 1.2
|
||||
go: 1.3
|
||||
|
20
Godeps/_workspace/src/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Fatih Arslan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
151
Godeps/_workspace/src/github.com/fatih/color/README.md
generated
vendored
Normal file
151
Godeps/_workspace/src/github.com/fatih/color/README.md
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
# Color [](http://godoc.org/github.com/fatih/color) [](https://travis-ci.org/fatih/color)
|
||||
|
||||
|
||||
|
||||
Color lets you use colorized outputs in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It has support for Windows too! The API can be used in several ways, pick one that suits you.
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get github.com/fatih/color
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Standard colors
|
||||
|
||||
```go
|
||||
// Print with default helper functions
|
||||
color.Cyan("Prints text in cyan.")
|
||||
|
||||
// A newline will be appended automatically
|
||||
color.Blue("Prints %s in blue.", "text")
|
||||
|
||||
// These are using the default foreground colors
|
||||
color.Red("We have red")
|
||||
color.Magenta("And many others ..")
|
||||
|
||||
```
|
||||
|
||||
### Mix and reuse colors
|
||||
|
||||
```go
|
||||
// Create a new color object
|
||||
c := color.New(color.FgCyan).Add(color.Underline)
|
||||
c.Println("Prints cyan text with an underline.")
|
||||
|
||||
// Or just add them to New()
|
||||
d := color.New(color.FgCyan, color.Bold)
|
||||
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||
|
||||
// Mix up foreground and background colors, create new mixes!
|
||||
red := color.New(color.FgRed)
|
||||
|
||||
boldRed := red.Add(color.Bold)
|
||||
boldRed.Println("This will print text in bold red.")
|
||||
|
||||
whiteBackground := red.Add(color.BgWhite)
|
||||
whiteBackground.Println("Red text with white background.")
|
||||
```
|
||||
|
||||
### Custom print functions (PrintFunc)
|
||||
|
||||
```go
|
||||
// Create a custom print function for convenience
|
||||
red := color.New(color.FgRed).PrintfFunc()
|
||||
red("Warning")
|
||||
red("Error: %s", err)
|
||||
|
||||
// Mix up multiple attributes
|
||||
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||
notice("Don't forget this...")
|
||||
```
|
||||
|
||||
### Insert into noncolor strings (SprintFunc)
|
||||
|
||||
```go
|
||||
// Create SprintXxx functions to mix strings with other non-colorized strings:
|
||||
yellow := color.New(color.FgYellow).SprintFunc()
|
||||
red := color.New(color.FgRed).SprintFunc()
|
||||
fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||
|
||||
info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
|
||||
fmt.Printf("This %s rocks!\n", info("package"))
|
||||
|
||||
// Use helper functions
|
||||
fmt.Printf("This", color.RedString("warning"), "should be not neglected.")
|
||||
fmt.Printf(color.GreenString("Info:"), "an important message." )
|
||||
|
||||
// Windows supported too! Just don't forget to change the output to color.Output
|
||||
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||
```
|
||||
|
||||
### Plug into existing code
|
||||
|
||||
```go
|
||||
// Use handy standard colors
|
||||
color.Set(color.FgYellow)
|
||||
|
||||
fmt.Println("Existing text will now be in yellow")
|
||||
fmt.Printf("This one %s\n", "too")
|
||||
|
||||
color.Unset() // Don't forget to unset
|
||||
|
||||
// You can mix up parameters
|
||||
color.Set(color.FgMagenta, color.Bold)
|
||||
defer color.Unset() // Use it in your function
|
||||
|
||||
fmt.Println("All text will now be bold magenta.")
|
||||
```
|
||||
|
||||
### Disable color
|
||||
|
||||
There might be a case where you want to disable color output (for example to
|
||||
pipe the standard output of your app to somewhere else). `Color` has support to
|
||||
disable colors both globally and for single color definition. For example
|
||||
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
|
||||
the color output with:
|
||||
|
||||
```go
|
||||
|
||||
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||
|
||||
if *flagNoColor {
|
||||
color.NoColor = true // disables colorized output
|
||||
}
|
||||
```
|
||||
|
||||
It also has support for single color definitions (local). You can
|
||||
disable/enable color output on the fly:
|
||||
|
||||
```go
|
||||
c := color.New(color.FgCyan)
|
||||
c.Println("Prints cyan text")
|
||||
|
||||
c.DisableColor()
|
||||
c.Println("This is printed without any color")
|
||||
|
||||
c.EnableColor()
|
||||
c.Println("This prints again cyan...")
|
||||
```
|
||||
|
||||
## Todo
|
||||
|
||||
* Save/Return previous values
|
||||
* Evaluate fmt.Formatter interface
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
* [Fatih Arslan](https://github.com/fatih)
|
||||
* Windows support via @shiena: [ansicolor](https://github.com/shiena/ansicolor)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details
|
||||
|
353
Godeps/_workspace/src/github.com/fatih/color/color.go
generated
vendored
Normal file
353
Godeps/_workspace/src/github.com/fatih/color/color.go
generated
vendored
Normal file
@ -0,0 +1,353 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||
// false or true based on the stdout's file descriptor referring to a terminal
|
||||
// or not. This is a global option and affects all colors. For more control
|
||||
// over each color block use the methods DisableColor() individually.
|
||||
var NoColor = !isatty.IsTerminal(os.Stdout.Fd())
|
||||
|
||||
// Color defines a custom color object which is defined by SGR parameters.
|
||||
type Color struct {
|
||||
params []Attribute
|
||||
noColor *bool
|
||||
}
|
||||
|
||||
// Attribute defines a single SGR Code
|
||||
type Attribute int
|
||||
|
||||
const escape = "\x1b"
|
||||
|
||||
// Base attributes
|
||||
const (
|
||||
Reset Attribute = iota
|
||||
Bold
|
||||
Faint
|
||||
Italic
|
||||
Underline
|
||||
BlinkSlow
|
||||
BlinkRapid
|
||||
ReverseVideo
|
||||
Concealed
|
||||
CrossedOut
|
||||
)
|
||||
|
||||
// Foreground text colors
|
||||
const (
|
||||
FgBlack Attribute = iota + 30
|
||||
FgRed
|
||||
FgGreen
|
||||
FgYellow
|
||||
FgBlue
|
||||
FgMagenta
|
||||
FgCyan
|
||||
FgWhite
|
||||
)
|
||||
|
||||
// Background text colors
|
||||
const (
|
||||
BgBlack Attribute = iota + 40
|
||||
BgRed
|
||||
BgGreen
|
||||
BgYellow
|
||||
BgBlue
|
||||
BgMagenta
|
||||
BgCyan
|
||||
BgWhite
|
||||
)
|
||||
|
||||
// New returns a newly created color object.
|
||||
func New(value ...Attribute) *Color {
|
||||
c := &Color{params: make([]Attribute, 0)}
|
||||
c.Add(value...)
|
||||
return c
|
||||
}
|
||||
|
||||
// Set sets the given parameters immediately. It will change the color of
|
||||
// output with the given SGR parameters until color.Unset() is called.
|
||||
func Set(p ...Attribute) *Color {
|
||||
c := New(p...)
|
||||
c.Set()
|
||||
return c
|
||||
}
|
||||
|
||||
// Unset resets all escape attributes and clears the output. Usually should
|
||||
// be called after Set().
|
||||
func Unset() {
|
||||
if NoColor {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(Output, "%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// Set sets the SGR sequence.
|
||||
func (c *Color) Set() *Color {
|
||||
if c.isNoColorSet() {
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Fprintf(Output, c.format())
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) unset() {
|
||||
if c.isNoColorSet() {
|
||||
return
|
||||
}
|
||||
|
||||
Unset()
|
||||
}
|
||||
|
||||
// Add is used to chain SGR parameters. Use as many as parameters to combine
|
||||
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
|
||||
func (c *Color) Add(value ...Attribute) *Color {
|
||||
c.params = append(c.params, value...)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) prepend(value Attribute) {
|
||||
c.params = append(c.params, 0)
|
||||
copy(c.params[1:], c.params[0:])
|
||||
c.params[0] = value
|
||||
}
|
||||
|
||||
// Output defines the standard output of the print functions. By default
|
||||
// os.Stdout is used.
|
||||
var Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
|
||||
// Print formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are added between operands when neither is a
|
||||
// string. It returns the number of bytes written and any write error
|
||||
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||
// color.
|
||||
func (c *Color) Print(a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprint(Output, a...)
|
||||
}
|
||||
|
||||
// Printf formats according to a format specifier and writes to standard output.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// This is the standard fmt.Printf() method wrapped with the given color.
|
||||
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprintf(Output, format, a...)
|
||||
}
|
||||
|
||||
// Println formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are always added between operands and a newline is
|
||||
// appended. It returns the number of bytes written and any write error
|
||||
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||
// color.
|
||||
func (c *Color) Println(a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprintln(Output, a...)
|
||||
}
|
||||
|
||||
// PrintFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Print().
|
||||
func (c *Color) PrintFunc() func(a ...interface{}) {
|
||||
return func(a ...interface{}) { c.Print(a...) }
|
||||
}
|
||||
|
||||
// PrintfFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Printf().
|
||||
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
|
||||
return func(format string, a ...interface{}) { c.Printf(format, a...) }
|
||||
}
|
||||
|
||||
// PrintlnFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Println().
|
||||
func (c *Color) PrintlnFunc() func(a ...interface{}) {
|
||||
return func(a ...interface{}) { c.Println(a...) }
|
||||
}
|
||||
|
||||
// SprintFunc returns a new function that returns colorized strings for the
|
||||
// given arguments with fmt.Sprint(). Useful to put into or mix into other
|
||||
// string. Windows users should use this in conjuction with color.Output, example:
|
||||
//
|
||||
// put := New(FgYellow).SprintFunc()
|
||||
// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
|
||||
func (c *Color) SprintFunc() func(a ...interface{}) string {
|
||||
return func(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprint(a...))
|
||||
}
|
||||
}
|
||||
|
||||
// SprintfFunc returns a new function that returns colorized strings for the
|
||||
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
|
||||
// string. Windows users should use this in conjuction with color.Output.
|
||||
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
|
||||
return func(format string, a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintf(format, a...))
|
||||
}
|
||||
}
|
||||
|
||||
// SprintlnFunc returns a new function that returns colorized strings for the
|
||||
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
|
||||
// string. Windows users should use this in conjuction with color.Output.
|
||||
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
|
||||
return func(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintln(a...))
|
||||
}
|
||||
}
|
||||
|
||||
// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
|
||||
// an example output might be: "1;36" -> bold cyan
|
||||
func (c *Color) sequence() string {
|
||||
format := make([]string, len(c.params))
|
||||
for i, v := range c.params {
|
||||
format[i] = strconv.Itoa(int(v))
|
||||
}
|
||||
|
||||
return strings.Join(format, ";")
|
||||
}
|
||||
|
||||
// wrap wraps the s string with the colors attributes. The string is ready to
|
||||
// be printed.
|
||||
func (c *Color) wrap(s string) string {
|
||||
if c.isNoColorSet() {
|
||||
return s
|
||||
}
|
||||
|
||||
return c.format() + s + c.unformat()
|
||||
}
|
||||
|
||||
func (c *Color) format() string {
|
||||
return fmt.Sprintf("%s[%sm", escape, c.sequence())
|
||||
}
|
||||
|
||||
func (c *Color) unformat() string {
|
||||
return fmt.Sprintf("%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// DisableColor disables the color output. Useful to not change any existing
|
||||
// code and still being able to output. Can be used for flags like
|
||||
// "--no-color". To enable back use EnableColor() method.
|
||||
func (c *Color) DisableColor() {
|
||||
c.noColor = boolPtr(true)
|
||||
}
|
||||
|
||||
// EnableColor enables the color output. Use it in conjuction with
|
||||
// DisableColor(). Otherwise this method has no side effects.
|
||||
func (c *Color) EnableColor() {
|
||||
c.noColor = boolPtr(false)
|
||||
}
|
||||
|
||||
func (c *Color) isNoColorSet() bool {
|
||||
// check first if we have user setted action
|
||||
if c.noColor != nil {
|
||||
return *c.noColor
|
||||
}
|
||||
|
||||
// if not return the global option, which is disabled by default
|
||||
return NoColor
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Black is an convenient helper function to print with black foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) }
|
||||
|
||||
// Red is an convenient helper function to print with red foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) }
|
||||
|
||||
// Green is an convenient helper function to print with green foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) }
|
||||
|
||||
// Yellow is an convenient helper function to print with yellow foreground.
|
||||
// A newline is appended to format by default.
|
||||
func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) }
|
||||
|
||||
// Blue is an convenient helper function to print with blue foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) }
|
||||
|
||||
// Magenta is an convenient helper function to print with magenta foreground.
|
||||
// A newline is appended to format by default.
|
||||
func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) }
|
||||
|
||||
// Cyan is an convenient helper function to print with cyan foreground. A
|
||||
// newline is appended to format by default.
|
||||
func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) }
|
||||
|
||||
// White is an convenient helper function to print with white foreground. A
|
||||
// newline is appended to format by default.
|
||||
func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) }
|
||||
|
||||
func printColor(format string, p Attribute, a ...interface{}) {
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format += "\n"
|
||||
}
|
||||
|
||||
c := &Color{params: []Attribute{p}}
|
||||
c.Printf(format, a...)
|
||||
}
|
||||
|
||||
// BlackString is an convenient helper function to return a string with black
|
||||
// foreground.
|
||||
func BlackString(format string, a ...interface{}) string {
|
||||
return New(FgBlack).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// RedString is an convenient helper function to return a string with red
|
||||
// foreground.
|
||||
func RedString(format string, a ...interface{}) string {
|
||||
return New(FgRed).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// GreenString is an convenient helper function to return a string with green
|
||||
// foreground.
|
||||
func GreenString(format string, a ...interface{}) string {
|
||||
return New(FgGreen).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// YellowString is an convenient helper function to return a string with yellow
|
||||
// foreground.
|
||||
func YellowString(format string, a ...interface{}) string {
|
||||
return New(FgYellow).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// BlueString is an convenient helper function to return a string with blue
|
||||
// foreground.
|
||||
func BlueString(format string, a ...interface{}) string {
|
||||
return New(FgBlue).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// MagentaString is an convenient helper function to return a string with magenta
|
||||
// foreground.
|
||||
func MagentaString(format string, a ...interface{}) string {
|
||||
return New(FgMagenta).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// CyanString is an convenient helper function to return a string with cyan
|
||||
// foreground.
|
||||
func CyanString(format string, a ...interface{}) string {
|
||||
return New(FgCyan).SprintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// WhiteString is an convenient helper function to return a string with white
|
||||
// foreground.
|
||||
func WhiteString(format string, a ...interface{}) string {
|
||||
return New(FgWhite).SprintfFunc()(format, a...)
|
||||
}
|
176
Godeps/_workspace/src/github.com/fatih/color/color_test.go
generated
vendored
Normal file
176
Godeps/_workspace/src/github.com/fatih/color/color_test.go
generated
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
// Testing colors is kinda different. First we test for given colors and their
|
||||
// escaped formatted results. Next we create some visual tests to be tested.
|
||||
// Each visual test includes the color name to be compared.
|
||||
func TestColor(t *testing.T) {
|
||||
rb := new(bytes.Buffer)
|
||||
Output = rb
|
||||
|
||||
testColors := []struct {
|
||||
text string
|
||||
code Attribute
|
||||
}{
|
||||
{text: "black", code: FgBlack},
|
||||
{text: "red", code: FgRed},
|
||||
{text: "green", code: FgGreen},
|
||||
{text: "yellow", code: FgYellow},
|
||||
{text: "blue", code: FgBlue},
|
||||
{text: "magent", code: FgMagenta},
|
||||
{text: "cyan", code: FgCyan},
|
||||
{text: "white", code: FgWhite},
|
||||
}
|
||||
|
||||
for _, c := range testColors {
|
||||
New(c.code).Print(c.text)
|
||||
|
||||
line, _ := rb.ReadString('\n')
|
||||
scannedLine := fmt.Sprintf("%q", line)
|
||||
colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
|
||||
escapedForm := fmt.Sprintf("%q", colored)
|
||||
|
||||
fmt.Printf("%s\t: %s\n", c.text, line)
|
||||
|
||||
if scannedLine != escapedForm {
|
||||
t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoColor(t *testing.T) {
|
||||
rb := new(bytes.Buffer)
|
||||
Output = rb
|
||||
|
||||
testColors := []struct {
|
||||
text string
|
||||
code Attribute
|
||||
}{
|
||||
{text: "black", code: FgBlack},
|
||||
{text: "red", code: FgRed},
|
||||
{text: "green", code: FgGreen},
|
||||
{text: "yellow", code: FgYellow},
|
||||
{text: "blue", code: FgBlue},
|
||||
{text: "magent", code: FgMagenta},
|
||||
{text: "cyan", code: FgCyan},
|
||||
{text: "white", code: FgWhite},
|
||||
}
|
||||
|
||||
for _, c := range testColors {
|
||||
p := New(c.code)
|
||||
p.DisableColor()
|
||||
p.Print(c.text)
|
||||
|
||||
line, _ := rb.ReadString('\n')
|
||||
if line != c.text {
|
||||
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
||||
}
|
||||
}
|
||||
|
||||
// global check
|
||||
NoColor = true
|
||||
defer func() {
|
||||
NoColor = false
|
||||
}()
|
||||
for _, c := range testColors {
|
||||
p := New(c.code)
|
||||
p.Print(c.text)
|
||||
|
||||
line, _ := rb.ReadString('\n')
|
||||
if line != c.text {
|
||||
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestColorVisual(t *testing.T) {
|
||||
// First Visual Test
|
||||
fmt.Println("")
|
||||
Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
|
||||
New(FgRed).Printf("red\t")
|
||||
New(BgRed).Print(" ")
|
||||
New(FgRed, Bold).Println(" red")
|
||||
|
||||
New(FgGreen).Printf("green\t")
|
||||
New(BgGreen).Print(" ")
|
||||
New(FgGreen, Bold).Println(" green")
|
||||
|
||||
New(FgYellow).Printf("yellow\t")
|
||||
New(BgYellow).Print(" ")
|
||||
New(FgYellow, Bold).Println(" yellow")
|
||||
|
||||
New(FgBlue).Printf("blue\t")
|
||||
New(BgBlue).Print(" ")
|
||||
New(FgBlue, Bold).Println(" blue")
|
||||
|
||||
New(FgMagenta).Printf("magenta\t")
|
||||
New(BgMagenta).Print(" ")
|
||||
New(FgMagenta, Bold).Println(" magenta")
|
||||
|
||||
New(FgCyan).Printf("cyan\t")
|
||||
New(BgCyan).Print(" ")
|
||||
New(FgCyan, Bold).Println(" cyan")
|
||||
|
||||
New(FgWhite).Printf("white\t")
|
||||
New(BgWhite).Print(" ")
|
||||
New(FgWhite, Bold).Println(" white")
|
||||
fmt.Println("")
|
||||
|
||||
// Second Visual test
|
||||
Black("black")
|
||||
Red("red")
|
||||
Green("green")
|
||||
Yellow("yellow")
|
||||
Blue("blue")
|
||||
Magenta("magenta")
|
||||
Cyan("cyan")
|
||||
White("white")
|
||||
|
||||
// Third visual test
|
||||
fmt.Println()
|
||||
Set(FgBlue)
|
||||
fmt.Println("is this blue?")
|
||||
Unset()
|
||||
|
||||
Set(FgMagenta)
|
||||
fmt.Println("and this magenta?")
|
||||
Unset()
|
||||
|
||||
// Fourth Visual test
|
||||
fmt.Println()
|
||||
blue := New(FgBlue).PrintlnFunc()
|
||||
blue("blue text with custom print func")
|
||||
|
||||
red := New(FgRed).PrintfFunc()
|
||||
red("red text with a printf func: %d\n", 123)
|
||||
|
||||
put := New(FgYellow).SprintFunc()
|
||||
warn := New(FgRed).SprintFunc()
|
||||
|
||||
fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
|
||||
|
||||
info := New(FgWhite, BgGreen).SprintFunc()
|
||||
fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
|
||||
|
||||
// Fifth Visual Test
|
||||
fmt.Println()
|
||||
|
||||
fmt.Fprintln(Output, BlackString("black"))
|
||||
fmt.Fprintln(Output, RedString("red"))
|
||||
fmt.Fprintln(Output, GreenString("green"))
|
||||
fmt.Fprintln(Output, YellowString("yellow"))
|
||||
fmt.Fprintln(Output, BlueString("blue"))
|
||||
fmt.Fprintln(Output, MagentaString("magenta"))
|
||||
fmt.Fprintln(Output, CyanString("cyan"))
|
||||
fmt.Fprintln(Output, WhiteString("white"))
|
||||
}
|
114
Godeps/_workspace/src/github.com/fatih/color/doc.go
generated
vendored
Normal file
114
Godeps/_workspace/src/github.com/fatih/color/doc.go
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
Package color is an ANSI color package to output colorized or SGR defined
|
||||
output to the standard output. The API can be used in several way, pick one
|
||||
that suits you.
|
||||
|
||||
Use simple and default helper functions with predefined foreground colors:
|
||||
|
||||
color.Cyan("Prints text in cyan.")
|
||||
|
||||
// a newline will be appended automatically
|
||||
color.Blue("Prints %s in blue.", "text")
|
||||
|
||||
// More default foreground colors..
|
||||
color.Red("We have red")
|
||||
color.Yellow("Yellow color too!")
|
||||
color.Magenta("And many others ..")
|
||||
|
||||
However there are times where custom color mixes are required. Below are some
|
||||
examples to create custom color objects and use the print functions of each
|
||||
separate color object.
|
||||
|
||||
// Create a new color object
|
||||
c := color.New(color.FgCyan).Add(color.Underline)
|
||||
c.Println("Prints cyan text with an underline.")
|
||||
|
||||
// Or just add them to New()
|
||||
d := color.New(color.FgCyan, color.Bold)
|
||||
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||
|
||||
|
||||
// Mix up foreground and background colors, create new mixes!
|
||||
red := color.New(color.FgRed)
|
||||
|
||||
boldRed := red.Add(color.Bold)
|
||||
boldRed.Println("This will print text in bold red.")
|
||||
|
||||
whiteBackground := red.Add(color.BgWhite)
|
||||
whiteBackground.Println("Red text with White background.")
|
||||
|
||||
|
||||
You can create PrintXxx functions to simplify even more:
|
||||
|
||||
// Create a custom print function for convenient
|
||||
red := color.New(color.FgRed).PrintfFunc()
|
||||
red("warning")
|
||||
red("error: %s", err)
|
||||
|
||||
// Mix up multiple attributes
|
||||
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||
notice("don't forget this...")
|
||||
|
||||
|
||||
Or create SprintXxx functions to mix strings with other non-colorized strings:
|
||||
|
||||
yellow := New(FgYellow).SprintFunc()
|
||||
red := New(FgRed).SprintFunc()
|
||||
|
||||
fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||
|
||||
info := New(FgWhite, BgGreen).SprintFunc()
|
||||
fmt.Printf("this %s rocks!\n", info("package"))
|
||||
|
||||
Windows support is enabled by default. All Print functions works as intended.
|
||||
However only for color.SprintXXX functions, user should use fmt.FprintXXX and
|
||||
set the output to color.Output:
|
||||
|
||||
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||
|
||||
info := New(FgWhite, BgGreen).SprintFunc()
|
||||
fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
|
||||
|
||||
Using with existing code is possible. Just use the Set() method to set the
|
||||
standard output to the given parameters. That way a rewrite of an existing
|
||||
code is not required.
|
||||
|
||||
// Use handy standard colors.
|
||||
color.Set(color.FgYellow)
|
||||
|
||||
fmt.Println("Existing text will be now in Yellow")
|
||||
fmt.Printf("This one %s\n", "too")
|
||||
|
||||
color.Unset() // don't forget to unset
|
||||
|
||||
// You can mix up parameters
|
||||
color.Set(color.FgMagenta, color.Bold)
|
||||
defer color.Unset() // use it in your function
|
||||
|
||||
fmt.Println("All text will be now bold magenta.")
|
||||
|
||||
There might be a case where you want to disable color output (for example to
|
||||
pipe the standard output of your app to somewhere else). `Color` has support to
|
||||
disable colors both globally and for single color definition. For example
|
||||
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
|
||||
the color output with:
|
||||
|
||||
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||
|
||||
if *flagNoColor {
|
||||
color.NoColor = true // disables colorized output
|
||||
}
|
||||
|
||||
It also has support for single color definitions (local). You can
|
||||
disable/enable color output on the fly:
|
||||
|
||||
c := color.New(color.FgCyan)
|
||||
c.Println("Prints cyan text")
|
||||
|
||||
c.DisableColor()
|
||||
c.Println("This is printed without any color")
|
||||
|
||||
c.EnableColor()
|
||||
c.Println("This prints again cyan...")
|
||||
*/
|
||||
package color
|
42
Godeps/_workspace/src/github.com/mattn/go-colorable/README.md
generated
vendored
42
Godeps/_workspace/src/github.com/mattn/go-colorable/README.md
generated
vendored
@ -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!
|
||||
|
||||

|
||||
|
||||
|
||||
## So Good!
|
||||
|
||||

|
||||
|
||||
## 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)
|
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
@ -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
|
||||
}
|
594
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
594
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
@ -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()
|
||||
}
|
||||
}
|
9
Godeps/_workspace/src/github.com/mattn/go-isatty/LICENSE
generated
vendored
Normal file
9
Godeps/_workspace/src/github.com/mattn/go-isatty/LICENSE
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
|
||||
|
||||
MIT License (Expat)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2
Godeps/_workspace/src/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
2
Godeps/_workspace/src/github.com/mattn/go-isatty/isatty_bsd.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// +build darwin freebsd
|
||||
// +build darwin freebsd openbsd netbsd
|
||||
|
||||
package isatty
|
||||
|
||||
|
1
Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS
generated
vendored
Normal file
1
Godeps/_workspace/src/github.com/pborman/uuid/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
Paul Borman <borman@google.com>
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009 Google Inc. All rights reserved.
|
||||
Copyright (c) 2009,2014 Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
30
Godeps/_workspace/src/github.com/pborman/uuid/json.go
generated
vendored
Normal file
30
Godeps/_workspace/src/github.com/pborman/uuid/json.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2014 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "errors"
|
||||
|
||||
func (u UUID) MarshalJSON() ([]byte, error) {
|
||||
if len(u) == 0 {
|
||||
return []byte(`""`), nil
|
||||
}
|
||||
return []byte(`"` + u.String() + `"`), nil
|
||||
}
|
||||
|
||||
func (u *UUID) UnmarshalJSON(data []byte) error {
|
||||
if len(data) == 0 || string(data) == `""` {
|
||||
return nil
|
||||
}
|
||||
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
data = data[1 : len(data)-1]
|
||||
uu := Parse(string(data))
|
||||
if uu == nil {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
*u = uu
|
||||
return nil
|
||||
}
|
32
Godeps/_workspace/src/github.com/pborman/uuid/json_test.go
generated
vendored
Normal file
32
Godeps/_workspace/src/github.com/pborman/uuid/json_test.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2014 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
|
||||
|
||||
func TestJSON(t *testing.T) {
|
||||
type S struct {
|
||||
ID1 UUID
|
||||
ID2 UUID
|
||||
}
|
||||
s1 := S{ID1: testUUID}
|
||||
data, err := json.Marshal(&s1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var s2 S
|
||||
if err := json.Unmarshal(data, &s2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(&s1, &s2) {
|
||||
t.Errorf("got %#v, want %#v", s2, s1)
|
||||
}
|
||||
}
|
66
Godeps/_workspace/src/github.com/pborman/uuid/seq_test.go
generated
vendored
Normal file
66
Godeps/_workspace/src/github.com/pborman/uuid/seq_test.go
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 2014 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// This test is only run when --regressions is passed on the go test line.
|
||||
var regressions = flag.Bool("regressions", false, "run uuid regression tests")
|
||||
|
||||
// TestClockSeqRace tests for a particular race condition of returning two
|
||||
// identical Version1 UUIDs. The duration of 1 minute was chosen as the race
|
||||
// condition, before being fixed, nearly always occured in under 30 seconds.
|
||||
func TestClockSeqRace(t *testing.T) {
|
||||
if !*regressions {
|
||||
t.Skip("skipping regression tests")
|
||||
}
|
||||
duration := time.Minute
|
||||
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
|
||||
ch := make(chan UUID, 10000)
|
||||
ncpu := runtime.NumCPU()
|
||||
switch ncpu {
|
||||
case 0, 1:
|
||||
// We can't run the test effectively.
|
||||
t.Skip("skipping race test, only one CPU detected")
|
||||
return
|
||||
default:
|
||||
runtime.GOMAXPROCS(ncpu)
|
||||
}
|
||||
for i := 0; i < ncpu; i++ {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case ch <- NewUUID():
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
uuids := make(map[string]bool)
|
||||
cnt := 0
|
||||
start := time.Now()
|
||||
for u := range ch {
|
||||
s := u.String()
|
||||
if uuids[s] {
|
||||
t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s)
|
||||
return
|
||||
}
|
||||
uuids[s] = true
|
||||
if time.Since(start) > duration {
|
||||
return
|
||||
}
|
||||
cnt++
|
||||
}
|
||||
}
|
40
Godeps/_workspace/src/github.com/pborman/uuid/sql.go
generated
vendored
Normal file
40
Godeps/_workspace/src/github.com/pborman/uuid/sql.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
switch src.(type) {
|
||||
case string:
|
||||
// see uuid.Parse for required string format
|
||||
parsed := Parse(src.(string))
|
||||
|
||||
if parsed == nil {
|
||||
return errors.New("Scan: invalid UUID format")
|
||||
}
|
||||
|
||||
*uuid = parsed
|
||||
case []byte:
|
||||
// assumes a simple slice of bytes, just check validity and store
|
||||
u := UUID(src.([]byte))
|
||||
|
||||
if u.Variant() == Invalid {
|
||||
return errors.New("Scan: invalid UUID format")
|
||||
}
|
||||
|
||||
*uuid = u
|
||||
default:
|
||||
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
53
Godeps/_workspace/src/github.com/pborman/uuid/sql_test.go
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/pborman/uuid/sql_test.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScan(t *testing.T) {
|
||||
var stringTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d479"
|
||||
var byteTest []byte = Parse(stringTest)
|
||||
var badTypeTest int = 6
|
||||
var invalidTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d4"
|
||||
var invalidByteTest []byte = Parse(invalidTest)
|
||||
|
||||
var uuid UUID
|
||||
err := (&uuid).Scan(stringTest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = (&uuid).Scan(byteTest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = (&uuid).Scan(badTypeTest)
|
||||
if err == nil {
|
||||
t.Error("int correctly parsed and shouldn't have")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "unable to scan type") {
|
||||
t.Error("attempting to parse an int returned an incorrect error message")
|
||||
}
|
||||
|
||||
err = (&uuid).Scan(invalidTest)
|
||||
if err == nil {
|
||||
t.Error("invalid uuid was parsed without error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "invalid UUID") {
|
||||
t.Error("attempting to parse an invalid UUID returned an incorrect error message")
|
||||
}
|
||||
|
||||
err = (&uuid).Scan(invalidByteTest)
|
||||
if err == nil {
|
||||
t.Error("invalid byte uuid was parsed without error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "invalid UUID") {
|
||||
t.Error("attempting to parse an invalid byte UUID returned an incorrect error message")
|
||||
}
|
||||
}
|
@ -40,15 +40,15 @@ func (t Time) UnixTime() (sec, nsec int64) {
|
||||
}
|
||||
|
||||
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
||||
// adjusts the clock sequence as needed. An error is returned if the current
|
||||
// time cannot be determined.
|
||||
func GetTime() (Time, error) {
|
||||
// clock sequence as well as adjusting the clock sequence as needed. An error
|
||||
// is returned if the current time cannot be determined.
|
||||
func GetTime() (Time, uint16, error) {
|
||||
defer mu.Unlock()
|
||||
mu.Lock()
|
||||
return getTime()
|
||||
}
|
||||
|
||||
func getTime() (Time, error) {
|
||||
func getTime() (Time, uint16, error) {
|
||||
t := timeNow()
|
||||
|
||||
// If we don't have a clock sequence already, set one.
|
||||
@ -63,7 +63,7 @@ func getTime() (Time, error) {
|
||||
clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000
|
||||
}
|
||||
lasttime = now
|
||||
return Time(now), nil
|
||||
return Time(now), clock_seq, nil
|
||||
}
|
||||
|
||||
// ClockSequence returns the current clock sequence, generating one if not
|
@ -19,7 +19,7 @@ func NewUUID() UUID {
|
||||
SetNodeInterface("")
|
||||
}
|
||||
|
||||
now, err := GetTime()
|
||||
now, seq, err := GetTime()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -34,7 +34,7 @@ func NewUUID() UUID {
|
||||
binary.BigEndian.PutUint32(uuid[0:], time_low)
|
||||
binary.BigEndian.PutUint16(uuid[4:], time_mid)
|
||||
binary.BigEndian.PutUint16(uuid[6:], time_hi)
|
||||
binary.BigEndian.PutUint16(uuid[8:], clock_seq)
|
||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
||||
copy(uuid[10:], nodeID)
|
||||
|
||||
return uuid
|
144
Godeps/_workspace/src/github.com/rakyll/globalconf/README.md
generated
vendored
144
Godeps/_workspace/src/github.com/rakyll/globalconf/README.md
generated
vendored
@ -1,144 +0,0 @@
|
||||
# globalconf
|
||||
|
||||
[](https://travis-ci.org/rakyll/globalconf)
|
||||
|
||||
Effortlessly persist/retrieve flags of your Golang programs. If you need global configuration instead of requiring user always to set command line flags, you are looking at the right package. `globalconf` allows your users to not only provide flags, but config files and environment variables as well.
|
||||
|
||||
## Usage
|
||||
|
||||
~~~ go
|
||||
import "github.com/rakyll/globalconf"
|
||||
~~~
|
||||
|
||||
### Loading a config file
|
||||
|
||||
By default, globalconf provides you a config file under `~/.config/<yourappname>/config.ini`.
|
||||
|
||||
~~~ go
|
||||
globalconf.New("appname") // loads from ~/.config/<appname>/config.ini
|
||||
~~~
|
||||
|
||||
If you don't prefer the default location you can load from a specified path as well.
|
||||
|
||||
~~~ go
|
||||
globalconf.NewWithOptions(&globalconf.Options{
|
||||
Filename: "/path/to/config/file",
|
||||
})
|
||||
~~~
|
||||
|
||||
You may like to override configuration with env variables. See "Environment variables" header to see how to it works.
|
||||
|
||||
~~~ go
|
||||
globalconf.NewWithOptions(&globalconf.Options{
|
||||
Filename: "/path/to/config/file",
|
||||
EnvPrefix: "APPCONF_",
|
||||
})
|
||||
~~~
|
||||
|
||||
### Parsing flag values
|
||||
|
||||
`globalconf` populates flags with data in the config file if they are not already set.
|
||||
|
||||
~~~ go
|
||||
var (
|
||||
flagName = flag.String("name", "", "Name of the person.")
|
||||
flagAddress = flag.String("addr", "", "Address of the person.")
|
||||
)
|
||||
~~~
|
||||
|
||||
Assume the configuration file to be loaded contains the following lines.
|
||||
|
||||
name = Burcu
|
||||
addr = Brandschenkestrasse 110, 8002
|
||||
|
||||
And your program is being started, `$ myapp -name=Jane`
|
||||
~~~ go
|
||||
conf, err := globalconf.New("myapp")
|
||||
conf.ParseAll()
|
||||
~~~
|
||||
|
||||
`*flagName` is going to be equal to `Jane`, whereas `*flagAddress` is `Brandschenkestrasse 110, 8002`, what is provided in the configuration file.
|
||||
|
||||
### Custom flag sets
|
||||
|
||||
Custom flagsets are supported, but required registration before parse is done. The default flagset `flag.CommandLine` is automatically registered.
|
||||
|
||||
~~~ go
|
||||
globalconf.Register("termopts", termOptsFlagSet)
|
||||
conf.ParseAll() // parses command line and all registered flag sets
|
||||
~~~
|
||||
|
||||
Custom flagset values should be provided in their own segment. Getting back to the sample ini config file, termopts values will have their own segment.
|
||||
|
||||
name = Burcu
|
||||
addr = Brandschenkestrasse 110, 8002
|
||||
|
||||
[termopts]
|
||||
color = true
|
||||
background = ff0000
|
||||
|
||||
### Environment variables
|
||||
|
||||
If an EnvPrefix is provided, environment variables will take precedence over values in the configuration file.
|
||||
Set the `EnvPrefix` option when calling `globalconf.NewWithOptions`.
|
||||
An `EnvPrefix` will only be used if it is a non-empty string.
|
||||
Command line flags will override the environment variables.
|
||||
|
||||
~~~ go
|
||||
opts := globalconf.Options{
|
||||
EnvPrefix: "MYAPP_",
|
||||
Filename: "/path/to/config",
|
||||
}
|
||||
conf, err := globalconf.NewWithOptions(&opts)
|
||||
conf.ParseAll()
|
||||
~~~
|
||||
|
||||
With environment variables:
|
||||
|
||||
APPCONF_NAME = Burcu
|
||||
|
||||
and configuration:
|
||||
|
||||
name = Jane
|
||||
addr = Brandschenkestrasse 110, 8002
|
||||
|
||||
`name` will be set to "burcu" and `addr` will be set to "Brandschenkestrasse 110, 8002".
|
||||
|
||||
### Modifying stored flags
|
||||
|
||||
Modifications are persisted as long as you set a new flag and your GlobalConf
|
||||
object was configured with a filename.
|
||||
|
||||
~~~ go
|
||||
f := &flag.Flag{Name: "name", Value: val}
|
||||
conf.Set("", f) // if you are modifying a command line flag
|
||||
|
||||
f := &flag.Flag{Name: "color", Value: val}
|
||||
conf.Set("termopts", color) // if you are modifying a custom flag set flag
|
||||
~~~
|
||||
|
||||
### Deleting stored flags
|
||||
|
||||
Like Set, Deletions are persisted as long as you delete a flag's value and your
|
||||
GlobalConf object was configured with a filename.
|
||||
|
||||
~~~ go
|
||||
conf.Delete("", "name") // removes command line flag "name"s value from config
|
||||
conf.Delete("termopts", "color") // removes "color"s value from the custom flag set
|
||||
~~~
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. 
|
179
Godeps/_workspace/src/github.com/rakyll/globalconf/globalconf.go
generated
vendored
179
Godeps/_workspace/src/github.com/rakyll/globalconf/globalconf.go
generated
vendored
@ -1,179 +0,0 @@
|
||||
package globalconf
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
ini "github.com/rakyll/goini"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultConfigFileName = "config.ini"
|
||||
)
|
||||
|
||||
var flags map[string]*flag.FlagSet = make(map[string]*flag.FlagSet)
|
||||
|
||||
// Represents a GlobalConf context.
|
||||
type GlobalConf struct {
|
||||
Filename string
|
||||
EnvPrefix string
|
||||
dict *ini.Dict
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
Filename string
|
||||
EnvPrefix string
|
||||
}
|
||||
|
||||
// NewWithOptions creates a GlobalConf from the provided
|
||||
// Options. The caller is responsible for creating any
|
||||
// referenced config files.
|
||||
func NewWithOptions(opts *Options) (g *GlobalConf, err error) {
|
||||
Register("", flag.CommandLine)
|
||||
|
||||
var dict ini.Dict
|
||||
if opts.Filename != "" {
|
||||
dict, err = ini.Load(opts.Filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
dict = make(ini.Dict, 0)
|
||||
}
|
||||
|
||||
return &GlobalConf{
|
||||
Filename: opts.Filename,
|
||||
EnvPrefix: opts.EnvPrefix,
|
||||
dict: &dict,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Opens/creates a config file for the specified appName.
|
||||
// The path to config file is ~/.config/appName/config.ini.
|
||||
func New(appName string) (g *GlobalConf, err error) {
|
||||
var u *user.User
|
||||
if u, err = user.Current(); u == nil {
|
||||
return
|
||||
}
|
||||
// Create config file's directory.
|
||||
dirPath := path.Join(u.HomeDir, ".config", appName)
|
||||
if err = os.MkdirAll(dirPath, 0755); err != nil {
|
||||
return
|
||||
}
|
||||
// Touch a config file if it doesn't exit.
|
||||
filePath := path.Join(dirPath, defaultConfigFileName)
|
||||
if _, err = os.Stat(filePath); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
// create file
|
||||
if err = ioutil.WriteFile(filePath, []byte{}, 0644); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
opts := Options{Filename: filePath}
|
||||
return NewWithOptions(&opts)
|
||||
}
|
||||
|
||||
// Sets a flag's value and persists the changes to the disk.
|
||||
func (g *GlobalConf) Set(flagSetName string, f *flag.Flag) error {
|
||||
g.dict.SetString(flagSetName, f.Name, f.Value.String())
|
||||
if g.Filename != "" {
|
||||
return ini.Write(g.Filename, g.dict)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deletes a flag from config file and persists the changes
|
||||
// to the disk.
|
||||
func (g *GlobalConf) Delete(flagSetName, flagName string) error {
|
||||
g.dict.Delete(flagSetName, flagName)
|
||||
if g.Filename != "" {
|
||||
return ini.Write(g.Filename, g.dict)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parses the config file for the provided flag set.
|
||||
// If the flags are already set, values are overwritten
|
||||
// by the values in the config file. Defaults are not set
|
||||
// if the flag is not in the file.
|
||||
func (g *GlobalConf) ParseSet(flagSetName string, set *flag.FlagSet) {
|
||||
set.VisitAll(func(f *flag.Flag) {
|
||||
val := getEnv(g.EnvPrefix, flagSetName, f.Name)
|
||||
if val != "" {
|
||||
set.Set(f.Name, val)
|
||||
return
|
||||
}
|
||||
|
||||
val, found := g.dict.GetString(flagSetName, f.Name)
|
||||
if found {
|
||||
set.Set(f.Name, val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Parses all the registered flag sets, including the command
|
||||
// line set and sets values from the config file if they are
|
||||
// not already set.
|
||||
func (g *GlobalConf) Parse() {
|
||||
for name, set := range flags {
|
||||
alreadySet := make(map[string]bool)
|
||||
set.Visit(func(f *flag.Flag) {
|
||||
alreadySet[f.Name] = true
|
||||
})
|
||||
set.VisitAll(func(f *flag.Flag) {
|
||||
// if not already set, set it from dict if exists
|
||||
if alreadySet[f.Name] {
|
||||
return
|
||||
}
|
||||
|
||||
val := getEnv(g.EnvPrefix, name, f.Name)
|
||||
if val != "" {
|
||||
set.Set(f.Name, val)
|
||||
return
|
||||
}
|
||||
|
||||
val, found := g.dict.GetString(name, f.Name)
|
||||
if found {
|
||||
set.Set(f.Name, val)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Parses command line flags and then, all of the registered
|
||||
// flag sets with the values provided in the config file.
|
||||
func (g *GlobalConf) ParseAll() {
|
||||
if !flag.Parsed() {
|
||||
flag.Parse()
|
||||
}
|
||||
g.Parse()
|
||||
}
|
||||
|
||||
// Looks up variable in environment
|
||||
func getEnv(envPrefix, flagSetName, flagName string) string {
|
||||
// If we haven't set an EnvPrefix, don't lookup vals in the ENV
|
||||
if envPrefix == "" {
|
||||
return ""
|
||||
}
|
||||
// Append a _ to flagSetName if it exists.
|
||||
if flagSetName != "" {
|
||||
flagSetName += "_"
|
||||
}
|
||||
flagName = strings.Replace(flagName, ".", "_", -1)
|
||||
flagName = strings.Replace(flagName, "-", "_", -1)
|
||||
envKey := strings.ToUpper(envPrefix + flagSetName + flagName)
|
||||
return os.Getenv(envKey)
|
||||
}
|
||||
|
||||
// Registers a flag set to be parsed. Register all flag sets
|
||||
// before calling this function. flag.CommandLine is automatically
|
||||
// registered.
|
||||
func Register(flagSetName string, set *flag.FlagSet) {
|
||||
flags[flagSetName] = set
|
||||
}
|
267
Godeps/_workspace/src/github.com/rakyll/globalconf/globalconf_test.go
generated
vendored
267
Godeps/_workspace/src/github.com/rakyll/globalconf/globalconf_test.go
generated
vendored
@ -1,267 +0,0 @@
|
||||
package globalconf
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const envTestPrefix = "CONFTEST_"
|
||||
|
||||
func TestNewWithOptionsNoFilename(t *testing.T) {
|
||||
opts := Options{EnvPrefix: envTestPrefix}
|
||||
|
||||
os.Setenv(envTestPrefix+"D", "EnvD")
|
||||
|
||||
flagD := flag.String("d", "default", "")
|
||||
flagE := flag.Bool("e", true, "")
|
||||
|
||||
conf, err := NewWithOptions(&opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conf.ParseAll()
|
||||
|
||||
if *flagD != "EnvD" {
|
||||
t.Errorf("flagD found %v, expected 'EnvD'", *flagD)
|
||||
}
|
||||
if !*flagE {
|
||||
t.Errorf("flagE found %v, expected true", *flagE)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_Global(t *testing.T) {
|
||||
resetForTesting("")
|
||||
|
||||
os.Setenv(envTestPrefix+"D", "EnvD")
|
||||
os.Setenv(envTestPrefix+"E", "true")
|
||||
os.Setenv(envTestPrefix+"F", "5.5")
|
||||
|
||||
flagA := flag.Bool("a", false, "")
|
||||
flagB := flag.Float64("b", 0.0, "")
|
||||
flagC := flag.String("c", "", "")
|
||||
|
||||
flagD := flag.String("d", "", "")
|
||||
flagE := flag.Bool("e", false, "")
|
||||
flagF := flag.Float64("f", 0.0, "")
|
||||
|
||||
parse(t, "./testdata/global.ini", envTestPrefix)
|
||||
if !*flagA {
|
||||
t.Errorf("flagA found %v, expected true", *flagA)
|
||||
}
|
||||
if *flagB != 5.6 {
|
||||
t.Errorf("flagB found %v, expected 5.6", *flagB)
|
||||
}
|
||||
if *flagC != "Hello world" {
|
||||
t.Errorf("flagC found %v, expected 'Hello world'", *flagC)
|
||||
}
|
||||
if *flagD != "EnvD" {
|
||||
t.Errorf("flagD found %v, expected 'EnvD'", *flagD)
|
||||
}
|
||||
if !*flagE {
|
||||
t.Errorf("flagE found %v, expected true", *flagE)
|
||||
}
|
||||
if *flagF != 5.5 {
|
||||
t.Errorf("flagF found %v, expected 5.5", *flagF)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_DashConversion(t *testing.T) {
|
||||
resetForTesting("")
|
||||
|
||||
flagFooBar := flag.String("foo-bar", "", "")
|
||||
os.Setenv("PREFIX_FOO_BAR", "baz")
|
||||
|
||||
opts := Options{EnvPrefix: "PREFIX_"}
|
||||
conf, err := NewWithOptions(&opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conf.ParseAll()
|
||||
|
||||
if *flagFooBar != "baz" {
|
||||
t.Errorf("flagFooBar found %v, expected 5.5", *flagFooBar)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_GlobalWithDottedFlagname(t *testing.T) {
|
||||
resetForTesting("")
|
||||
os.Setenv(envTestPrefix+"SOME_VALUE", "some-value")
|
||||
flagSomeValue := flag.String("some.value", "", "")
|
||||
|
||||
parse(t, "./testdata/global.ini", envTestPrefix)
|
||||
if *flagSomeValue != "some-value" {
|
||||
t.Errorf("flagSomeValue found %v, some-value expected", *flagSomeValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_GlobalOverwrite(t *testing.T) {
|
||||
resetForTesting("-b=7.6")
|
||||
flagB := flag.Float64("b", 0.0, "")
|
||||
|
||||
parse(t, "./testdata/global.ini", "")
|
||||
if *flagB != 7.6 {
|
||||
t.Errorf("flagB found %v, expected 7.6", *flagB)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_Custom(t *testing.T) {
|
||||
resetForTesting("")
|
||||
|
||||
os.Setenv(envTestPrefix+"CUSTOM_E", "Hello Env")
|
||||
|
||||
flagB := flag.Float64("b", 5.0, "")
|
||||
|
||||
name := "custom"
|
||||
custom := flag.NewFlagSet(name, flag.ExitOnError)
|
||||
flagD := custom.String("d", "dd", "")
|
||||
flagE := custom.String("e", "ee", "")
|
||||
|
||||
Register(name, custom)
|
||||
parse(t, "./testdata/custom.ini", envTestPrefix)
|
||||
if *flagB != 5.0 {
|
||||
t.Errorf("flagB found %v, expected 5.0", *flagB)
|
||||
}
|
||||
if *flagD != "Hello d" {
|
||||
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
|
||||
}
|
||||
if *flagE != "Hello Env" {
|
||||
t.Errorf("flagE found %v, expected 'Hello Env'", *flagE)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_CustomOverwrite(t *testing.T) {
|
||||
resetForTesting("-b=6")
|
||||
flagB := flag.Float64("b", 5.0, "")
|
||||
|
||||
name := "custom"
|
||||
custom := flag.NewFlagSet(name, flag.ExitOnError)
|
||||
flagD := custom.String("d", "dd", "")
|
||||
|
||||
Register(name, custom)
|
||||
parse(t, "./testdata/custom.ini", "")
|
||||
if *flagB != 6.0 {
|
||||
t.Errorf("flagB found %v, expected 6.0", *flagB)
|
||||
}
|
||||
if *flagD != "Hello d" {
|
||||
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_GlobalAndCustom(t *testing.T) {
|
||||
resetForTesting("")
|
||||
flagA := flag.Bool("a", false, "")
|
||||
flagB := flag.Float64("b", 0.0, "")
|
||||
flagC := flag.String("c", "", "")
|
||||
|
||||
name := "custom"
|
||||
custom := flag.NewFlagSet(name, flag.ExitOnError)
|
||||
flagD := custom.String("d", "", "")
|
||||
|
||||
Register(name, custom)
|
||||
parse(t, "./testdata/globalandcustom.ini", "")
|
||||
if !*flagA {
|
||||
t.Errorf("flagA found %v, expected true", *flagA)
|
||||
}
|
||||
if *flagB != 5.6 {
|
||||
t.Errorf("flagB found %v, expected 5.6", *flagB)
|
||||
}
|
||||
if *flagC != "Hello world" {
|
||||
t.Errorf("flagC found %v, expected 'Hello world'", *flagC)
|
||||
}
|
||||
if *flagD != "Hello d" {
|
||||
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse_GlobalAndCustomOverwrite(t *testing.T) {
|
||||
resetForTesting("-a=true", "-b=5", "-c=Hello")
|
||||
flagA := flag.Bool("a", false, "")
|
||||
flagB := flag.Float64("b", 0.0, "")
|
||||
flagC := flag.String("c", "", "")
|
||||
|
||||
name := "custom"
|
||||
custom := flag.NewFlagSet(name, flag.ExitOnError)
|
||||
flagD := custom.String("d", "", "")
|
||||
|
||||
Register(name, custom)
|
||||
parse(t, "./testdata/globalandcustom.ini", "")
|
||||
if !*flagA {
|
||||
t.Errorf("flagA found %v, expected true", *flagA)
|
||||
}
|
||||
if *flagB != 5.0 {
|
||||
t.Errorf("flagB found %v, expected 5.0", *flagB)
|
||||
}
|
||||
if *flagC != "Hello" {
|
||||
t.Errorf("flagC found %v, expected 'Hello'", *flagC)
|
||||
}
|
||||
if *flagD != "Hello d" {
|
||||
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
resetForTesting()
|
||||
file, _ := ioutil.TempFile("", "")
|
||||
conf := parse(t, file.Name(), "")
|
||||
conf.Set("", &flag.Flag{Name: "a", Value: newFlagValue("test")})
|
||||
|
||||
flagA := flag.String("a", "", "")
|
||||
parse(t, file.Name(), "")
|
||||
if *flagA != "test" {
|
||||
t.Errorf("flagA found %v, expected 'test'", *flagA)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
resetForTesting()
|
||||
file, _ := ioutil.TempFile("", "")
|
||||
conf := parse(t, file.Name(), "")
|
||||
conf.Set("", &flag.Flag{Name: "a", Value: newFlagValue("test")})
|
||||
conf.Delete("", "a")
|
||||
|
||||
flagA := flag.String("a", "", "")
|
||||
parse(t, file.Name(), "")
|
||||
if *flagA != "" {
|
||||
t.Errorf("flagNewA found %v, expected ''", *flagA)
|
||||
}
|
||||
}
|
||||
|
||||
func parse(t *testing.T, filename, envPrefix string) *GlobalConf {
|
||||
opts := Options{
|
||||
Filename: filename,
|
||||
EnvPrefix: envPrefix,
|
||||
}
|
||||
conf, err := NewWithOptions(&opts)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
conf.ParseAll()
|
||||
return conf
|
||||
}
|
||||
|
||||
// Resets os.Args and the default flag set.
|
||||
func resetForTesting(args ...string) {
|
||||
os.Clearenv()
|
||||
|
||||
os.Args = append([]string{"cmd"}, args...)
|
||||
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
|
||||
}
|
||||
|
||||
type flagValue struct {
|
||||
str string
|
||||
}
|
||||
|
||||
func (f *flagValue) String() string {
|
||||
return f.str
|
||||
}
|
||||
|
||||
func (f *flagValue) Set(value string) error {
|
||||
f.str = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func newFlagValue(val string) *flagValue {
|
||||
return &flagValue{str: val}
|
||||
}
|
2
Godeps/_workspace/src/github.com/rakyll/globalconf/testdata/custom.ini
generated
vendored
2
Godeps/_workspace/src/github.com/rakyll/globalconf/testdata/custom.ini
generated
vendored
@ -1,2 +0,0 @@
|
||||
[custom]
|
||||
d = Hello d
|
3
Godeps/_workspace/src/github.com/rakyll/globalconf/testdata/global.ini
generated
vendored
3
Godeps/_workspace/src/github.com/rakyll/globalconf/testdata/global.ini
generated
vendored
@ -1,3 +0,0 @@
|
||||
a = true
|
||||
b = 5.6
|
||||
c = Hello world
|
6
Godeps/_workspace/src/github.com/rakyll/globalconf/testdata/globalandcustom.ini
generated
vendored
6
Godeps/_workspace/src/github.com/rakyll/globalconf/testdata/globalandcustom.ini
generated
vendored
@ -1,6 +0,0 @@
|
||||
a = true
|
||||
b = 5.6
|
||||
c = Hello world
|
||||
|
||||
[custom]
|
||||
d = Hello d
|
8
Godeps/_workspace/src/github.com/rakyll/goini/.gitignore
generated
vendored
8
Godeps/_workspace/src/github.com/rakyll/goini/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
||||
.*.swp
|
||||
|
||||
*.[689]
|
||||
[689].out
|
||||
|
||||
_obj
|
||||
_test
|
||||
_testmain.go
|
7
Godeps/_workspace/src/github.com/rakyll/goini/Makefile
generated
vendored
7
Godeps/_workspace/src/github.com/rakyll/goini/Makefile
generated
vendored
@ -1,7 +0,0 @@
|
||||
test:
|
||||
go test
|
||||
|
||||
format:
|
||||
gofmt -w *.go
|
||||
|
||||
.PHONY: format test
|
0
Godeps/_workspace/src/github.com/rakyll/goini/empty.ini
generated
vendored
0
Godeps/_workspace/src/github.com/rakyll/goini/empty.ini
generated
vendored
18
Godeps/_workspace/src/github.com/rakyll/goini/example.ini
generated
vendored
18
Godeps/_workspace/src/github.com/rakyll/goini/example.ini
generated
vendored
@ -1,18 +0,0 @@
|
||||
#
|
||||
# This is an example of ini file
|
||||
#
|
||||
|
||||
[Pizza]
|
||||
|
||||
Ham = yes;
|
||||
Mushrooms = TRUE;
|
||||
Capres = 0;
|
||||
Cheese = Non;
|
||||
|
||||
|
||||
[Wine]
|
||||
|
||||
Grape = Cabernet Sauvignon;
|
||||
Year = 1989;
|
||||
Country = Spain;
|
||||
Alcohol = 12.5;
|
241
Godeps/_workspace/src/github.com/rakyll/goini/ini.go
generated
vendored
241
Godeps/_workspace/src/github.com/rakyll/goini/ini.go
generated
vendored
@ -1,241 +0,0 @@
|
||||
package ini
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type Dict map[string]map[string]string
|
||||
|
||||
type Error string
|
||||
|
||||
var (
|
||||
regDoubleQuote = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*\"([^\"]*)\"$")
|
||||
regSingleQuote = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*'([^']*)'$")
|
||||
regNoQuote = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*([^#;]+)")
|
||||
regNoValue = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*([#;].*)?")
|
||||
)
|
||||
|
||||
func Load(filename string) (dict Dict, err error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
dict = make(map[string]map[string]string)
|
||||
reader := bufio.NewReader(file)
|
||||
lineno := 0
|
||||
section := ""
|
||||
dict[section] = make(map[string]string)
|
||||
|
||||
for err == nil {
|
||||
l, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
lineno++
|
||||
if len(l) == 0 {
|
||||
continue
|
||||
}
|
||||
line := strings.TrimFunc(string(l), unicode.IsSpace)
|
||||
|
||||
for line[len(line)-1] == '\\' {
|
||||
line = line[:len(line)-1]
|
||||
l, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
line += strings.TrimFunc(string(l), unicode.IsSpace)
|
||||
}
|
||||
|
||||
section, err = dict.parseLine(section, line)
|
||||
if err != nil {
|
||||
return nil, newError(
|
||||
err.Error() + fmt.Sprintf("'%s:%d'.", filename, lineno))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func Write(filename string, dict *Dict) error {
|
||||
buffer := dict.format()
|
||||
return ioutil.WriteFile(filename, buffer.Bytes(), 0644)
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
func (dict Dict) parseLine(section, line string) (string, error) {
|
||||
// commets
|
||||
if line[0] == '#' || line[0] == ';' {
|
||||
return section, nil
|
||||
}
|
||||
|
||||
// section name
|
||||
if line[0] == '[' && line[len(line)-1] == ']' {
|
||||
section := strings.TrimFunc(line[1:len(line)-1], unicode.IsSpace)
|
||||
section = strings.ToLower(section)
|
||||
dict[section] = make(map[string]string)
|
||||
return section, nil
|
||||
}
|
||||
|
||||
// key = value
|
||||
if m := regDoubleQuote.FindAllStringSubmatch(line, 1); m != nil {
|
||||
dict.add(section, m[0][1], m[0][2])
|
||||
return section, nil
|
||||
} else if m = regSingleQuote.FindAllStringSubmatch(line, 1); m != nil {
|
||||
dict.add(section, m[0][1], m[0][2])
|
||||
return section, nil
|
||||
} else if m = regNoQuote.FindAllStringSubmatch(line, 1); m != nil {
|
||||
dict.add(section, m[0][1], strings.TrimFunc(m[0][2], unicode.IsSpace))
|
||||
return section, nil
|
||||
} else if m = regNoValue.FindAllStringSubmatch(line, 1); m != nil {
|
||||
dict.add(section, m[0][1], "")
|
||||
return section, nil
|
||||
}
|
||||
|
||||
return section, newError("iniparser: syntax error at ")
|
||||
}
|
||||
|
||||
func (dict Dict) add(section, key, value string) {
|
||||
key = strings.ToLower(key)
|
||||
dict[section][key] = value
|
||||
}
|
||||
|
||||
func (dict Dict) GetBool(section, key string) (bool, bool) {
|
||||
sec, ok := dict[section]
|
||||
if !ok {
|
||||
return false, false
|
||||
}
|
||||
value, ok := sec[key]
|
||||
if !ok {
|
||||
return false, false
|
||||
}
|
||||
v := value[0]
|
||||
if v == 'y' || v == 'Y' || v == '1' || v == 't' || v == 'T' {
|
||||
return true, true
|
||||
}
|
||||
if v == 'n' || v == 'N' || v == '0' || v == 'f' || v == 'F' {
|
||||
return false, true
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
func (dict Dict) SetBool(section, key string, value bool) {
|
||||
dict.SetString(section, key, strconv.FormatBool(value))
|
||||
}
|
||||
|
||||
func (dict Dict) GetString(section, key string) (string, bool) {
|
||||
sec, ok := dict[section]
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
value, ok := sec[key]
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return value, true
|
||||
}
|
||||
|
||||
func (dict Dict) SetString(section, key, value string) {
|
||||
_, ok := dict[section]
|
||||
if !ok {
|
||||
dict[section] = make(map[string]string)
|
||||
}
|
||||
dict[section][key] = value
|
||||
}
|
||||
|
||||
func (dict Dict) GetInt(section, key string) (int, bool) {
|
||||
sec, ok := dict[section]
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
value, ok := sec[key]
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
i, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return i, true
|
||||
}
|
||||
|
||||
func (dict Dict) SetInt(section, key string, value int) {
|
||||
dict.SetString(section, key, strconv.FormatInt(int64(value), 10))
|
||||
}
|
||||
|
||||
func (dict Dict) GetDouble(section, key string) (float64, bool) {
|
||||
sec, ok := dict[section]
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
value, ok := sec[key]
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
d, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return d, true
|
||||
}
|
||||
|
||||
func (dict Dict) SetDouble(section, key string, value float64) {
|
||||
dict.SetString(section, key, strconv.FormatFloat(value, 'f', -1, 64))
|
||||
}
|
||||
|
||||
func (dict Dict) Delete(section, key string) {
|
||||
_, ok := dict[section]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
delete(dict[section], key)
|
||||
// If there are no items left in the section,
|
||||
// delete the section.
|
||||
if len(dict[section]) == 0 {
|
||||
delete(dict, section)
|
||||
}
|
||||
}
|
||||
|
||||
func (dict Dict) GetSections() []string {
|
||||
size := len(dict)
|
||||
sections := make([]string, size)
|
||||
i := 0
|
||||
for section, _ := range dict {
|
||||
sections[i] = section
|
||||
i++
|
||||
}
|
||||
return sections
|
||||
}
|
||||
|
||||
func (dict Dict) String() string {
|
||||
return (*dict.format()).String()
|
||||
}
|
||||
|
||||
func (dict Dict) format() *bytes.Buffer {
|
||||
var buffer bytes.Buffer
|
||||
for section, vals := range dict {
|
||||
if section != "" {
|
||||
buffer.WriteString(fmt.Sprintf("[%s]\n", section))
|
||||
}
|
||||
for key, val := range vals {
|
||||
buffer.WriteString(fmt.Sprintf("%s = %s\n", key, val))
|
||||
}
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
return &buffer
|
||||
}
|
||||
|
||||
func newError(message string) (e error) {
|
||||
return Error(message)
|
||||
}
|
169
Godeps/_workspace/src/github.com/rakyll/goini/ini_test.go
generated
vendored
169
Godeps/_workspace/src/github.com/rakyll/goini/ini_test.go
generated
vendored
@ -1,169 +0,0 @@
|
||||
package ini
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
exampleStr = `key1 = true
|
||||
|
||||
[section1]
|
||||
key1 = value2
|
||||
key2 = 5
|
||||
key3 = 1.3
|
||||
|
||||
[section2]
|
||||
key1 = 5
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
var (
|
||||
dict Dict
|
||||
err error
|
||||
)
|
||||
|
||||
func init() {
|
||||
dict, err = Load("example.ini")
|
||||
}
|
||||
|
||||
func TestLoad(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("Example: load error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
d, err := Load("empty.ini")
|
||||
if err != nil {
|
||||
t.Error("Example: load error:", err)
|
||||
}
|
||||
d.SetString("", "key", "value")
|
||||
tempFile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Error("Write: Couldn't create temp file.", err)
|
||||
}
|
||||
err = Write(tempFile.Name(), &d)
|
||||
if err != nil {
|
||||
t.Error("Write: Couldn't write to temp config file.", err)
|
||||
}
|
||||
contents, err := ioutil.ReadFile(tempFile.Name())
|
||||
if err != nil {
|
||||
t.Error("Write: Couldn't read from the temp config file.", err)
|
||||
}
|
||||
if string(contents) != "key = value\n\n" {
|
||||
t.Error("Write: Contents of the config file doesn't match the expected.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBool(t *testing.T) {
|
||||
b, found := dict.GetBool("pizza", "ham")
|
||||
if !found || !b {
|
||||
t.Error("Example: parse error for key ham of section pizza.")
|
||||
}
|
||||
b, found = dict.GetBool("pizza", "mushrooms")
|
||||
if !found || !b {
|
||||
t.Error("Example: parse error for key mushrooms of section pizza.")
|
||||
}
|
||||
b, found = dict.GetBool("pizza", "capres")
|
||||
if !found || b {
|
||||
t.Error("Example: parse error for key capres of section pizza.")
|
||||
}
|
||||
b, found = dict.GetBool("pizza", "cheese")
|
||||
if !found || b {
|
||||
t.Error("Example: parse error for key cheese of section pizza.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStringIntAndDouble(t *testing.T) {
|
||||
str, found := dict.GetString("wine", "grape")
|
||||
if !found || str != "Cabernet Sauvignon" {
|
||||
t.Error("Example: parse error for key grape of section wine.")
|
||||
}
|
||||
i, found := dict.GetInt("wine", "year")
|
||||
if !found || i != 1989 {
|
||||
t.Error("Example: parse error for key year of section wine.")
|
||||
}
|
||||
str, found = dict.GetString("wine", "country")
|
||||
if !found || str != "Spain" {
|
||||
t.Error("Example: parse error for key grape of section wine.")
|
||||
}
|
||||
d, found := dict.GetDouble("wine", "alcohol")
|
||||
if !found || d != 12.5 {
|
||||
t.Error("Example: parse error for key grape of section wine.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetBoolAndStringAndIntAndDouble(t *testing.T) {
|
||||
dict.SetBool("pizza", "ham", false)
|
||||
b, found := dict.GetBool("pizza", "ham")
|
||||
if !found || b {
|
||||
t.Error("Example: bool set error for key ham of section pizza.")
|
||||
}
|
||||
dict.SetString("pizza", "ham", "no")
|
||||
n, found := dict.GetString("pizza", "ham")
|
||||
if !found || n != "no" {
|
||||
t.Error("Example: string set error for key ham of section pizza.")
|
||||
}
|
||||
dict.SetInt("wine", "year", 1978)
|
||||
i, found := dict.GetInt("wine", "year")
|
||||
if !found || i != 1978 {
|
||||
t.Error("Example: int set error for key year of section wine.")
|
||||
}
|
||||
dict.SetDouble("wine", "not-exists", 5.6)
|
||||
d, found := dict.GetDouble("wine", "not-exists")
|
||||
if !found || d != 5.6 {
|
||||
t.Error("Example: float set error for not existing key for wine.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
d, err := Load("empty.ini")
|
||||
if err != nil {
|
||||
t.Error("Example: load error:", err)
|
||||
}
|
||||
d.SetString("pizza", "ham", "yes")
|
||||
d.Delete("pizza", "ham")
|
||||
_, found := d.GetString("pizza", "ham")
|
||||
if found {
|
||||
t.Error("Example: delete error for key ham of section pizza.")
|
||||
}
|
||||
if len(d.GetSections()) > 1 {
|
||||
t.Error("Only a single section should exist after deletion.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNotExist(t *testing.T) {
|
||||
_, found := dict.GetString("not", "exist")
|
||||
if found {
|
||||
t.Error("There is no key exist of section not.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSections(t *testing.T) {
|
||||
sections := dict.GetSections()
|
||||
if len(sections) != 3 {
|
||||
t.Error("The number of sections is wrong:", len(sections))
|
||||
}
|
||||
for _, section := range sections {
|
||||
if section != "" && section != "pizza" && section != "wine" {
|
||||
t.Errorf("Section '%s' should not be exist.", section)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
d, err := Load("empty.ini")
|
||||
if err != nil {
|
||||
t.Error("Example: load error:", err)
|
||||
}
|
||||
d.SetBool("", "key1", true)
|
||||
d.SetString("section1", "key1", "value2")
|
||||
d.SetInt("section1", "key2", 5)
|
||||
d.SetDouble("section1", "key3", 1.3)
|
||||
d.SetDouble("section2", "key1", 5.0)
|
||||
if d.String() != exampleStr {
|
||||
t.Errorf("Dict cannot be stringified as expected.")
|
||||
}
|
||||
}
|
27
Godeps/_workspace/src/github.com/shiena/ansicolor/.gitignore
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/shiena/ansicolor/.gitignore
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# Created by http://www.gitignore.io
|
||||
|
||||
### Go ###
|
||||
# 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
|
||||
*.test
|
||||
|
21
Godeps/_workspace/src/github.com/shiena/ansicolor/LICENSE
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/shiena/ansicolor/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) [2014] [shiena]
|
||||
|
||||
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.
|
100
Godeps/_workspace/src/github.com/shiena/ansicolor/README.md
generated
vendored
Normal file
100
Godeps/_workspace/src/github.com/shiena/ansicolor/README.md
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
[](https://godoc.org/github.com/shiena/ansicolor)
|
||||
|
||||
# ansicolor
|
||||
|
||||
Ansicolor library provides color console in Windows as ANSICON for Golang.
|
||||
|
||||
## Features
|
||||
|
||||
|Escape sequence|Text attributes|
|
||||
|---------------|----|
|
||||
|\x1b[0m|All attributes off(color at startup)|
|
||||
|\x1b[1m|Bold on(enable foreground intensity)|
|
||||
|\x1b[4m|Underline on|
|
||||
|\x1b[5m|Blink on(enable background intensity)|
|
||||
|\x1b[21m|Bold off(disable foreground intensity)|
|
||||
|\x1b[24m|Underline off|
|
||||
|\x1b[25m|Blink off(disable background intensity)|
|
||||
|
||||
|Escape sequence|Foreground colors|
|
||||
|---------------|----|
|
||||
|\x1b[30m|Black|
|
||||
|\x1b[31m|Red|
|
||||
|\x1b[32m|Green|
|
||||
|\x1b[33m|Yellow|
|
||||
|\x1b[34m|Blue|
|
||||
|\x1b[35m|Magenta|
|
||||
|\x1b[36m|Cyan|
|
||||
|\x1b[37m|White|
|
||||
|\x1b[39m|Default(foreground color at startup)|
|
||||
|\x1b[90m|Light Gray|
|
||||
|\x1b[91m|Light Red|
|
||||
|\x1b[92m|Light Green|
|
||||
|\x1b[93m|Light Yellow|
|
||||
|\x1b[94m|Light Blue|
|
||||
|\x1b[95m|Light Magenta|
|
||||
|\x1b[96m|Light Cyan|
|
||||
|\x1b[97m|Light White|
|
||||
|
||||
|Escape sequence|Background colors|
|
||||
|---------------|----|
|
||||
|\x1b[40m|Black|
|
||||
|\x1b[41m|Red|
|
||||
|\x1b[42m|Green|
|
||||
|\x1b[43m|Yellow|
|
||||
|\x1b[44m|Blue|
|
||||
|\x1b[45m|Magenta|
|
||||
|\x1b[46m|Cyan|
|
||||
|\x1b[47m|White|
|
||||
|\x1b[49m|Default(background color at startup)|
|
||||
|\x1b[100m|Light Gray|
|
||||
|\x1b[101m|Light Red|
|
||||
|\x1b[102m|Light Green|
|
||||
|\x1b[103m|Light Yellow|
|
||||
|\x1b[104m|Light Blue|
|
||||
|\x1b[105m|Light Magenta|
|
||||
|\x1b[106m|Light Cyan|
|
||||
|\x1b[107m|Light White|
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
text := "%sforeground %sbold%s %sbackground%s\n"
|
||||
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## See also:
|
||||
|
||||
- https://github.com/daviddengcn/go-colortext
|
||||
- https://github.com/adoxa/ansicon
|
||||
- https://github.com/aslakhellesoy/wac
|
||||
- https://github.com/wsxiaoys/terminal
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
|
20
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor.go
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ansicolor provides color console in Windows as ANSICON.
|
||||
package ansicolor
|
||||
|
||||
import "io"
|
||||
|
||||
// NewAnsiColorWriter creates and initializes a new ansiColorWriter
|
||||
// using io.Writer w as its initial contents.
|
||||
// In the console of Windows, which change the foreground and background
|
||||
// colors of the text by the escape sequence.
|
||||
// In the console of other systems, which writes to w all text.
|
||||
func NewAnsiColorWriter(w io.Writer) io.Writer {
|
||||
if _, ok := w.(*ansiColorWriter); !ok {
|
||||
return &ansiColorWriter{w: w}
|
||||
}
|
||||
return w
|
||||
}
|
27
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor/main.go
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor/main.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
The ansicolor command colors a console text by ANSI escape sequence like wac.
|
||||
|
||||
$ go get github.com/shiena/ansicolor/ansicolor
|
||||
|
||||
See also:
|
||||
https://github.com/aslakhellesoy/wac
|
||||
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
io.Copy(w, os.Stdin)
|
||||
}
|
17
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_ansi.go
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_ansi.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package ansicolor
|
||||
|
||||
import "io"
|
||||
|
||||
type ansiColorWriter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||
return cw.w.Write(p)
|
||||
}
|
25
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_test.go
generated
vendored
Normal file
25
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_test.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package ansicolor_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func TestNewAnsiColor1(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
if w == inner {
|
||||
t.Errorf("Get %#v, want %#v", w, inner)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAnsiColor2(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w1 := ansicolor.NewAnsiColorWriter(inner)
|
||||
w2 := ansicolor.NewAnsiColorWriter(w1)
|
||||
if w1 != w2 {
|
||||
t.Errorf("Get %#v, want %#v", w1, w2)
|
||||
}
|
||||
}
|
351
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows.go
generated
vendored
Normal file
351
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows.go
generated
vendored
Normal file
@ -0,0 +1,351 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package ansicolor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type csiState int
|
||||
|
||||
const (
|
||||
outsideCsiCode csiState = iota
|
||||
firstCsiCode
|
||||
secondCsiCode
|
||||
)
|
||||
|
||||
type ansiColorWriter struct {
|
||||
w io.Writer
|
||||
state csiState
|
||||
paramBuf bytes.Buffer
|
||||
}
|
||||
|
||||
const (
|
||||
firstCsiChar byte = '\x1b'
|
||||
secondeCsiChar byte = '['
|
||||
separatorChar byte = ';'
|
||||
sgrCode byte = 'm'
|
||||
)
|
||||
|
||||
const (
|
||||
foregroundBlue = uint16(0x0001)
|
||||
foregroundGreen = uint16(0x0002)
|
||||
foregroundRed = uint16(0x0004)
|
||||
foregroundIntensity = uint16(0x0008)
|
||||
backgroundBlue = uint16(0x0010)
|
||||
backgroundGreen = uint16(0x0020)
|
||||
backgroundRed = uint16(0x0040)
|
||||
backgroundIntensity = uint16(0x0080)
|
||||
underscore = uint16(0x8000)
|
||||
|
||||
foregroundMask = foregroundBlue | foregroundGreen | foregroundRed | foregroundIntensity
|
||||
backgroundMask = backgroundBlue | backgroundGreen | backgroundRed | backgroundIntensity
|
||||
)
|
||||
|
||||
const (
|
||||
ansiReset = "0"
|
||||
ansiIntensityOn = "1"
|
||||
ansiIntensityOff = "21"
|
||||
ansiUnderlineOn = "4"
|
||||
ansiUnderlineOff = "24"
|
||||
ansiBlinkOn = "5"
|
||||
ansiBlinkOff = "25"
|
||||
|
||||
ansiForegroundBlack = "30"
|
||||
ansiForegroundRed = "31"
|
||||
ansiForegroundGreen = "32"
|
||||
ansiForegroundYellow = "33"
|
||||
ansiForegroundBlue = "34"
|
||||
ansiForegroundMagenta = "35"
|
||||
ansiForegroundCyan = "36"
|
||||
ansiForegroundWhite = "37"
|
||||
ansiForegroundDefault = "39"
|
||||
|
||||
ansiBackgroundBlack = "40"
|
||||
ansiBackgroundRed = "41"
|
||||
ansiBackgroundGreen = "42"
|
||||
ansiBackgroundYellow = "43"
|
||||
ansiBackgroundBlue = "44"
|
||||
ansiBackgroundMagenta = "45"
|
||||
ansiBackgroundCyan = "46"
|
||||
ansiBackgroundWhite = "47"
|
||||
ansiBackgroundDefault = "49"
|
||||
|
||||
ansiLightForegroundGray = "90"
|
||||
ansiLightForegroundRed = "91"
|
||||
ansiLightForegroundGreen = "92"
|
||||
ansiLightForegroundYellow = "93"
|
||||
ansiLightForegroundBlue = "94"
|
||||
ansiLightForegroundMagenta = "95"
|
||||
ansiLightForegroundCyan = "96"
|
||||
ansiLightForegroundWhite = "97"
|
||||
|
||||
ansiLightBackgroundGray = "100"
|
||||
ansiLightBackgroundRed = "101"
|
||||
ansiLightBackgroundGreen = "102"
|
||||
ansiLightBackgroundYellow = "103"
|
||||
ansiLightBackgroundBlue = "104"
|
||||
ansiLightBackgroundMagenta = "105"
|
||||
ansiLightBackgroundCyan = "106"
|
||||
ansiLightBackgroundWhite = "107"
|
||||
)
|
||||
|
||||
type drawType int
|
||||
|
||||
const (
|
||||
foreground drawType = iota
|
||||
background
|
||||
)
|
||||
|
||||
type winColor struct {
|
||||
code uint16
|
||||
drawType drawType
|
||||
}
|
||||
|
||||
var colorMap = map[string]winColor{
|
||||
ansiForegroundBlack: {0, foreground},
|
||||
ansiForegroundRed: {foregroundRed, foreground},
|
||||
ansiForegroundGreen: {foregroundGreen, foreground},
|
||||
ansiForegroundYellow: {foregroundRed | foregroundGreen, foreground},
|
||||
ansiForegroundBlue: {foregroundBlue, foreground},
|
||||
ansiForegroundMagenta: {foregroundRed | foregroundBlue, foreground},
|
||||
ansiForegroundCyan: {foregroundGreen | foregroundBlue, foreground},
|
||||
ansiForegroundWhite: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||
ansiForegroundDefault: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||
|
||||
ansiBackgroundBlack: {0, background},
|
||||
ansiBackgroundRed: {backgroundRed, background},
|
||||
ansiBackgroundGreen: {backgroundGreen, background},
|
||||
ansiBackgroundYellow: {backgroundRed | backgroundGreen, background},
|
||||
ansiBackgroundBlue: {backgroundBlue, background},
|
||||
ansiBackgroundMagenta: {backgroundRed | backgroundBlue, background},
|
||||
ansiBackgroundCyan: {backgroundGreen | backgroundBlue, background},
|
||||
ansiBackgroundWhite: {backgroundRed | backgroundGreen | backgroundBlue, background},
|
||||
ansiBackgroundDefault: {0, background},
|
||||
|
||||
ansiLightForegroundGray: {foregroundIntensity, foreground},
|
||||
ansiLightForegroundRed: {foregroundIntensity | foregroundRed, foreground},
|
||||
ansiLightForegroundGreen: {foregroundIntensity | foregroundGreen, foreground},
|
||||
ansiLightForegroundYellow: {foregroundIntensity | foregroundRed | foregroundGreen, foreground},
|
||||
ansiLightForegroundBlue: {foregroundIntensity | foregroundBlue, foreground},
|
||||
ansiLightForegroundMagenta: {foregroundIntensity | foregroundRed | foregroundBlue, foreground},
|
||||
ansiLightForegroundCyan: {foregroundIntensity | foregroundGreen | foregroundBlue, foreground},
|
||||
ansiLightForegroundWhite: {foregroundIntensity | foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||
|
||||
ansiLightBackgroundGray: {backgroundIntensity, background},
|
||||
ansiLightBackgroundRed: {backgroundIntensity | backgroundRed, background},
|
||||
ansiLightBackgroundGreen: {backgroundIntensity | backgroundGreen, background},
|
||||
ansiLightBackgroundYellow: {backgroundIntensity | backgroundRed | backgroundGreen, background},
|
||||
ansiLightBackgroundBlue: {backgroundIntensity | backgroundBlue, background},
|
||||
ansiLightBackgroundMagenta: {backgroundIntensity | backgroundRed | backgroundBlue, background},
|
||||
ansiLightBackgroundCyan: {backgroundIntensity | backgroundGreen | backgroundBlue, background},
|
||||
ansiLightBackgroundWhite: {backgroundIntensity | backgroundRed | backgroundGreen | backgroundBlue, background},
|
||||
}
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
defaultAttr *textAttributes
|
||||
)
|
||||
|
||||
func init() {
|
||||
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo != nil {
|
||||
colorMap[ansiForegroundDefault] = winColor{
|
||||
screenInfo.WAttributes & (foregroundRed | foregroundGreen | foregroundBlue),
|
||||
foreground,
|
||||
}
|
||||
colorMap[ansiBackgroundDefault] = winColor{
|
||||
screenInfo.WAttributes & (backgroundRed | backgroundGreen | backgroundBlue),
|
||||
background,
|
||||
}
|
||||
defaultAttr = convertTextAttr(screenInfo.WAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
type coord struct {
|
||||
X, Y int16
|
||||
}
|
||||
|
||||
type smallRect struct {
|
||||
Left, Top, Right, Bottom int16
|
||||
}
|
||||
|
||||
type consoleScreenBufferInfo struct {
|
||||
DwSize coord
|
||||
DwCursorPosition coord
|
||||
WAttributes uint16
|
||||
SrWindow smallRect
|
||||
DwMaximumWindowSize coord
|
||||
}
|
||||
|
||||
func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
|
||||
var csbi consoleScreenBufferInfo
|
||||
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
|
||||
hConsoleOutput,
|
||||
uintptr(unsafe.Pointer(&csbi)))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return &csbi
|
||||
}
|
||||
|
||||
func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
|
||||
ret, _, _ := procSetConsoleTextAttribute.Call(
|
||||
hConsoleOutput,
|
||||
uintptr(wAttributes))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
type textAttributes struct {
|
||||
foregroundColor uint16
|
||||
backgroundColor uint16
|
||||
foregroundIntensity uint16
|
||||
backgroundIntensity uint16
|
||||
underscore uint16
|
||||
otherAttributes uint16
|
||||
}
|
||||
|
||||
func convertTextAttr(winAttr uint16) *textAttributes {
|
||||
fgColor := winAttr & (foregroundRed | foregroundGreen | foregroundBlue)
|
||||
bgColor := winAttr & (backgroundRed | backgroundGreen | backgroundBlue)
|
||||
fgIntensity := winAttr & foregroundIntensity
|
||||
bgIntensity := winAttr & backgroundIntensity
|
||||
underline := winAttr & underscore
|
||||
otherAttributes := winAttr &^ (foregroundMask | backgroundMask | underscore)
|
||||
return &textAttributes{fgColor, bgColor, fgIntensity, bgIntensity, underline, otherAttributes}
|
||||
}
|
||||
|
||||
func convertWinAttr(textAttr *textAttributes) uint16 {
|
||||
var winAttr uint16 = 0
|
||||
winAttr |= textAttr.foregroundColor
|
||||
winAttr |= textAttr.backgroundColor
|
||||
winAttr |= textAttr.foregroundIntensity
|
||||
winAttr |= textAttr.backgroundIntensity
|
||||
winAttr |= textAttr.underscore
|
||||
winAttr |= textAttr.otherAttributes
|
||||
return winAttr
|
||||
}
|
||||
|
||||
func changeColor(param []byte) {
|
||||
if defaultAttr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo == nil {
|
||||
return
|
||||
}
|
||||
|
||||
winAttr := convertTextAttr(screenInfo.WAttributes)
|
||||
strParam := string(param)
|
||||
if len(strParam) <= 0 {
|
||||
strParam = "0"
|
||||
}
|
||||
csiParam := strings.Split(strParam, string(separatorChar))
|
||||
for _, p := range csiParam {
|
||||
c, ok := colorMap[p]
|
||||
switch {
|
||||
case !ok:
|
||||
switch p {
|
||||
case ansiReset:
|
||||
winAttr.foregroundColor = defaultAttr.foregroundColor
|
||||
winAttr.backgroundColor = defaultAttr.backgroundColor
|
||||
winAttr.foregroundIntensity = defaultAttr.foregroundIntensity
|
||||
winAttr.backgroundIntensity = defaultAttr.backgroundIntensity
|
||||
winAttr.underscore = 0
|
||||
winAttr.otherAttributes = 0
|
||||
case ansiIntensityOn:
|
||||
winAttr.foregroundIntensity = foregroundIntensity
|
||||
case ansiIntensityOff:
|
||||
winAttr.foregroundIntensity = 0
|
||||
case ansiUnderlineOn:
|
||||
winAttr.underscore = underscore
|
||||
case ansiUnderlineOff:
|
||||
winAttr.underscore = 0
|
||||
case ansiBlinkOn:
|
||||
winAttr.backgroundIntensity = backgroundIntensity
|
||||
case ansiBlinkOff:
|
||||
winAttr.backgroundIntensity = 0
|
||||
default:
|
||||
// unknown code
|
||||
}
|
||||
case c.drawType == foreground:
|
||||
winAttr.foregroundColor = c.code
|
||||
case c.drawType == background:
|
||||
winAttr.backgroundColor = c.code
|
||||
}
|
||||
}
|
||||
winTextAttribute := convertWinAttr(winAttr)
|
||||
setConsoleTextAttribute(uintptr(syscall.Stdout), winTextAttribute)
|
||||
}
|
||||
|
||||
func parseEscapeSequence(command byte, param []byte) {
|
||||
switch command {
|
||||
case sgrCode:
|
||||
changeColor(param)
|
||||
}
|
||||
}
|
||||
|
||||
func isParameterChar(b byte) bool {
|
||||
return ('0' <= b && b <= '9') || b == separatorChar
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||
r, nw, nc, first, last := 0, 0, 0, 0, 0
|
||||
var err error
|
||||
for i, ch := range p {
|
||||
switch cw.state {
|
||||
case outsideCsiCode:
|
||||
if ch == firstCsiChar {
|
||||
nc++
|
||||
cw.state = firstCsiCode
|
||||
}
|
||||
case firstCsiCode:
|
||||
switch ch {
|
||||
case firstCsiChar:
|
||||
nc++
|
||||
break
|
||||
case secondeCsiChar:
|
||||
nc++
|
||||
cw.state = secondCsiCode
|
||||
last = i - 1
|
||||
default:
|
||||
cw.state = outsideCsiCode
|
||||
}
|
||||
case secondCsiCode:
|
||||
nc++
|
||||
if isParameterChar(ch) {
|
||||
cw.paramBuf.WriteByte(ch)
|
||||
} else {
|
||||
nw, err = cw.w.Write(p[first:last])
|
||||
r += nw
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
first = i + 1
|
||||
param := cw.paramBuf.Bytes()
|
||||
cw.paramBuf.Reset()
|
||||
parseEscapeSequence(ch, param)
|
||||
cw.state = outsideCsiCode
|
||||
}
|
||||
default:
|
||||
cw.state = outsideCsiCode
|
||||
}
|
||||
}
|
||||
|
||||
if cw.state == outsideCsiCode {
|
||||
nw, err = cw.w.Write(p[first:len(p)])
|
||||
}
|
||||
|
||||
return r + nw + nc, err
|
||||
}
|
236
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows_test.go
generated
vendored
Normal file
236
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows_test.go
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package ansicolor_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
. "github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func TestWritePlanText(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
expected := "plain text"
|
||||
fmt.Fprintf(w, expected)
|
||||
actual := inner.String()
|
||||
if actual != expected {
|
||||
t.Errorf("Get %s, want %s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteParseText(t *testing.T) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
|
||||
inputTail := "\x1b[0mtail text"
|
||||
expectedTail := "tail text"
|
||||
fmt.Fprintf(w, inputTail)
|
||||
actualTail := inner.String()
|
||||
inner.Reset()
|
||||
if actualTail != expectedTail {
|
||||
t.Errorf("Get %s, want %s", actualTail, expectedTail)
|
||||
}
|
||||
|
||||
inputHead := "head text\x1b[0m"
|
||||
expectedHead := "head text"
|
||||
fmt.Fprintf(w, inputHead)
|
||||
actualHead := inner.String()
|
||||
inner.Reset()
|
||||
if actualHead != expectedHead {
|
||||
t.Errorf("Get %s, want %s", actualHead, expectedHead)
|
||||
}
|
||||
|
||||
inputBothEnds := "both ends \x1b[0m text"
|
||||
expectedBothEnds := "both ends text"
|
||||
fmt.Fprintf(w, inputBothEnds)
|
||||
actualBothEnds := inner.String()
|
||||
inner.Reset()
|
||||
if actualBothEnds != expectedBothEnds {
|
||||
t.Errorf("Get %s, want %s", actualBothEnds, expectedBothEnds)
|
||||
}
|
||||
|
||||
inputManyEsc := "\x1b\x1b\x1b\x1b[0m many esc"
|
||||
expectedManyEsc := "\x1b\x1b\x1b many esc"
|
||||
fmt.Fprintf(w, inputManyEsc)
|
||||
actualManyEsc := inner.String()
|
||||
inner.Reset()
|
||||
if actualManyEsc != expectedManyEsc {
|
||||
t.Errorf("Get %s, want %s", actualManyEsc, expectedManyEsc)
|
||||
}
|
||||
|
||||
expectedSplit := "split text"
|
||||
for _, ch := range "split \x1b[0m text" {
|
||||
fmt.Fprintf(w, string(ch))
|
||||
}
|
||||
actualSplit := inner.String()
|
||||
inner.Reset()
|
||||
if actualSplit != expectedSplit {
|
||||
t.Errorf("Get %s, want %s", actualSplit, expectedSplit)
|
||||
}
|
||||
}
|
||||
|
||||
type screenNotFoundError struct {
|
||||
error
|
||||
}
|
||||
|
||||
func writeAnsiColor(expectedText, colorCode string) (actualText string, actualAttributes uint16, err error) {
|
||||
inner := bytes.NewBufferString("")
|
||||
w := ansicolor.NewAnsiColorWriter(inner)
|
||||
fmt.Fprintf(w, "\x1b[%sm%s", colorCode, expectedText)
|
||||
|
||||
actualText = inner.String()
|
||||
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo != nil {
|
||||
actualAttributes = screenInfo.WAttributes
|
||||
} else {
|
||||
err = &screenNotFoundError{}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type testParam struct {
|
||||
text string
|
||||
attributes uint16
|
||||
ansiColor string
|
||||
}
|
||||
|
||||
func TestWriteAnsiColorText(t *testing.T) {
|
||||
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||
if screenInfo == nil {
|
||||
t.Fatal("Could not get ConsoleScreenBufferInfo")
|
||||
}
|
||||
defer ChangeColor(screenInfo.WAttributes)
|
||||
defaultFgColor := screenInfo.WAttributes & uint16(0x0007)
|
||||
defaultBgColor := screenInfo.WAttributes & uint16(0x0070)
|
||||
defaultFgIntensity := screenInfo.WAttributes & uint16(0x0008)
|
||||
defaultBgIntensity := screenInfo.WAttributes & uint16(0x0080)
|
||||
|
||||
fgParam := []testParam{
|
||||
{"foreground black ", uint16(0x0000 | 0x0000), "30"},
|
||||
{"foreground red ", uint16(0x0004 | 0x0000), "31"},
|
||||
{"foreground green ", uint16(0x0002 | 0x0000), "32"},
|
||||
{"foreground yellow ", uint16(0x0006 | 0x0000), "33"},
|
||||
{"foreground blue ", uint16(0x0001 | 0x0000), "34"},
|
||||
{"foreground magenta", uint16(0x0005 | 0x0000), "35"},
|
||||
{"foreground cyan ", uint16(0x0003 | 0x0000), "36"},
|
||||
{"foreground white ", uint16(0x0007 | 0x0000), "37"},
|
||||
{"foreground default", defaultFgColor | 0x0000, "39"},
|
||||
{"foreground light gray ", uint16(0x0000 | 0x0008 | 0x0000), "90"},
|
||||
{"foreground light red ", uint16(0x0004 | 0x0008 | 0x0000), "91"},
|
||||
{"foreground light green ", uint16(0x0002 | 0x0008 | 0x0000), "92"},
|
||||
{"foreground light yellow ", uint16(0x0006 | 0x0008 | 0x0000), "93"},
|
||||
{"foreground light blue ", uint16(0x0001 | 0x0008 | 0x0000), "94"},
|
||||
{"foreground light magenta", uint16(0x0005 | 0x0008 | 0x0000), "95"},
|
||||
{"foreground light cyan ", uint16(0x0003 | 0x0008 | 0x0000), "96"},
|
||||
{"foreground light white ", uint16(0x0007 | 0x0008 | 0x0000), "97"},
|
||||
}
|
||||
|
||||
bgParam := []testParam{
|
||||
{"background black ", uint16(0x0007 | 0x0000), "40"},
|
||||
{"background red ", uint16(0x0007 | 0x0040), "41"},
|
||||
{"background green ", uint16(0x0007 | 0x0020), "42"},
|
||||
{"background yellow ", uint16(0x0007 | 0x0060), "43"},
|
||||
{"background blue ", uint16(0x0007 | 0x0010), "44"},
|
||||
{"background magenta", uint16(0x0007 | 0x0050), "45"},
|
||||
{"background cyan ", uint16(0x0007 | 0x0030), "46"},
|
||||
{"background white ", uint16(0x0007 | 0x0070), "47"},
|
||||
{"background default", uint16(0x0007) | defaultBgColor, "49"},
|
||||
{"background light gray ", uint16(0x0007 | 0x0000 | 0x0080), "100"},
|
||||
{"background light red ", uint16(0x0007 | 0x0040 | 0x0080), "101"},
|
||||
{"background light green ", uint16(0x0007 | 0x0020 | 0x0080), "102"},
|
||||
{"background light yellow ", uint16(0x0007 | 0x0060 | 0x0080), "103"},
|
||||
{"background light blue ", uint16(0x0007 | 0x0010 | 0x0080), "104"},
|
||||
{"background light magenta", uint16(0x0007 | 0x0050 | 0x0080), "105"},
|
||||
{"background light cyan ", uint16(0x0007 | 0x0030 | 0x0080), "106"},
|
||||
{"background light white ", uint16(0x0007 | 0x0070 | 0x0080), "107"},
|
||||
}
|
||||
|
||||
resetParam := []testParam{
|
||||
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, "0"},
|
||||
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, ""},
|
||||
}
|
||||
|
||||
boldParam := []testParam{
|
||||
{"bold on", uint16(0x0007 | 0x0008), "1"},
|
||||
{"bold off", uint16(0x0007), "21"},
|
||||
}
|
||||
|
||||
underscoreParam := []testParam{
|
||||
{"underscore on", uint16(0x0007 | 0x8000), "4"},
|
||||
{"underscore off", uint16(0x0007), "24"},
|
||||
}
|
||||
|
||||
blinkParam := []testParam{
|
||||
{"blink on", uint16(0x0007 | 0x0080), "5"},
|
||||
{"blink off", uint16(0x0007), "25"},
|
||||
}
|
||||
|
||||
mixedParam := []testParam{
|
||||
{"both black, bold, underline, blink", uint16(0x0000 | 0x0000 | 0x0008 | 0x8000 | 0x0080), "30;40;1;4;5"},
|
||||
{"both red, bold, underline, blink", uint16(0x0004 | 0x0040 | 0x0008 | 0x8000 | 0x0080), "31;41;1;4;5"},
|
||||
{"both green, bold, underline, blink", uint16(0x0002 | 0x0020 | 0x0008 | 0x8000 | 0x0080), "32;42;1;4;5"},
|
||||
{"both yellow, bold, underline, blink", uint16(0x0006 | 0x0060 | 0x0008 | 0x8000 | 0x0080), "33;43;1;4;5"},
|
||||
{"both blue, bold, underline, blink", uint16(0x0001 | 0x0010 | 0x0008 | 0x8000 | 0x0080), "34;44;1;4;5"},
|
||||
{"both magenta, bold, underline, blink", uint16(0x0005 | 0x0050 | 0x0008 | 0x8000 | 0x0080), "35;45;1;4;5"},
|
||||
{"both cyan, bold, underline, blink", uint16(0x0003 | 0x0030 | 0x0008 | 0x8000 | 0x0080), "36;46;1;4;5"},
|
||||
{"both white, bold, underline, blink", uint16(0x0007 | 0x0070 | 0x0008 | 0x8000 | 0x0080), "37;47;1;4;5"},
|
||||
{"both default, bold, underline, blink", uint16(defaultFgColor | defaultBgColor | 0x0008 | 0x8000 | 0x0080), "39;49;1;4;5"},
|
||||
}
|
||||
|
||||
assertTextAttribute := func(expectedText string, expectedAttributes uint16, ansiColor string) {
|
||||
actualText, actualAttributes, err := writeAnsiColor(expectedText, ansiColor)
|
||||
if actualText != expectedText {
|
||||
t.Errorf("Get %s, want %s", actualText, expectedText)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal("Could not get ConsoleScreenBufferInfo")
|
||||
}
|
||||
if actualAttributes != expectedAttributes {
|
||||
t.Errorf("Text: %s, Get 0x%04x, want 0x%04x", expectedText, actualAttributes, expectedAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range fgParam {
|
||||
ResetColor()
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
for _, v := range bgParam {
|
||||
ChangeColor(uint16(0x0070 | 0x0007))
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
for _, v := range resetParam {
|
||||
ChangeColor(uint16(0x0000 | 0x0070 | 0x0008))
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
ResetColor()
|
||||
for _, v := range boldParam {
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
ResetColor()
|
||||
for _, v := range underscoreParam {
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
ResetColor()
|
||||
for _, v := range blinkParam {
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
|
||||
for _, v := range mixedParam {
|
||||
ResetColor()
|
||||
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||
}
|
||||
}
|
24
Godeps/_workspace/src/github.com/shiena/ansicolor/example_test.go
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/shiena/ansicolor/example_test.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ansicolor_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/shiena/ansicolor"
|
||||
)
|
||||
|
||||
func ExampleNewAnsiColorWriter() {
|
||||
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||
text := "%sforeground %sbold%s %sbackground%s\n"
|
||||
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
|
||||
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
|
||||
}
|
19
Godeps/_workspace/src/github.com/shiena/ansicolor/export_test.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/shiena/ansicolor/export_test.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2014 shiena Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package ansicolor
|
||||
|
||||
import "syscall"
|
||||
|
||||
var GetConsoleScreenBufferInfo = getConsoleScreenBufferInfo
|
||||
|
||||
func ChangeColor(color uint16) {
|
||||
setConsoleTextAttribute(uintptr(syscall.Stdout), color)
|
||||
}
|
||||
|
||||
func ResetColor() {
|
||||
ChangeColor(uint16(0x0007))
|
||||
}
|
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque.go
generated
vendored
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque.go
generated
vendored
@ -1,19 +1,10 @@
|
||||
// CookieJar - A contestant's algorithm toolbox
|
||||
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
|
||||
//
|
||||
// CookieJar is dual licensed: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
|
||||
// and conditions contained in a signed written agreement between you and the
|
||||
// author(s).
|
||||
// CookieJar is dual licensed: use of this source code is governed by a BSD
|
||||
// license that can be found in the LICENSE file. Alternatively, the CookieJar
|
||||
// toolbox may be used in accordance with the terms and conditions contained
|
||||
// in a signed written agreement between you and the author(s).
|
||||
|
||||
// Package prque implements a priority queue data structure supporting arbitrary
|
||||
// value types and float priorities.
|
||||
|
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque_test.go
generated
vendored
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/prque_test.go
generated
vendored
@ -1,19 +1,10 @@
|
||||
// CookieJar - A contestant's algorithm toolbox
|
||||
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
|
||||
//
|
||||
// CookieJar is dual licensed: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
|
||||
// and conditions contained in a signed written agreement between you and the
|
||||
// author(s).
|
||||
// CookieJar is dual licensed: use of this source code is governed by a BSD
|
||||
// license that can be found in the LICENSE file. Alternatively, the CookieJar
|
||||
// toolbox may be used in accordance with the terms and conditions contained
|
||||
// in a signed written agreement between you and the author(s).
|
||||
|
||||
package prque
|
||||
|
||||
|
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack.go
generated
vendored
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack.go
generated
vendored
@ -1,19 +1,10 @@
|
||||
// CookieJar - A contestant's algorithm toolbox
|
||||
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
|
||||
//
|
||||
// CookieJar is dual licensed: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
|
||||
// and conditions contained in a signed written agreement between you and the
|
||||
// author(s).
|
||||
// CookieJar is dual licensed: use of this source code is governed by a BSD
|
||||
// license that can be found in the LICENSE file. Alternatively, the CookieJar
|
||||
// toolbox may be used in accordance with the terms and conditions contained
|
||||
// in a signed written agreement between you and the author(s).
|
||||
|
||||
package prque
|
||||
|
||||
|
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack_test.go
generated
vendored
17
Godeps/_workspace/src/gopkg.in/karalabe/cookiejar.v2/collections/prque/sstack_test.go
generated
vendored
@ -1,19 +1,10 @@
|
||||
// CookieJar - A contestant's algorithm toolbox
|
||||
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
|
||||
//
|
||||
// CookieJar is dual licensed: you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
|
||||
// and conditions contained in a signed written agreement between you and the
|
||||
// author(s).
|
||||
// CookieJar is dual licensed: use of this source code is governed by a BSD
|
||||
// license that can be found in the LICENSE file. Alternatively, the CookieJar
|
||||
// toolbox may be used in accordance with the terms and conditions contained
|
||||
// in a signed written agreement between you and the author(s).
|
||||
|
||||
package prque
|
||||
|
||||
|
16
LICENSE
16
LICENSE
@ -1,16 +0,0 @@
|
||||
Copyright (c) 2013-2015, The go-ethereum Authors. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA
|
33
Makefile
33
Makefile
@ -2,7 +2,7 @@
|
||||
# with Go source code. If you know what GOPATH is then you probably
|
||||
# don't need to bother with make.
|
||||
|
||||
.PHONY: geth mist all test travis-test-with-coverage clean
|
||||
.PHONY: geth evm mist all test travis-test-with-coverage clean
|
||||
GOBIN = build/bin
|
||||
|
||||
geth:
|
||||
@ -10,6 +10,34 @@ geth:
|
||||
@echo "Done building."
|
||||
@echo "Run \"$(GOBIN)/geth\" to launch geth."
|
||||
|
||||
geth-cross: geth-linux geth-darwin geth-windows geth-android
|
||||
@echo "Full cross compilation done:"
|
||||
@ls -l $(GOBIN)/geth-*
|
||||
|
||||
geth-linux: xgo
|
||||
build/env.sh $(GOBIN)/xgo --dest=$(GOBIN) --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 --targets=linux/* -v ./cmd/geth
|
||||
@echo "Linux cross compilation done:"
|
||||
@ls -l $(GOBIN)/geth-linux-*
|
||||
|
||||
geth-darwin: xgo
|
||||
build/env.sh $(GOBIN)/xgo --dest=$(GOBIN) --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 --targets=darwin/* -v ./cmd/geth
|
||||
@echo "Darwin cross compilation done:"
|
||||
@ls -l $(GOBIN)/geth-darwin-*
|
||||
|
||||
geth-windows: xgo
|
||||
build/env.sh $(GOBIN)/xgo --dest=$(GOBIN) --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 --targets=windows/* -v ./cmd/geth
|
||||
@echo "Windows cross compilation done:"
|
||||
@ls -l $(GOBIN)/geth-windows-*
|
||||
|
||||
geth-android: xgo
|
||||
build/env.sh $(GOBIN)/xgo --dest=$(GOBIN) --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 --targets=android-16/*,android-21/* -v ./cmd/geth
|
||||
@echo "Android cross compilation done:"
|
||||
@ls -l $(GOBIN)/geth-android-*
|
||||
|
||||
evm:
|
||||
build/env.sh $(GOROOT)/bin/go install -v $(shell build/ldflags.sh) ./cmd/evm
|
||||
@echo "Done building."
|
||||
@echo "Run \"$(GOBIN)/evm to start the evm."
|
||||
mist:
|
||||
build/env.sh go install -v $(shell build/ldflags.sh) ./cmd/mist
|
||||
@echo "Done building."
|
||||
@ -24,5 +52,8 @@ test: all
|
||||
travis-test-with-coverage: all
|
||||
build/env.sh build/test-global-coverage.sh
|
||||
|
||||
xgo:
|
||||
build/env.sh go get github.com/karalabe/xgo
|
||||
|
||||
clean:
|
||||
rm -fr build/_workspace/pkg/ Godeps/_workspace/pkg $(GOBIN)/*
|
||||
|
45
README.md
45
README.md
@ -1,19 +1,18 @@
|
||||
## Ethereum Go
|
||||
|
||||
Ethereum Go Client, by Jeffrey Wilcke (and some other people).
|
||||
Official golang implementation of the Ethereum protocol
|
||||
|
||||
| Linux | OSX | ARM | Windows | Tests
|
||||
----------|---------|-----|-----|---------|------
|
||||
develop | [](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20develop%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](https://coveralls.io/r/ethereum/go-ethereum?branch=develop)
|
||||
master | [](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20master%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](https://coveralls.io/r/ethereum/go-ethereum?branch=master)
|
||||
develop | [](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20develop%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](http://codecov.io/github/ethereum/go-ethereum?branch=develop)
|
||||
master | [](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20master%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](http://codecov.io/github/ethereum/go-ethereum?branch=master)
|
||||
|
||||
[](https://waffle.io/ethereum/go-ethereum)
|
||||
[](https://waffle.io/ethereum/go-ethereum)
|
||||
[](http://waffle.io/ethereum/go-ethereum)
|
||||
[](https://godoc.org/github.com/ethereum/go-ethereum)
|
||||
[](https://gitter.im/ethereum/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Automated development builds
|
||||
======================
|
||||
## Automated development builds
|
||||
|
||||
The following builds are build automatically by our build servers after each push to the [develop](https://github.com/ethereum/go-ethereum/tree/develop) branch.
|
||||
|
||||
@ -25,8 +24,7 @@ The following builds are build automatically by our build servers after each pus
|
||||
* [Windows 64-bit](https://build.ethdev.com/builds/Windows%20Go%20develop%20branch/Geth-Win64-latest.zip)
|
||||
* [ARM](https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2)
|
||||
|
||||
Building the source
|
||||
===================
|
||||
## Building the source
|
||||
|
||||
For prerequisites and detailed build instructions please read the
|
||||
[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum)
|
||||
@ -38,34 +36,31 @@ Once the dependencies are installed, run
|
||||
|
||||
make geth
|
||||
|
||||
Executables
|
||||
===========
|
||||
## Executables
|
||||
|
||||
Go Ethereum comes with several wrappers/executables found in
|
||||
[the `cmd` directory](https://github.com/ethereum/go-ethereum/tree/develop/cmd):
|
||||
|
||||
* `geth` Ethereum CLI (ethereum command line interface client)
|
||||
* `bootnode` runs a bootstrap node for the Discovery Protocol
|
||||
* `ethtest` test tool which runs with the [tests](https://github.com/ethereum/tests) suite:
|
||||
`/path/to/test.json > ethtest --test BlockTests --stdin`.
|
||||
* `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas
|
||||
10000 -price 0 -dump`. See `-h` for a detailed description.
|
||||
* `disasm` disassembles EVM code: `echo "6001" | disasm`
|
||||
* `rlpdump` prints RLP structures
|
||||
Command | |
|
||||
----------|---------|
|
||||
`geth` | Ethereum CLI (ethereum command line interface client) |
|
||||
`bootnode` | runs a bootstrap node for the Discovery Protocol |
|
||||
`ethtest` | test tool which runs with the [tests](https://github.com/ethereum/tests) suite: `/path/to/test.json > ethtest --test BlockTests --stdin`.
|
||||
`evm` | is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas 10000 -price 0 -dump`. See `-h` for a detailed description. |
|
||||
`disasm` | disassembles EVM code: `echo "6001" | disasm` |
|
||||
`rlpdump` | prints RLP structures |
|
||||
|
||||
Command line options
|
||||
====================
|
||||
## Command line options
|
||||
|
||||
`geth` can be configured via command line options, environment variables and config files.
|
||||
|
||||
To get the options available:
|
||||
|
||||
geth --help
|
||||
geth help
|
||||
|
||||
For further details on options, see the [wiki](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)
|
||||
|
||||
Contribution
|
||||
============
|
||||
## Contribution
|
||||
|
||||
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
||||
send a pull request. Commits who do not comply with the coding standards
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package abi
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package abi
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package abi implements the Ethereum ABI (Application Binary
|
||||
// Interface).
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package abi
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package abi
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package abi
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package implements a private key management facility.
|
||||
//
|
||||
@ -78,8 +78,8 @@ func (am *Manager) DeleteAccount(address common.Address, auth string) error {
|
||||
|
||||
func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error) {
|
||||
am.mutex.RLock()
|
||||
defer am.mutex.RUnlock()
|
||||
unlockedKey, found := am.unlocked[a.Address]
|
||||
am.mutex.RUnlock()
|
||||
if !found {
|
||||
return nil, ErrLocked
|
||||
}
|
||||
@ -87,14 +87,17 @@ func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error)
|
||||
return signature, err
|
||||
}
|
||||
|
||||
// unlock indefinitely
|
||||
// Unlock unlocks the given account indefinitely.
|
||||
func (am *Manager) Unlock(addr common.Address, keyAuth string) error {
|
||||
return am.TimedUnlock(addr, keyAuth, 0)
|
||||
}
|
||||
|
||||
// Unlock unlocks the account with the given address. The account
|
||||
// stays unlocked for the duration of timeout
|
||||
// it timeout is 0 the account is unlocked for the entire session
|
||||
// TimedUnlock unlocks the account with the given address. The account
|
||||
// stays unlocked for the duration of timeout. A timeout of 0 unlocks the account
|
||||
// until the program exits.
|
||||
//
|
||||
// If the accout is already unlocked, TimedUnlock extends or shortens
|
||||
// the active unlock timeout.
|
||||
func (am *Manager) TimedUnlock(addr common.Address, keyAuth string, timeout time.Duration) error {
|
||||
key, err := am.keyStore.GetKey(addr, keyAuth)
|
||||
if err != nil {
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package accounts
|
||||
|
||||
@ -23,9 +23,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/randentropy"
|
||||
)
|
||||
|
||||
var testSigData = make([]byte, 32)
|
||||
|
||||
func TestSign(t *testing.T) {
|
||||
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
|
||||
defer os.RemoveAll(dir)
|
||||
@ -33,26 +34,24 @@ func TestSign(t *testing.T) {
|
||||
am := NewManager(ks)
|
||||
pass := "" // not used but required by API
|
||||
a1, err := am.NewAccount(pass)
|
||||
toSign := randentropy.GetEntropyCSPRNG(32)
|
||||
am.Unlock(a1.Address, "")
|
||||
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimedUnlock(t *testing.T) {
|
||||
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePassphrase)
|
||||
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
am := NewManager(ks)
|
||||
pass := "foo"
|
||||
a1, err := am.NewAccount(pass)
|
||||
toSign := randentropy.GetEntropyCSPRNG(32)
|
||||
|
||||
// Signing without passphrase fails because account is locked
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != ErrLocked {
|
||||
t.Fatal("Signing should've failed with ErrLocked before unlocking, got ", err)
|
||||
}
|
||||
@ -63,28 +62,26 @@ func TestTimedUnlock(t *testing.T) {
|
||||
}
|
||||
|
||||
// Signing without passphrase works because account is temp unlocked
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != nil {
|
||||
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
|
||||
}
|
||||
|
||||
// Signing fails again after automatic locking
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != ErrLocked {
|
||||
t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOverrideUnlock(t *testing.T) {
|
||||
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePassphrase)
|
||||
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
am := NewManager(ks)
|
||||
pass := "foo"
|
||||
a1, err := am.NewAccount(pass)
|
||||
toSign := randentropy.GetEntropyCSPRNG(32)
|
||||
|
||||
// Unlock indefinitely
|
||||
if err = am.Unlock(a1.Address, pass); err != nil {
|
||||
@ -92,7 +89,7 @@ func TestOverrideUnlock(t *testing.T) {
|
||||
}
|
||||
|
||||
// Signing without passphrase works because account is temp unlocked
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != nil {
|
||||
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
|
||||
}
|
||||
@ -103,20 +100,46 @@ func TestOverrideUnlock(t *testing.T) {
|
||||
}
|
||||
|
||||
// Signing without passphrase still works because account is temp unlocked
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != nil {
|
||||
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
|
||||
}
|
||||
|
||||
// Signing fails again after automatic locking
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
_, err = am.Sign(a1, toSign)
|
||||
_, err = am.Sign(a1, testSigData)
|
||||
if err != ErrLocked {
|
||||
t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This test should fail under -race if signing races the expiration goroutine.
|
||||
func TestSignRace(t *testing.T) {
|
||||
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
// Create a test account.
|
||||
am := NewManager(ks)
|
||||
a1, err := am.NewAccount("")
|
||||
if err != nil {
|
||||
t.Fatal("could not create the test account", err)
|
||||
}
|
||||
|
||||
if err := am.TimedUnlock(a1.Address, "", 15*time.Millisecond); err != nil {
|
||||
t.Fatalf("could not unlock the test account", err)
|
||||
}
|
||||
end := time.Now().Add(500 * time.Millisecond)
|
||||
for time.Now().Before(end) {
|
||||
if _, err := am.Sign(a1, testSigData); err == ErrLocked {
|
||||
return
|
||||
} else if err != nil {
|
||||
t.Errorf("Sign error: %v", err)
|
||||
return
|
||||
}
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
}
|
||||
t.Errorf("Account did not lock within the timeout")
|
||||
}
|
||||
|
||||
func tmpKeyStore(t *testing.T, new func(string) crypto.KeyStore) (string, crypto.KeyStore) {
|
||||
d, err := ioutil.TempDir("", "eth-keystore-test")
|
||||
|
@ -7,7 +7,12 @@ if [ ! -f "build/env.sh" ]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Since Go 1.5, the separator char for link time assignments
|
||||
# is '=' and using ' ' prints a warning. However, Go < 1.5 does
|
||||
# not support using '='.
|
||||
sep=$(go version | awk '{ if ($3 >= "go1.5" || index($3, "devel")) print "="; else print " "; }' -)
|
||||
|
||||
# set gitCommit when running from a Git checkout.
|
||||
if [ -f ".git/HEAD" ]; then
|
||||
echo "-ldflags '-X main.gitCommit $(git rev-parse HEAD)'"
|
||||
echo "-ldflags '-X main.gitCommit$sep$(git rev-parse HEAD)'"
|
||||
fi
|
||||
|
@ -1,26 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script runs all package tests and merges the resulting coverage
|
||||
# profiles. Coverage is accounted per package under test.
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
echo "" > coverage.txt
|
||||
|
||||
if [ ! -f "build/env.sh" ]; then
|
||||
echo "$0 must be run from the root of the repository."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "mode: count" > profile.cov
|
||||
|
||||
for pkg in $(go list ./...); do
|
||||
# drop the namespace prefix.
|
||||
dir=${pkg##github.com/ethereum/go-ethereum/}
|
||||
|
||||
if [[ $dir != "tests" ]]; then
|
||||
go test -covermode=count -coverprofile=$dir/profile.tmp $pkg
|
||||
fi
|
||||
if [[ -f $dir/profile.tmp ]]; then
|
||||
tail -n +2 $dir/profile.tmp >> profile.cov
|
||||
rm $dir/profile.tmp
|
||||
for d in $(find ./* -maxdepth 10 -type d -not -path "./build" -not -path "./Godeps/*" ); do
|
||||
if ls $d/*.go &> /dev/null; then
|
||||
go test -coverprofile=profile.out -covermode=atomic $d
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out >> coverage.txt
|
||||
echo '<<<<<< EOF' >> coverage.txt
|
||||
rm profile.out
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
@ -48,6 +48,7 @@ var (
|
||||
"Godeps/", "tests/files/", "build/",
|
||||
// don't relicense vendored packages
|
||||
"crypto/sha3/", "crypto/ecies/", "logger/glog/",
|
||||
"crypto/curve.go",
|
||||
}
|
||||
|
||||
// paths with this prefix are licensed as GPL. all other files are LGPL.
|
||||
@ -65,20 +66,20 @@ var (
|
||||
// its input is an info structure.
|
||||
var licenseT = template.Must(template.New("").Parse(`
|
||||
// Copyright {{.Year}} The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of {{.Whole false}}.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// {{.Whole true}} is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU {{.License}} as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// {{.Whole true}} is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU {{.License}} for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU {{.License}}
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with {{.Whole false}}. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
`[1:]))
|
||||
|
||||
@ -90,17 +91,25 @@ type info struct {
|
||||
func (i info) License() string {
|
||||
if i.gpl() {
|
||||
return "General Public License"
|
||||
} else {
|
||||
return "Lesser General Public License"
|
||||
}
|
||||
return "Lesser General Public License"
|
||||
}
|
||||
|
||||
func (i info) ShortLicense() string {
|
||||
if i.gpl() {
|
||||
return "GPL"
|
||||
} else {
|
||||
return "LGPL"
|
||||
}
|
||||
return "LGPL"
|
||||
}
|
||||
|
||||
func (i info) Whole(startOfSentence bool) string {
|
||||
if i.gpl() {
|
||||
return "go-ethereum"
|
||||
}
|
||||
if startOfSentence {
|
||||
return "The go-ethereum library"
|
||||
}
|
||||
return "the go-ethereum library"
|
||||
}
|
||||
|
||||
func (i info) gpl() bool {
|
||||
|
16
cmd/LICENSE
16
cmd/LICENSE
@ -1,16 +0,0 @@
|
||||
Copyright (c) 2013-2015, The go-ethereum Authors. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// bootnode runs a bootstrap node for the Ethereum Discovery Protocol.
|
||||
package main
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// disasm is a pretty-printer for EVM bytecode.
|
||||
package main
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// ethtest executes Ethereum JSON tests.
|
||||
package main
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/tests"
|
||||
)
|
||||
@ -35,7 +36,8 @@ var (
|
||||
testExtension = ".json"
|
||||
defaultTest = "all"
|
||||
defaultDir = "."
|
||||
allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"}
|
||||
allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests", "RLPTests"}
|
||||
testDirMapping = map[string]string{"BlockTests": "BlockchainTests"}
|
||||
skipTests = []string{}
|
||||
|
||||
TestFlag = cli.StringFlag{
|
||||
@ -61,6 +63,10 @@ var (
|
||||
Name: "skip",
|
||||
Usage: "Tests names to skip",
|
||||
}
|
||||
TraceFlag = cli.BoolFlag{
|
||||
Name: "trace",
|
||||
Usage: "Enable VM tracing",
|
||||
}
|
||||
)
|
||||
|
||||
func runTestWithReader(test string, r io.Reader) error {
|
||||
@ -75,6 +81,8 @@ func runTestWithReader(test string, r io.Reader) error {
|
||||
err = tests.RunTransactionTestsWithReader(r, skipTests)
|
||||
case "vm", "vmtest", "vmtests":
|
||||
err = tests.RunVmTestWithReader(r, skipTests)
|
||||
case "rlp", "rlptest", "rlptests":
|
||||
err = tests.RunRLPTestWithReader(r, skipTests)
|
||||
default:
|
||||
err = fmt.Errorf("Invalid test type specified: %v", test)
|
||||
}
|
||||
@ -133,8 +141,13 @@ func runSuite(test, file string) {
|
||||
var err error
|
||||
var files []string
|
||||
if test == defaultTest {
|
||||
files, err = getFiles(filepath.Join(file, curTest))
|
||||
|
||||
// check if we have an explicit directory mapping for the test
|
||||
if _, ok := testDirMapping[curTest]; ok {
|
||||
files, err = getFiles(filepath.Join(file, testDirMapping[curTest]))
|
||||
} else {
|
||||
// otherwise assume test name
|
||||
files, err = getFiles(filepath.Join(file, curTest))
|
||||
}
|
||||
} else {
|
||||
files, err = getFiles(file)
|
||||
}
|
||||
@ -165,7 +178,6 @@ func runSuite(test, file string) {
|
||||
glog.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,6 +188,7 @@ func setupApp(c *cli.Context) {
|
||||
continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name)
|
||||
useStdIn := c.GlobalBool(ReadStdInFlag.Name)
|
||||
skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ")
|
||||
vm.Debug = c.GlobalBool(TraceFlag.Name)
|
||||
|
||||
if !useStdIn {
|
||||
runSuite(flagTest, flagFile)
|
||||
@ -203,6 +216,7 @@ func main() {
|
||||
ContinueOnErrorFlag,
|
||||
ReadStdInFlag,
|
||||
SkipTestsFlag,
|
||||
TraceFlag,
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
|
143
cmd/evm/main.go
143
cmd/evm/main.go
@ -8,89 +8,153 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// evm executes EVM code snippets.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
)
|
||||
|
||||
var (
|
||||
code = flag.String("code", "", "evm code")
|
||||
loglevel = flag.Int("log", 4, "log level")
|
||||
gas = flag.String("gas", "1000000000", "gas amount")
|
||||
price = flag.String("price", "0", "gas price")
|
||||
value = flag.String("value", "0", "tx value")
|
||||
dump = flag.Bool("dump", false, "dump state after run")
|
||||
data = flag.String("data", "", "data")
|
||||
app *cli.App
|
||||
DebugFlag = cli.BoolFlag{
|
||||
Name: "debug",
|
||||
Usage: "output full trace logs",
|
||||
}
|
||||
ForceJitFlag = cli.BoolFlag{
|
||||
Name: "forcejit",
|
||||
Usage: "forces jit compilation",
|
||||
}
|
||||
DisableJitFlag = cli.BoolFlag{
|
||||
Name: "nojit",
|
||||
Usage: "disabled jit compilation",
|
||||
}
|
||||
CodeFlag = cli.StringFlag{
|
||||
Name: "code",
|
||||
Usage: "EVM code",
|
||||
}
|
||||
GasFlag = cli.StringFlag{
|
||||
Name: "gas",
|
||||
Usage: "gas limit for the evm",
|
||||
Value: "10000000000",
|
||||
}
|
||||
PriceFlag = cli.StringFlag{
|
||||
Name: "price",
|
||||
Usage: "price set for the evm",
|
||||
Value: "0",
|
||||
}
|
||||
ValueFlag = cli.StringFlag{
|
||||
Name: "value",
|
||||
Usage: "value set for the evm",
|
||||
Value: "0",
|
||||
}
|
||||
DumpFlag = cli.BoolFlag{
|
||||
Name: "dump",
|
||||
Usage: "dumps the state after the run",
|
||||
}
|
||||
InputFlag = cli.StringFlag{
|
||||
Name: "input",
|
||||
Usage: "input for the EVM",
|
||||
}
|
||||
SysStatFlag = cli.BoolFlag{
|
||||
Name: "sysstat",
|
||||
Usage: "display system stats",
|
||||
}
|
||||
)
|
||||
|
||||
func perr(v ...interface{}) {
|
||||
fmt.Println(v...)
|
||||
//os.Exit(1)
|
||||
func init() {
|
||||
app = utils.NewApp("0.2", "the evm command line interface")
|
||||
app.Flags = []cli.Flag{
|
||||
DebugFlag,
|
||||
ForceJitFlag,
|
||||
DisableJitFlag,
|
||||
SysStatFlag,
|
||||
CodeFlag,
|
||||
GasFlag,
|
||||
PriceFlag,
|
||||
ValueFlag,
|
||||
DumpFlag,
|
||||
InputFlag,
|
||||
}
|
||||
app.Action = run
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
func run(ctx *cli.Context) {
|
||||
vm.Debug = ctx.GlobalBool(DebugFlag.Name)
|
||||
vm.ForceJit = ctx.GlobalBool(ForceJitFlag.Name)
|
||||
vm.EnableJit = !ctx.GlobalBool(DisableJitFlag.Name)
|
||||
|
||||
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(*loglevel)))
|
||||
glog.SetToStderr(true)
|
||||
|
||||
vm.Debug = true
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
statedb := state.New(common.Hash{}, db)
|
||||
sender := statedb.CreateAccount(common.StringToAddress("sender"))
|
||||
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
||||
receiver.SetCode(common.Hex2Bytes(*code))
|
||||
receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)))
|
||||
|
||||
vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(*value))
|
||||
vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name)))
|
||||
|
||||
tstart := time.Now()
|
||||
ret, e := vmenv.Call(
|
||||
sender,
|
||||
receiver.Address(),
|
||||
common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)),
|
||||
common.Big(ctx.GlobalString(GasFlag.Name)),
|
||||
common.Big(ctx.GlobalString(PriceFlag.Name)),
|
||||
common.Big(ctx.GlobalString(ValueFlag.Name)),
|
||||
)
|
||||
vmdone := time.Since(tstart)
|
||||
|
||||
ret, e := vmenv.Call(sender, receiver.Address(), common.Hex2Bytes(*data), common.Big(*gas), common.Big(*price), common.Big(*value))
|
||||
|
||||
logger.Flush()
|
||||
if e != nil {
|
||||
perr(e)
|
||||
}
|
||||
|
||||
if *dump {
|
||||
if ctx.GlobalBool(DumpFlag.Name) {
|
||||
fmt.Println(string(statedb.Dump()))
|
||||
}
|
||||
|
||||
vm.StdErrFormat(vmenv.StructLogs())
|
||||
|
||||
var mem runtime.MemStats
|
||||
runtime.ReadMemStats(&mem)
|
||||
fmt.Printf("vm took %v\n", time.Since(tstart))
|
||||
fmt.Printf(`alloc: %d
|
||||
if ctx.GlobalBool(SysStatFlag.Name) {
|
||||
var mem runtime.MemStats
|
||||
runtime.ReadMemStats(&mem)
|
||||
fmt.Printf("vm took %v\n", vmdone)
|
||||
fmt.Printf(`alloc: %d
|
||||
tot alloc: %d
|
||||
no. malloc: %d
|
||||
heap alloc: %d
|
||||
heap objs: %d
|
||||
num gc: %d
|
||||
`, mem.Alloc, mem.TotalAlloc, mem.Mallocs, mem.HeapAlloc, mem.HeapObjects, mem.NumGC)
|
||||
}
|
||||
|
||||
fmt.Printf("%x\n", ret)
|
||||
fmt.Printf("OUT: 0x%x", ret)
|
||||
if e != nil {
|
||||
fmt.Printf(" error: %v", e)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
type VMEnv struct {
|
||||
@ -102,7 +166,7 @@ type VMEnv struct {
|
||||
|
||||
depth int
|
||||
Gas *big.Int
|
||||
time uint64
|
||||
time *big.Int
|
||||
logs []vm.StructLog
|
||||
}
|
||||
|
||||
@ -111,7 +175,7 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int) *VM
|
||||
state: state,
|
||||
transactor: &transactor,
|
||||
value: value,
|
||||
time: uint64(time.Now().Unix()),
|
||||
time: big.NewInt(time.Now().Unix()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +183,7 @@ func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||
func (self *VMEnv) Origin() common.Address { return *self.transactor }
|
||||
func (self *VMEnv) BlockNumber() *big.Int { return common.Big0 }
|
||||
func (self *VMEnv) Coinbase() common.Address { return *self.transactor }
|
||||
func (self *VMEnv) Time() uint64 { return self.time }
|
||||
func (self *VMEnv) Time() *big.Int { return self.time }
|
||||
func (self *VMEnv) Difficulty() *big.Int { return common.Big1 }
|
||||
func (self *VMEnv) BlockHash() []byte { return make([]byte, 32) }
|
||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||
@ -142,6 +206,9 @@ func (self *VMEnv) StructLogs() []vm.StructLog {
|
||||
func (self *VMEnv) AddLog(log *state.Log) {
|
||||
self.state.AddLog(log)
|
||||
}
|
||||
func (self *VMEnv) CanTransfer(from vm.Account, balance *big.Int) bool {
|
||||
return from.Balance().Cmp(balance) >= 0
|
||||
}
|
||||
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
||||
return vm.Transfer(from, to, amount)
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
@ -22,7 +22,6 @@ import (
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/tests"
|
||||
@ -92,7 +91,6 @@ func runBlockTest(ctx *cli.Context) {
|
||||
if err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
}
|
||||
defer ethereum.Stop()
|
||||
if rpc {
|
||||
fmt.Println("Block Test post state validated, starting RPC interface.")
|
||||
startEth(ctx, ethereum)
|
||||
@ -103,34 +101,31 @@ func runBlockTest(ctx *cli.Context) {
|
||||
|
||||
func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
|
||||
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
|
||||
cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }
|
||||
cfg.NewDB = func(path string) (ethdb.Database, error) { return ethdb.NewMemDatabase() }
|
||||
cfg.MaxPeers = 0 // disable network
|
||||
cfg.Shh = false // disable whisper
|
||||
cfg.NAT = nil // disable port mapping
|
||||
|
||||
ethereum, err := eth.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if err := ethereum.Start(); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// import the genesis block
|
||||
ethereum.ResetWithGenesisBlock(test.Genesis)
|
||||
|
||||
// import pre accounts
|
||||
statedb, err := test.InsertPreState(ethereum)
|
||||
_, err = test.InsertPreState(ethereum)
|
||||
if err != nil {
|
||||
return ethereum, fmt.Errorf("InsertPreState: %v", err)
|
||||
}
|
||||
|
||||
if err := test.TryBlocksInsert(ethereum.ChainManager()); err != nil {
|
||||
cm := ethereum.ChainManager()
|
||||
validBlocks, err := test.TryBlocksInsert(cm)
|
||||
if err != nil {
|
||||
return ethereum, fmt.Errorf("Block Test load error: %v", err)
|
||||
}
|
||||
|
||||
if err := test.ValidatePostState(statedb); err != nil {
|
||||
newDB := cm.State()
|
||||
if err := test.ValidatePostState(newDB); err != nil {
|
||||
return ethereum, fmt.Errorf("post state validation failed: %v", err)
|
||||
}
|
||||
return ethereum, nil
|
||||
return ethereum, test.ValidateImportedHeaders(cm, validBlocks)
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
@ -29,6 +29,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
)
|
||||
|
||||
@ -74,10 +75,10 @@ func importChain(ctx *cli.Context) {
|
||||
if len(ctx.Args()) != 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
chain, blockDB, stateDB, extraDB := utils.MakeChain(ctx)
|
||||
chain, chainDb := utils.MakeChain(ctx)
|
||||
start := time.Now()
|
||||
err := utils.ImportChain(chain, ctx.Args().First())
|
||||
closeAll(blockDB, stateDB, extraDB)
|
||||
chainDb.Close()
|
||||
if err != nil {
|
||||
utils.Fatalf("Import error: %v", err)
|
||||
}
|
||||
@ -88,7 +89,7 @@ func exportChain(ctx *cli.Context) {
|
||||
if len(ctx.Args()) < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
chain, _, _, _ := utils.MakeChain(ctx)
|
||||
chain, _ := utils.MakeChain(ctx)
|
||||
start := time.Now()
|
||||
|
||||
var err error
|
||||
@ -115,17 +116,16 @@ func exportChain(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func removeDB(ctx *cli.Context) {
|
||||
confirm, err := utils.PromptConfirm("Remove local databases?")
|
||||
confirm, err := utils.PromptConfirm("Remove local database?")
|
||||
if err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
if confirm {
|
||||
fmt.Println("Removing chain and state databases...")
|
||||
fmt.Println("Removing chaindata...")
|
||||
start := time.Now()
|
||||
|
||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
|
||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
|
||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata"))
|
||||
|
||||
fmt.Printf("Removed in %v\n", time.Since(start))
|
||||
} else {
|
||||
@ -136,8 +136,8 @@ func removeDB(ctx *cli.Context) {
|
||||
func upgradeDB(ctx *cli.Context) {
|
||||
glog.Infoln("Upgrading blockchain database")
|
||||
|
||||
chain, blockDB, stateDB, extraDB := utils.MakeChain(ctx)
|
||||
v, _ := blockDB.Get([]byte("BlockchainVersion"))
|
||||
chain, chainDb := utils.MakeChain(ctx)
|
||||
v, _ := chainDb.Get([]byte("BlockchainVersion"))
|
||||
bcVersion := int(common.NewValue(v).Uint())
|
||||
if bcVersion == 0 {
|
||||
bcVersion = core.BlockChainVersion
|
||||
@ -149,15 +149,14 @@ func upgradeDB(ctx *cli.Context) {
|
||||
if err := utils.ExportChain(chain, exportFile); err != nil {
|
||||
utils.Fatalf("Unable to export chain for reimport %s", err)
|
||||
}
|
||||
closeAll(blockDB, stateDB, extraDB)
|
||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
|
||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
|
||||
chainDb.Close()
|
||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata"))
|
||||
|
||||
// Import the chain file.
|
||||
chain, blockDB, stateDB, extraDB = utils.MakeChain(ctx)
|
||||
blockDB.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes())
|
||||
chain, chainDb = utils.MakeChain(ctx)
|
||||
chainDb.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes())
|
||||
err := utils.ImportChain(chain, exportFile)
|
||||
closeAll(blockDB, stateDB, extraDB)
|
||||
chainDb.Close()
|
||||
if err != nil {
|
||||
utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)", err, exportFile)
|
||||
} else {
|
||||
@ -167,7 +166,7 @@ func upgradeDB(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func dump(ctx *cli.Context) {
|
||||
chain, _, stateDB, _ := utils.MakeChain(ctx)
|
||||
chain, chainDb := utils.MakeChain(ctx)
|
||||
for _, arg := range ctx.Args() {
|
||||
var block *types.Block
|
||||
if hashish(arg) {
|
||||
@ -180,10 +179,11 @@ func dump(ctx *cli.Context) {
|
||||
fmt.Println("{}")
|
||||
utils.Fatalf("block not found")
|
||||
} else {
|
||||
state := state.New(block.Root(), stateDB)
|
||||
state := state.New(block.Root(), chainDb)
|
||||
fmt.Printf("%s\n", state.Dump())
|
||||
}
|
||||
}
|
||||
chainDb.Close()
|
||||
}
|
||||
|
||||
// hashish returns true for strings that look like hashes.
|
||||
@ -192,7 +192,7 @@ func hashish(x string) bool {
|
||||
return err != nil
|
||||
}
|
||||
|
||||
func closeAll(dbs ...common.Database) {
|
||||
func closeAll(dbs ...ethdb.Database) {
|
||||
for _, db := range dbs {
|
||||
db.Close()
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
@ -23,6 +23,7 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"sort"
|
||||
@ -44,6 +45,10 @@ import (
|
||||
"github.com/robertkrimen/otto"
|
||||
)
|
||||
|
||||
var passwordRegexp = regexp.MustCompile("personal.[nu]")
|
||||
|
||||
const passwordRepl = ""
|
||||
|
||||
type prompter interface {
|
||||
AppendHistory(string)
|
||||
Prompt(p string) (string, error)
|
||||
@ -116,7 +121,7 @@ func keywordCompleter(line string) []string {
|
||||
}
|
||||
|
||||
func apiWordCompleter(line string, pos int) (head string, completions []string, tail string) {
|
||||
if len(line) == 0 {
|
||||
if len(line) == 0 || pos == 0 {
|
||||
return "", nil, ""
|
||||
}
|
||||
|
||||
@ -140,19 +145,15 @@ func apiWordCompleter(line string, pos int) (head string, completions []string,
|
||||
return begin, completionWords, end
|
||||
}
|
||||
|
||||
func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre {
|
||||
func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool) *jsre {
|
||||
js := &jsre{ps1: "> "}
|
||||
js.wait = make(chan *big.Int)
|
||||
js.client = client
|
||||
js.ds = docserver.New("/")
|
||||
|
||||
if f == nil {
|
||||
f = js
|
||||
}
|
||||
|
||||
// update state in separare forever blocks
|
||||
js.re = re.New(libPath)
|
||||
if err := js.apiBindings(f); err != nil {
|
||||
if err := js.apiBindings(js); err != nil {
|
||||
utils.Fatalf("Unable to initialize console - %v", err)
|
||||
}
|
||||
|
||||
@ -227,15 +228,10 @@ func (self *jsre) loadAutoCompletion() {
|
||||
}
|
||||
|
||||
func (self *jsre) batch(statement string) {
|
||||
val, err := self.re.Run(statement)
|
||||
err := self.re.EvalAndPrettyPrint(statement)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v", err)
|
||||
} else if val.IsDefined() && val.IsObject() {
|
||||
obj, _ := self.re.Get("ret_result")
|
||||
fmt.Printf("%v", obj)
|
||||
} else if val.IsDefined() {
|
||||
fmt.Printf("%v", val)
|
||||
}
|
||||
|
||||
if self.atexit != nil {
|
||||
@ -247,22 +243,22 @@ func (self *jsre) batch(statement string) {
|
||||
|
||||
// show summary of current geth instance
|
||||
func (self *jsre) welcome() {
|
||||
self.re.Eval(`console.log('instance: ' + web3.version.client);`)
|
||||
self.re.Eval(`console.log(' datadir: ' + admin.datadir);`)
|
||||
self.re.Eval(`console.log("coinbase: " + eth.coinbase);`)
|
||||
self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`)
|
||||
self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString()
|
||||
+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
|
||||
|
||||
self.re.Run(`
|
||||
(function () {
|
||||
console.log('instance: ' + web3.version.client);
|
||||
console.log(' datadir: ' + admin.datadir);
|
||||
console.log("coinbase: " + eth.coinbase);
|
||||
var ts = 1000 * eth.getBlock(eth.blockNumber).timestamp;
|
||||
console.log("at block: " + eth.blockNumber + " (" + new Date(ts) + ")");
|
||||
})();
|
||||
`)
|
||||
if modules, err := self.supportedApis(); err == nil {
|
||||
loadedModules := make([]string, 0)
|
||||
for api, version := range modules {
|
||||
loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
|
||||
}
|
||||
sort.Strings(loadedModules)
|
||||
|
||||
self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " ")))
|
||||
self.re.Eval(`console.log(" modules: " + modules);`)
|
||||
fmt.Println("modules:", strings.Join(loadedModules, " "))
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +282,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
|
||||
utils.Fatalf("Unable to determine supported api's: %v", err)
|
||||
}
|
||||
|
||||
jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client)
|
||||
jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client, f)
|
||||
js.re.Set("jeth", struct{}{})
|
||||
t, _ := js.re.Get("jeth")
|
||||
jethObj := t.Object()
|
||||
@ -304,12 +300,12 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
|
||||
utils.Fatalf("Error loading web3.js: %v", err)
|
||||
}
|
||||
|
||||
_, err = js.re.Eval("var web3 = require('web3');")
|
||||
_, err = js.re.Run("var web3 = require('web3');")
|
||||
if err != nil {
|
||||
utils.Fatalf("Error requiring web3: %v", err)
|
||||
}
|
||||
|
||||
_, err = js.re.Eval("web3.setProvider(jeth)")
|
||||
_, err = js.re.Run("web3.setProvider(jeth)")
|
||||
if err != nil {
|
||||
utils.Fatalf("Error setting web3 provider: %v", err)
|
||||
}
|
||||
@ -328,13 +324,13 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
|
||||
}
|
||||
}
|
||||
|
||||
_, err = js.re.Eval(shortcuts)
|
||||
_, err = js.re.Run(shortcuts)
|
||||
|
||||
if err != nil {
|
||||
utils.Fatalf("Error setting namespaces: %v", err)
|
||||
}
|
||||
|
||||
js.re.Eval(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
|
||||
js.re.Run(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -382,6 +378,11 @@ func (self *jsre) interactive() {
|
||||
for {
|
||||
line, err := self.Prompt(<-prompt)
|
||||
if err != nil {
|
||||
if err == liner.ErrPromptAborted { // ctrl-C
|
||||
self.resetPrompt()
|
||||
inputln <- ""
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
inputln <- line
|
||||
@ -413,8 +414,10 @@ func (self *jsre) interactive() {
|
||||
str += input + "\n"
|
||||
self.setIndent()
|
||||
if indentCount <= 0 {
|
||||
hist := str[:len(str)-1]
|
||||
self.AppendHistory(hist)
|
||||
hist := hidepassword(str[:len(str)-1])
|
||||
if len(hist) > 0 {
|
||||
self.AppendHistory(hist)
|
||||
}
|
||||
self.parseInput(str)
|
||||
str = ""
|
||||
}
|
||||
@ -422,6 +425,14 @@ func (self *jsre) interactive() {
|
||||
}
|
||||
}
|
||||
|
||||
func hidepassword(input string) string {
|
||||
if passwordRegexp.MatchString(input) {
|
||||
return passwordRepl
|
||||
} else {
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
func (self *jsre) withHistory(op func(*os.File)) {
|
||||
datadir := common.DefaultDataDir()
|
||||
if self.ethereum != nil {
|
||||
@ -443,8 +454,7 @@ func (self *jsre) parseInput(code string) {
|
||||
fmt.Println("[native] error", r)
|
||||
}
|
||||
}()
|
||||
value, err := self.re.Run(code)
|
||||
if err != nil {
|
||||
if err := self.re.EvalAndPrettyPrint(code); err != nil {
|
||||
if ottoErr, ok := err.(*otto.Error); ok {
|
||||
fmt.Println(ottoErr.String())
|
||||
} else {
|
||||
@ -452,12 +462,17 @@ func (self *jsre) parseInput(code string) {
|
||||
}
|
||||
return
|
||||
}
|
||||
self.printValue(value)
|
||||
}
|
||||
|
||||
var indentCount = 0
|
||||
var str = ""
|
||||
|
||||
func (self *jsre) resetPrompt() {
|
||||
indentCount = 0
|
||||
str = ""
|
||||
self.ps1 = "> "
|
||||
}
|
||||
|
||||
func (self *jsre) setIndent() {
|
||||
open := strings.Count(str, "{")
|
||||
open += strings.Count(str, "(")
|
||||
@ -471,10 +486,3 @@ func (self *jsre) setIndent() {
|
||||
self.ps1 += " "
|
||||
}
|
||||
}
|
||||
|
||||
func (self *jsre) printValue(v interface{}) {
|
||||
val, err := self.re.PrettyPrint(v)
|
||||
if err == nil {
|
||||
fmt.Printf("%v", val)
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
@ -37,6 +37,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||
)
|
||||
@ -89,9 +90,9 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// set up mock genesis with balance on the testAddress
|
||||
core.GenesisAccounts = []byte(testGenesis)
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
|
||||
core.WriteGenesisBlockForTesting(db, core.GenesisAccount{common.HexToAddress(testAddress), common.String2Big(testBalance)})
|
||||
ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keystore"))
|
||||
am := accounts.NewManager(ks)
|
||||
conf := ð.Config{
|
||||
@ -102,6 +103,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth
|
||||
Name: "test",
|
||||
SolcPath: testSolcPath,
|
||||
PowTest: true,
|
||||
NewDB: func(path string) (ethdb.Database, error) { return db, nil },
|
||||
}
|
||||
if config != nil {
|
||||
config(conf)
|
||||
@ -157,7 +159,7 @@ func TestAccounts(t *testing.T) {
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`"]`)
|
||||
checkEvalJSON(t, repl, `eth.coinbase`, `null`)
|
||||
checkEvalJSON(t, repl, `eth.coinbase`, `"`+testAddress+`"`)
|
||||
val, err := repl.re.Run(`personal.newAccount("password")`)
|
||||
if err != nil {
|
||||
t.Errorf("expected no error, got %v", err)
|
||||
@ -168,6 +170,7 @@ func TestAccounts(t *testing.T) {
|
||||
}
|
||||
|
||||
checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`","`+addr+`"]`)
|
||||
|
||||
}
|
||||
|
||||
func TestBlockChain(t *testing.T) {
|
||||
|
120
cmd/geth/main.go
120
cmd/geth/main.go
@ -8,18 +8,17 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// geth is the official command-line client for Ethereum.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
@ -41,21 +40,29 @@ import (
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
const (
|
||||
ClientIdentifier = "Geth"
|
||||
Version = "0.9.38"
|
||||
Version = "1.2.3"
|
||||
VersionMajor = 1
|
||||
VersionMinor = 2
|
||||
VersionPatch = 3
|
||||
)
|
||||
|
||||
var (
|
||||
gitCommit string // set via linker flag
|
||||
gitCommit string // set via linker flagg
|
||||
nodeNameVersion string
|
||||
app *cli.App
|
||||
|
||||
ExtraDataFlag = cli.StringFlag{
|
||||
Name: "extradata",
|
||||
Usage: "Extra data for the miner",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -276,10 +283,13 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
|
||||
utils.IdentityFlag,
|
||||
utils.UnlockedAccountFlag,
|
||||
utils.PasswordFileFlag,
|
||||
utils.GenesisNonceFlag,
|
||||
utils.GenesisFileFlag,
|
||||
utils.BootnodesFlag,
|
||||
utils.DataDirFlag,
|
||||
utils.BlockchainVersionFlag,
|
||||
utils.OlympicFlag,
|
||||
utils.EthVersionFlag,
|
||||
utils.CacheFlag,
|
||||
utils.JSpathFlag,
|
||||
utils.ListenPortFlag,
|
||||
utils.MaxPeersFlag,
|
||||
@ -303,7 +313,11 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
|
||||
utils.IPCPathFlag,
|
||||
utils.ExecFlag,
|
||||
utils.WhisperEnabledFlag,
|
||||
utils.DevModeFlag,
|
||||
utils.VMDebugFlag,
|
||||
utils.VMForceJitFlag,
|
||||
utils.VMJitCacheFlag,
|
||||
utils.VMEnableJitFlag,
|
||||
utils.NetworkIdFlag,
|
||||
utils.RPCCORSDomainFlag,
|
||||
utils.VerbosityFlag,
|
||||
@ -322,9 +336,12 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
|
||||
utils.GpobaseStepDownFlag,
|
||||
utils.GpobaseStepUpFlag,
|
||||
utils.GpobaseCorrectionFactorFlag,
|
||||
ExtraDataFlag,
|
||||
}
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
utils.SetupLogger(ctx)
|
||||
utils.SetupVM(ctx)
|
||||
utils.SetupEth(ctx)
|
||||
if ctx.GlobalBool(utils.PProfEanbledFlag.Name) {
|
||||
utils.StartPProf(ctx)
|
||||
}
|
||||
@ -343,8 +360,44 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// makeExtra resolves extradata for the miner from a flag or returns a default.
|
||||
func makeExtra(ctx *cli.Context) []byte {
|
||||
if ctx.GlobalIsSet(ExtraDataFlag.Name) {
|
||||
return []byte(ctx.GlobalString(ExtraDataFlag.Name))
|
||||
}
|
||||
return makeDefaultExtra()
|
||||
}
|
||||
|
||||
func makeDefaultExtra() []byte {
|
||||
var clientInfo = struct {
|
||||
Version uint
|
||||
Name string
|
||||
GoVersion string
|
||||
Os string
|
||||
}{uint(VersionMajor<<16 | VersionMinor<<8 | VersionPatch), ClientIdentifier, runtime.Version(), runtime.GOOS}
|
||||
extra, err := rlp.EncodeToBytes(clientInfo)
|
||||
if err != nil {
|
||||
glog.V(logger.Warn).Infoln("error setting canonical miner information:", err)
|
||||
}
|
||||
|
||||
if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() {
|
||||
glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
|
||||
glog.V(logger.Debug).Infof("extra: %x\n", extra)
|
||||
return nil
|
||||
}
|
||||
|
||||
return extra
|
||||
}
|
||||
|
||||
func run(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
if ctx.GlobalBool(utils.OlympicFlag.Name) {
|
||||
utils.InitOlympic()
|
||||
}
|
||||
|
||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||
cfg.ExtraData = makeExtra(ctx)
|
||||
|
||||
ethereum, err := eth.New(cfg)
|
||||
if err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
@ -356,13 +409,7 @@ func run(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func attach(ctx *cli.Context) {
|
||||
// Wrap the standard output with a colorified stream (windows)
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
if pr, pw, err := os.Pipe(); err == nil {
|
||||
go io.Copy(colorable.NewColorableStdout(), pr)
|
||||
os.Stdout = pw
|
||||
}
|
||||
}
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
var client comms.EthereumClient
|
||||
var err error
|
||||
@ -370,7 +417,7 @@ func attach(ctx *cli.Context) {
|
||||
client, err = comms.ClientFromEndpoint(ctx.Args().First(), codec.JSON)
|
||||
} else {
|
||||
cfg := comms.IpcConfig{
|
||||
Endpoint: ctx.GlobalString(utils.IPCPathFlag.Name),
|
||||
Endpoint: utils.IpcSocketPath(ctx),
|
||||
}
|
||||
client, err = comms.NewIpcClient(cfg, codec.JSON)
|
||||
}
|
||||
@ -383,7 +430,7 @@ func attach(ctx *cli.Context) {
|
||||
ctx.GlobalString(utils.JSpathFlag.Name),
|
||||
client,
|
||||
true,
|
||||
nil)
|
||||
)
|
||||
|
||||
if ctx.GlobalString(utils.ExecFlag.Name) != "" {
|
||||
repl.batch(ctx.GlobalString(utils.ExecFlag.Name))
|
||||
@ -394,15 +441,11 @@ func attach(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func console(ctx *cli.Context) {
|
||||
// Wrap the standard output with a colorified stream (windows)
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
if pr, pw, err := os.Pipe(); err == nil {
|
||||
go io.Copy(colorable.NewColorableStdout(), pr)
|
||||
os.Stdout = pw
|
||||
}
|
||||
}
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||
cfg.ExtraData = makeExtra(ctx)
|
||||
|
||||
ethereum, err := eth.New(cfg)
|
||||
if err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
@ -432,6 +475,8 @@ func console(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func execJSFiles(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||
ethereum, err := eth.New(cfg)
|
||||
if err != nil {
|
||||
@ -457,6 +502,8 @@ func execJSFiles(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func unlockAccount(ctx *cli.Context, am *accounts.Manager, addr string, i int) (addrHex, auth string) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
var err error
|
||||
addrHex, err = utils.ParamToAddress(addr, am)
|
||||
if err == nil {
|
||||
@ -480,30 +527,33 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, addr string, i int) (
|
||||
}
|
||||
|
||||
func blockRecovery(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
arg := ctx.Args().First()
|
||||
if len(ctx.Args()) < 1 && len(arg) > 0 {
|
||||
glog.Fatal("recover requires block number or hash")
|
||||
}
|
||||
|
||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"))
|
||||
utils.CheckLegalese(cfg.DataDir)
|
||||
|
||||
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache)
|
||||
if err != nil {
|
||||
glog.Fatalln("could not open db:", err)
|
||||
}
|
||||
|
||||
var block *types.Block
|
||||
if arg[0] == '#' {
|
||||
block = core.GetBlockByNumber(blockDb, common.String2Big(arg[1:]).Uint64())
|
||||
block = core.GetBlock(blockDb, core.GetCanonicalHash(blockDb, common.String2Big(arg[1:]).Uint64()))
|
||||
} else {
|
||||
block = core.GetBlockByHash(blockDb, common.HexToHash(arg))
|
||||
block = core.GetBlock(blockDb, common.HexToHash(arg))
|
||||
}
|
||||
|
||||
if block == nil {
|
||||
glog.Fatalln("block not found. Recovery failed")
|
||||
}
|
||||
|
||||
err = core.WriteHead(blockDb, block)
|
||||
if err != nil {
|
||||
if err = core.WriteHeadBlockHash(blockDb, block.Hash()); err != nil {
|
||||
glog.Fatalln("block write err", err)
|
||||
}
|
||||
glog.Infof("Recovery succesful. New HEAD %x\n", block.Hash())
|
||||
@ -543,6 +593,8 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
|
||||
}
|
||||
|
||||
func accountList(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
am := utils.MakeAccountManager(ctx)
|
||||
accts, err := am.Accounts()
|
||||
if err != nil {
|
||||
@ -591,6 +643,8 @@ func getPassPhrase(ctx *cli.Context, desc string, confirmation bool, i int) (pas
|
||||
}
|
||||
|
||||
func accountCreate(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
am := utils.MakeAccountManager(ctx)
|
||||
passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0)
|
||||
acct, err := am.NewAccount(passphrase)
|
||||
@ -601,6 +655,8 @@ func accountCreate(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func accountUpdate(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
am := utils.MakeAccountManager(ctx)
|
||||
arg := ctx.Args().First()
|
||||
if len(arg) == 0 {
|
||||
@ -616,6 +672,8 @@ func accountUpdate(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func importWallet(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
keyfile := ctx.Args().First()
|
||||
if len(keyfile) == 0 {
|
||||
utils.Fatalf("keyfile must be given as argument")
|
||||
@ -636,6 +694,8 @@ func importWallet(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func accountImport(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
keyfile := ctx.Args().First()
|
||||
if len(keyfile) == 0 {
|
||||
utils.Fatalf("keyfile must be given as argument")
|
||||
@ -650,6 +710,8 @@ func accountImport(ctx *cli.Context) {
|
||||
}
|
||||
|
||||
func makedag(ctx *cli.Context) {
|
||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||
|
||||
args := ctx.Args()
|
||||
wrongArgs := func() {
|
||||
utils.Fatalf(`Usage: geth makedag <block number> <outputdir>`)
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
@ -289,7 +289,7 @@ func updateChart(metric string, data []float64, base *int, chart *termui.LineCha
|
||||
}
|
||||
}
|
||||
unit, scale := 0, 1.0
|
||||
for high >= 1000 {
|
||||
for high >= 1000 && unit+1 < len(dataUnits) {
|
||||
high, unit, scale = high/1000, unit+1, scale*1000
|
||||
}
|
||||
// If the unit changes, re-create the chart (hack to set max height...)
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// rlpdump is a pretty-printer for RLP data.
|
||||
package main
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package utils contains internal helper functions for go-ethereum commands.
|
||||
package utils
|
||||
@ -21,6 +21,8 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
@ -32,6 +34,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/peterh/liner"
|
||||
)
|
||||
@ -58,15 +61,16 @@ func PromptConfirm(prompt string) (bool, error) {
|
||||
)
|
||||
prompt = prompt + " [y/N] "
|
||||
|
||||
if liner.TerminalSupported() {
|
||||
lr := liner.NewLiner()
|
||||
defer lr.Close()
|
||||
input, err = lr.Prompt(prompt)
|
||||
} else {
|
||||
fmt.Print(prompt)
|
||||
input, err = bufio.NewReader(os.Stdin).ReadString('\n')
|
||||
fmt.Println()
|
||||
}
|
||||
// if liner.TerminalSupported() {
|
||||
// fmt.Println("term")
|
||||
// lr := liner.NewLiner()
|
||||
// defer lr.Close()
|
||||
// input, err = lr.Prompt(prompt)
|
||||
// } else {
|
||||
fmt.Print(prompt)
|
||||
input, err = bufio.NewReader(os.Stdin).ReadString('\n')
|
||||
fmt.Println()
|
||||
// }
|
||||
|
||||
if len(input) > 0 && strings.ToUpper(input[:1]) == "Y" {
|
||||
return true, nil
|
||||
@ -92,12 +96,12 @@ func PromptPassword(prompt string, warnTerm bool) (string, error) {
|
||||
return input, err
|
||||
}
|
||||
|
||||
func initDataDir(Datadir string) {
|
||||
_, err := os.Stat(Datadir)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Printf("Data directory '%s' doesn't exist, creating it\n", Datadir)
|
||||
os.Mkdir(Datadir, 0777)
|
||||
func CheckLegalese(datadir string) {
|
||||
// check "first run"
|
||||
if !common.FileExist(datadir) {
|
||||
r, _ := PromptConfirm(legalese)
|
||||
if !r {
|
||||
Fatalf("Must accept to continue. Shutting down...\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,6 +146,16 @@ func StartEthereum(ethereum *eth.Ethereum) {
|
||||
}()
|
||||
}
|
||||
|
||||
func InitOlympic() {
|
||||
params.DurationLimit = big.NewInt(8)
|
||||
params.GenesisGasLimit = big.NewInt(3141592)
|
||||
params.MinGasLimit = big.NewInt(125000)
|
||||
params.MaximumExtraDataSize = big.NewInt(1024)
|
||||
NetworkIdFlag.Value = 0
|
||||
core.BlockReward = big.NewInt(1.5e+18)
|
||||
core.ExpDiffPeriod = big.NewInt(math.MaxInt64)
|
||||
}
|
||||
|
||||
func FormatTransactionData(data string) []byte {
|
||||
d := common.StringToByteFunc(data, func(s string) (ret []byte) {
|
||||
slice := regexp.MustCompile("\\n|\\s").Split(s, 1000000000)
|
||||
@ -202,6 +216,11 @@ func ImportChain(chain *core.ChainManager, fn string) error {
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("at block %d: %v", n, err)
|
||||
}
|
||||
// don't import first block
|
||||
if b.NumberU64() == 0 {
|
||||
i--
|
||||
continue
|
||||
}
|
||||
blocks[i] = &b
|
||||
n++
|
||||
}
|
||||
@ -217,6 +236,7 @@ func ImportChain(chain *core.ChainManager, fn string) error {
|
||||
batch, blocks[0].Hash().Bytes()[:4], blocks[i-1].Hash().Bytes()[:4])
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := chain.InsertChain(blocks[:i]); err != nil {
|
||||
return fmt.Errorf("invalid block %d: %v", n, err)
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package utils
|
||||
|
||||
@ -21,7 +21,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
@ -138,11 +138,8 @@ func (self *DirectoryFlag) Set(value string) {
|
||||
func expandPath(p string) string {
|
||||
if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
|
||||
if user, err := user.Current(); err == nil {
|
||||
if err == nil {
|
||||
p = strings.Replace(p, "~", user.HomeDir, 1)
|
||||
}
|
||||
p = user.HomeDir + p[1:]
|
||||
}
|
||||
}
|
||||
|
||||
return filepath.Clean(os.ExpandEnv(p))
|
||||
return path.Clean(os.ExpandEnv(p))
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package utils
|
||||
|
||||
@ -23,18 +23,15 @@ import (
|
||||
)
|
||||
|
||||
func TestPathExpansion(t *testing.T) {
|
||||
|
||||
user, _ := user.Current()
|
||||
|
||||
tests := map[string]string{
|
||||
"/home/someuser/tmp": "/home/someuser/tmp",
|
||||
"~/tmp": user.HomeDir + "/tmp",
|
||||
"~thisOtherUser/b/": "~thisOtherUser/b",
|
||||
"$DDDXXX/a/b": "/tmp/a/b",
|
||||
"/a/b/": "/a/b",
|
||||
}
|
||||
|
||||
os.Setenv("DDDXXX", "/tmp")
|
||||
|
||||
for test, expected := range tests {
|
||||
got := expandPath(test)
|
||||
if got != expected {
|
||||
|
@ -8,11 +8,11 @@
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package utils
|
||||
|
||||
@ -21,29 +21,32 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/ethereum/ethash"
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
"github.com/ethereum/go-ethereum/rpc/api"
|
||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||
"github.com/ethereum/go-ethereum/rpc/useragent"
|
||||
"github.com/ethereum/go-ethereum/xeth"
|
||||
)
|
||||
|
||||
@ -114,6 +117,14 @@ var (
|
||||
Usage: "Sets the genesis nonce",
|
||||
Value: 42,
|
||||
}
|
||||
GenesisFileFlag = cli.StringFlag{
|
||||
Name: "genesis",
|
||||
Usage: "Inserts/Overwrites the genesis block (json format)",
|
||||
}
|
||||
DevModeFlag = cli.BoolFlag{
|
||||
Name: "dev",
|
||||
Usage: "Developer mode. This mode creates a private network and sets several debugging flags",
|
||||
}
|
||||
IdentityFlag = cli.StringFlag{
|
||||
Name: "identity",
|
||||
Usage: "Custom node name",
|
||||
@ -122,6 +133,20 @@ var (
|
||||
Name: "natspec",
|
||||
Usage: "Enable NatSpec confirmation notice",
|
||||
}
|
||||
CacheFlag = cli.IntFlag{
|
||||
Name: "cache",
|
||||
Usage: "Megabytes of memory allocated to internal caching",
|
||||
Value: 0,
|
||||
}
|
||||
OlympicFlag = cli.BoolFlag{
|
||||
Name: "olympic",
|
||||
Usage: "Use olympic style protocol",
|
||||
}
|
||||
EthVersionFlag = cli.IntFlag{
|
||||
Name: "eth",
|
||||
Value: 62,
|
||||
Usage: "Highest eth protocol to advertise (temporary, dev option)",
|
||||
}
|
||||
|
||||
// miner settings
|
||||
MinerThreadsFlag = cli.IntFlag{
|
||||
@ -145,7 +170,7 @@ var (
|
||||
GasPriceFlag = cli.StringFlag{
|
||||
Name: "gasprice",
|
||||
Usage: "Sets the minimal gasprice when mining transactions",
|
||||
Value: new(big.Int).Mul(big.NewInt(1), common.Szabo).String(),
|
||||
Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
|
||||
}
|
||||
|
||||
UnlockedAccountFlag = cli.StringFlag{
|
||||
@ -159,6 +184,25 @@ var (
|
||||
Value: "",
|
||||
}
|
||||
|
||||
// vm flags
|
||||
VMDebugFlag = cli.BoolFlag{
|
||||
Name: "vmdebug",
|
||||
Usage: "Virtual Machine debug output",
|
||||
}
|
||||
VMForceJitFlag = cli.BoolFlag{
|
||||
Name: "forcejit",
|
||||
Usage: "Force the JIT VM to take precedence",
|
||||
}
|
||||
VMJitCacheFlag = cli.IntFlag{
|
||||
Name: "jitcache",
|
||||
Usage: "Amount of cached JIT VM programs",
|
||||
Value: 64,
|
||||
}
|
||||
VMEnableJitFlag = cli.BoolFlag{
|
||||
Name: "jitvm",
|
||||
Usage: "Enable the JIT VM",
|
||||
}
|
||||
|
||||
// logging and debug settings
|
||||
LogFileFlag = cli.StringFlag{
|
||||
Name: "logfile",
|
||||
@ -183,10 +227,6 @@ var (
|
||||
Usage: "The syntax of the argument is a comma-separated list of pattern=N, where pattern is a literal file name (minus the \".go\" suffix) or \"glob\" pattern and N is a log verbosity level.",
|
||||
Value: glog.GetVModule(),
|
||||
}
|
||||
VMDebugFlag = cli.BoolFlag{
|
||||
Name: "vmdebug",
|
||||
Usage: "Virtual Machine debug output",
|
||||
}
|
||||
BacktraceAtFlag = cli.GenericFlag{
|
||||
Name: "backtrace_at",
|
||||
Usage: "If set to a file and line number (e.g., \"block.go:271\") holding a logging statement, a stack trace will be logged",
|
||||
@ -305,12 +345,12 @@ var (
|
||||
GpoMinGasPriceFlag = cli.StringFlag{
|
||||
Name: "gpomin",
|
||||
Usage: "Minimum suggested gas price",
|
||||
Value: new(big.Int).Mul(big.NewInt(1), common.Szabo).String(),
|
||||
Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
|
||||
}
|
||||
GpoMaxGasPriceFlag = cli.StringFlag{
|
||||
Name: "gpomax",
|
||||
Usage: "Maximum suggested gas price",
|
||||
Value: new(big.Int).Mul(big.NewInt(100), common.Szabo).String(),
|
||||
Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(),
|
||||
}
|
||||
GpoFullBlockRatioFlag = cli.IntFlag{
|
||||
Name: "gpofull",
|
||||
@ -374,11 +414,13 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
|
||||
glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default")
|
||||
}
|
||||
|
||||
return ð.Config{
|
||||
cfg := ð.Config{
|
||||
Name: common.MakeName(clientID, version),
|
||||
DataDir: ctx.GlobalString(DataDirFlag.Name),
|
||||
GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name),
|
||||
GenesisFile: ctx.GlobalString(GenesisFileFlag.Name),
|
||||
BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name),
|
||||
DatabaseCache: ctx.GlobalInt(CacheFlag.Name),
|
||||
SkipBcVersionCheck: false,
|
||||
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
|
||||
LogFile: ctx.GlobalString(LogFileFlag.Name),
|
||||
@ -391,6 +433,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
|
||||
MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name),
|
||||
MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name),
|
||||
Port: ctx.GlobalString(ListenPortFlag.Name),
|
||||
Olympic: ctx.GlobalBool(OlympicFlag.Name),
|
||||
NAT: MakeNAT(ctx),
|
||||
NatSpec: ctx.GlobalBool(NatspecEnabledFlag.Name),
|
||||
Discovery: !ctx.GlobalBool(NoDiscoverFlag.Name),
|
||||
@ -408,6 +451,33 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
|
||||
SolcPath: ctx.GlobalString(SolcPathFlag.Name),
|
||||
AutoDAG: ctx.GlobalBool(AutoDAGFlag.Name) || ctx.GlobalBool(MiningEnabledFlag.Name),
|
||||
}
|
||||
|
||||
if ctx.GlobalBool(DevModeFlag.Name) {
|
||||
if !ctx.GlobalIsSet(VMDebugFlag.Name) {
|
||||
cfg.VmDebug = true
|
||||
}
|
||||
if !ctx.GlobalIsSet(MaxPeersFlag.Name) {
|
||||
cfg.MaxPeers = 0
|
||||
}
|
||||
if !ctx.GlobalIsSet(GasPriceFlag.Name) {
|
||||
cfg.GasPrice = new(big.Int)
|
||||
}
|
||||
if !ctx.GlobalIsSet(ListenPortFlag.Name) {
|
||||
cfg.Port = "0" // auto port
|
||||
}
|
||||
if !ctx.GlobalIsSet(WhisperEnabledFlag.Name) {
|
||||
cfg.Shh = true
|
||||
}
|
||||
if !ctx.GlobalIsSet(DataDirFlag.Name) {
|
||||
cfg.DataDir = os.TempDir() + "/ethereum_dev_mode"
|
||||
}
|
||||
cfg.PowTest = true
|
||||
cfg.DevMode = true
|
||||
|
||||
glog.V(logger.Info).Infoln("dev mode enabled")
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
// SetupLogger configures glog from the logging-related command line flags.
|
||||
@ -418,31 +488,53 @@ func SetupLogger(ctx *cli.Context) {
|
||||
glog.SetLogDir(ctx.GlobalString(LogFileFlag.Name))
|
||||
}
|
||||
|
||||
// SetupVM configured the VM package's global settings
|
||||
func SetupVM(ctx *cli.Context) {
|
||||
vm.EnableJit = ctx.GlobalBool(VMEnableJitFlag.Name)
|
||||
vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name)
|
||||
vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
|
||||
}
|
||||
|
||||
// SetupEth configures the eth packages global settings
|
||||
func SetupEth(ctx *cli.Context) {
|
||||
version := ctx.GlobalInt(EthVersionFlag.Name)
|
||||
for len(eth.ProtocolVersions) > 0 && eth.ProtocolVersions[0] > uint(version) {
|
||||
eth.ProtocolVersions = eth.ProtocolVersions[1:]
|
||||
eth.ProtocolLengths = eth.ProtocolLengths[1:]
|
||||
}
|
||||
if len(eth.ProtocolVersions) == 0 {
|
||||
Fatalf("No valid eth protocols remaining")
|
||||
}
|
||||
}
|
||||
|
||||
// MakeChain creates a chain manager from set command line flags.
|
||||
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) {
|
||||
dd := ctx.GlobalString(DataDirFlag.Name)
|
||||
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, chainDb ethdb.Database) {
|
||||
datadir := ctx.GlobalString(DataDirFlag.Name)
|
||||
cache := ctx.GlobalInt(CacheFlag.Name)
|
||||
|
||||
var err error
|
||||
if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "blockchain")); err != nil {
|
||||
if chainDb, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache); err != nil {
|
||||
Fatalf("Could not open database: %v", err)
|
||||
}
|
||||
if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "state")); err != nil {
|
||||
Fatalf("Could not open database: %v", err)
|
||||
}
|
||||
if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "extra")); err != nil {
|
||||
Fatalf("Could not open database: %v", err)
|
||||
if ctx.GlobalBool(OlympicFlag.Name) {
|
||||
InitOlympic()
|
||||
_, err := core.WriteTestNetGenesisBlock(chainDb, 42)
|
||||
if err != nil {
|
||||
glog.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
eventMux := new(event.TypeMux)
|
||||
pow := ethash.New()
|
||||
genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
|
||||
chain, err = core.NewChainManager(genesis, blockDB, stateDB, extraDB, pow, eventMux)
|
||||
//genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
|
||||
chain, err = core.NewChainManager(chainDb, pow, eventMux)
|
||||
if err != nil {
|
||||
Fatalf("Could not start chainmanager: %v", err)
|
||||
}
|
||||
|
||||
proc := core.NewBlockProcessor(stateDB, extraDB, pow, chain, eventMux)
|
||||
proc := core.NewBlockProcessor(chainDb, pow, chain, eventMux)
|
||||
chain.SetProcessor(proc)
|
||||
return chain, blockDB, stateDB, extraDB
|
||||
return chain, chainDb
|
||||
}
|
||||
|
||||
// MakeChain creates an account manager from set command line flags.
|
||||
@ -453,7 +545,7 @@ func MakeAccountManager(ctx *cli.Context) *accounts.Manager {
|
||||
}
|
||||
|
||||
func IpcSocketPath(ctx *cli.Context) (ipcpath string) {
|
||||
if common.IsWindows() {
|
||||
if runtime.GOOS == "windows" {
|
||||
ipcpath = common.DefaultIpcPath()
|
||||
if ctx.GlobalIsSet(IPCPathFlag.Name) {
|
||||
ipcpath = ctx.GlobalString(IPCPathFlag.Name)
|
||||
@ -476,15 +568,20 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
|
||||
Endpoint: IpcSocketPath(ctx),
|
||||
}
|
||||
|
||||
xeth := xeth.New(eth, nil)
|
||||
codec := codec.JSON
|
||||
initializer := func(conn net.Conn) (shared.EthereumApi, error) {
|
||||
fe := useragent.NewRemoteFrontend(conn, eth.AccountManager())
|
||||
xeth := xeth.New(eth, fe)
|
||||
codec := codec.JSON
|
||||
|
||||
apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
|
||||
if err != nil {
|
||||
return err
|
||||
apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return api.Merge(apis...), nil
|
||||
}
|
||||
|
||||
return comms.StartIpc(config, codec, api.Merge(apis...))
|
||||
return comms.StartIpc(config, codec.JSON, initializer)
|
||||
}
|
||||
|
||||
func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
|
||||
|
41
cmd/utils/legalese.go
Normal file
41
cmd/utils/legalese.go
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package utils
|
||||
|
||||
const (
|
||||
legalese = `
|
||||
=======================================
|
||||
Disclaimer of Liabilites and Warranties
|
||||
=======================================
|
||||
|
||||
THE USER EXPRESSLY KNOWS AND AGREES THAT THE USER IS USING THE ETHEREUM PLATFORM AT THE USER’S SOLE
|
||||
RISK. THE USER REPRESENTS THAT THE USER HAS AN ADEQUATE UNDERSTANDING OF THE RISKS, USAGE AND
|
||||
INTRICACIES OF CRYPTOGRAPHIC TOKENS AND BLOCKCHAIN-BASED OPEN SOURCE SOFTWARE, ETH PLATFORM AND ETH.
|
||||
THE USER ACKNOWLEDGES AND AGREES THAT, TO THE FULLEST EXTENT PERMITTED BY ANY APPLICABLE LAW, THE
|
||||
DISCLAIMERS OF LIABILITY CONTAINED HEREIN APPLY TO ANY AND ALL DAMAGES OR INJURY WHATSOEVER CAUSED
|
||||
BY OR RELATED TO RISKS OF, USE OF, OR INABILITY TO USE, ETH OR THE ETHEREUM PLATFORM UNDER ANY CAUSE
|
||||
OR ACTION WHATSOEVER OF ANY KIND IN ANY JURISDICTION, INCLUDING, WITHOUT LIMITATION, ACTIONS FOR
|
||||
BREACH OF WARRANTY, BREACH OF CONTRACT OR TORT (INCLUDING NEGLIGENCE) AND THAT NEITHER STIFTUNG
|
||||
ETHEREUM NOR ETHEREUM TEAM SHALL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
|
||||
CONSEQUENTIAL DAMAGES, INCLUDING FOR LOSS OF PROFITS, GOODWILL OR DATA. SOME JURISDICTIONS DO NOT
|
||||
ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN
|
||||
TYPES OF DAMAGES. THEREFORE, SOME OF THE ABOVE LIMITATIONS IN THIS SECTION MAY NOT APPLY TO A USER.
|
||||
IN PARTICULAR, NOTHING IN THESE TERMS SHALL AFFECT THE STATUTORY RIGHTS OF ANY USER OR EXCLUDE
|
||||
INJURY ARISING FROM ANY WILLFUL MISCONDUCT OR FRAUD OF STIFTUNG ETHEREUM.
|
||||
|
||||
Do you accept this agreement?`
|
||||
)
|
@ -1,49 +1,50 @@
|
||||
# ethutil
|
||||
# common
|
||||
|
||||
[](https://travis-ci.org/ethereum/go-ethereum)
|
||||
|
||||
The ethutil package contains the ethereum utility library.
|
||||
The common package contains the ethereum utility library.
|
||||
|
||||
# Installation
|
||||
|
||||
`go get github.com/ethereum/ethutil-go`
|
||||
As a subdirectory the main go-ethereum repository, you get it with
|
||||
`go get github.com/ethereum/go-ethereum`.
|
||||
|
||||
# Usage
|
||||
|
||||
## RLP (Recursive Linear Prefix) Encoding
|
||||
|
||||
RLP Encoding is an encoding scheme utilized by the Ethereum project. It
|
||||
encodes any native value or list to string.
|
||||
RLP Encoding is an encoding scheme used by the Ethereum project. It
|
||||
encodes any native value or list to a string.
|
||||
|
||||
More in depth information about the Encoding scheme see the [Wiki](http://wiki.ethereum.org/index.php/RLP)
|
||||
article.
|
||||
More in depth information about the encoding scheme see the
|
||||
[Wiki](http://wiki.ethereum.org/index.php/RLP) article.
|
||||
|
||||
```go
|
||||
rlp := ethutil.Encode("doge")
|
||||
rlp := common.Encode("doge")
|
||||
fmt.Printf("%q\n", rlp) // => "\0x83dog"
|
||||
|
||||
rlp = ethutil.Encode([]interface{}{"dog", "cat"})
|
||||
rlp = common.Encode([]interface{}{"dog", "cat"})
|
||||
fmt.Printf("%q\n", rlp) // => "\0xc8\0x83dog\0x83cat"
|
||||
decoded := ethutil.Decode(rlp)
|
||||
decoded := common.Decode(rlp)
|
||||
fmt.Println(decoded) // => ["dog" "cat"]
|
||||
```
|
||||
|
||||
## Patricia Trie
|
||||
|
||||
Patricie Tree is a merkle trie utilized by the Ethereum project.
|
||||
Patricie Tree is a merkle trie used by the Ethereum project.
|
||||
|
||||
More in depth information about the (modified) Patricia Trie can be
|
||||
found on the [Wiki](http://wiki.ethereum.org/index.php/Patricia_Tree).
|
||||
|
||||
The patricia trie uses a db as backend and could be anything as long as
|
||||
it satisfies the Database interface found in `ethutil/db.go`.
|
||||
it satisfies the Database interface found in `common/db.go`.
|
||||
|
||||
```go
|
||||
db := NewDatabase()
|
||||
|
||||
// db, root
|
||||
trie := ethutil.NewTrie(db, "")
|
||||
trie := common.NewTrie(db, "")
|
||||
|
||||
trie.Put("puppy", "dog")
|
||||
trie.Put("horse", "stallion")
|
||||
@ -65,7 +66,7 @@ all (key, value) bindings.
|
||||
// ... Create db/trie
|
||||
|
||||
// Note that RLP uses interface slices as list
|
||||
value := ethutil.Encode([]interface{}{"one", 2, "three", []interface{}{42}})
|
||||
value := common.Encode([]interface{}{"one", 2, "three", []interface{}{42}})
|
||||
// Store the RLP encoded value of the list
|
||||
trie.Put("mykey", value)
|
||||
```
|
||||
@ -89,7 +90,7 @@ type (e.g. `Slice()` returns []interface{}, `Uint()` return 0, etc).
|
||||
`Append(v)` appends the value (v) to the current value/list.
|
||||
|
||||
```go
|
||||
val := ethutil.NewEmptyValue().Append(1).Append("2")
|
||||
val := common.NewEmptyValue().Append(1).Append("2")
|
||||
val.AppendList().Append(3)
|
||||
```
|
||||
|
||||
@ -110,7 +111,7 @@ val.AppendList().Append(3)
|
||||
`Byte()` returns the value as a single byte.
|
||||
|
||||
```go
|
||||
val := ethutil.NewValue([]interface{}{1,"2",[]interface{}{3}})
|
||||
val := common.NewValue([]interface{}{1,"2",[]interface{}{3}})
|
||||
val.Get(0).Uint() // => 1
|
||||
val.Get(1).Str() // => "2"
|
||||
s := val.Get(2) // => Value([]interface{}{3})
|
||||
@ -122,7 +123,7 @@ s.Get(0).Uint() // => 3
|
||||
Decoding streams of RLP data is simplified
|
||||
|
||||
```go
|
||||
val := ethutil.NewValueFromBytes(rlpData)
|
||||
val := common.NewValueFromBytes(rlpData)
|
||||
val.Get(0).Uint()
|
||||
```
|
||||
|
||||
@ -132,7 +133,7 @@ Encoding from Value to RLP is done with the `Encode` method. The
|
||||
underlying value can be anything RLP can encode (int, str, lists, bytes)
|
||||
|
||||
```go
|
||||
val := ethutil.NewValue([]interface{}{1,"2",[]interface{}{3}})
|
||||
val := common.NewValue([]interface{}{1,"2",[]interface{}{3}})
|
||||
rlp := val.Encode()
|
||||
// Store the rlp data
|
||||
Store(rlp)
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2014 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package common
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2014 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package common
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2014 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package common contains various helper functions.
|
||||
package common
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2014 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package common
|
||||
|
||||
|
@ -1,24 +1,25 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -33,15 +34,10 @@ import (
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
// flair = "Christian <c@ethdev.com> and Lefteris <lefteris@ethdev.com> (c) 2014-2015"
|
||||
flair = ""
|
||||
languageVersion = "0"
|
||||
)
|
||||
|
||||
var (
|
||||
versionRegExp = regexp.MustCompile("[0-9]+.[0-9]+.[0-9]+")
|
||||
params = []string{
|
||||
versionRegexp = regexp.MustCompile("[0-9]+\\.[0-9]+\\.[0-9]+")
|
||||
legacyRegexp = regexp.MustCompile("0\\.(9\\..*|1\\.[01])")
|
||||
paramsLegacy = []string{
|
||||
"--binary", // Request to output the contract in binary (hexadecimal).
|
||||
"file", //
|
||||
"--json-abi", // Request to output the contract's JSON ABI interface.
|
||||
@ -53,6 +49,15 @@ var (
|
||||
"--add-std",
|
||||
"1",
|
||||
}
|
||||
paramsNew = []string{
|
||||
"--bin", // Request to output the contract in binary (hexadecimal).
|
||||
"--abi", // Request to output the contract's JSON ABI interface.
|
||||
"--userdoc", // Request to output the contract's Natspec user documentation.
|
||||
"--devdoc", // Request to output the contract's Natspec developer documentation.
|
||||
"--add-std", // include standard lib contracts
|
||||
"--optimize", // code optimizer switched on
|
||||
"-o", // output directory
|
||||
}
|
||||
)
|
||||
|
||||
type Contract struct {
|
||||
@ -65,14 +70,17 @@ type ContractInfo struct {
|
||||
Language string `json:"language"`
|
||||
LanguageVersion string `json:"languageVersion"`
|
||||
CompilerVersion string `json:"compilerVersion"`
|
||||
CompilerOptions string `json:"compilerOptions"`
|
||||
AbiDefinition interface{} `json:"abiDefinition"`
|
||||
UserDoc interface{} `json:"userDoc"`
|
||||
DeveloperDoc interface{} `json:"developerDoc"`
|
||||
}
|
||||
|
||||
type Solidity struct {
|
||||
solcPath string
|
||||
version string
|
||||
solcPath string
|
||||
version string
|
||||
fullVersion string
|
||||
legacy bool
|
||||
}
|
||||
|
||||
func New(solcPath string) (sol *Solidity, err error) {
|
||||
@ -93,112 +101,118 @@ func New(solcPath string) (sol *Solidity, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
version := versionRegExp.FindString(out.String())
|
||||
fullVersion := out.String()
|
||||
version := versionRegexp.FindString(fullVersion)
|
||||
legacy := legacyRegexp.MatchString(version)
|
||||
|
||||
sol = &Solidity{
|
||||
solcPath: solcPath,
|
||||
version: version,
|
||||
solcPath: solcPath,
|
||||
version: version,
|
||||
fullVersion: fullVersion,
|
||||
legacy: legacy,
|
||||
}
|
||||
glog.V(logger.Info).Infoln(sol.Info())
|
||||
return
|
||||
}
|
||||
|
||||
func (sol *Solidity) Info() string {
|
||||
return fmt.Sprintf("solc v%s\nSolidity Compiler: %s\n%s", sol.version, sol.solcPath, flair)
|
||||
return fmt.Sprintf("%s\npath: %s", sol.fullVersion, sol.solcPath)
|
||||
}
|
||||
|
||||
func (sol *Solidity) Version() string {
|
||||
return sol.version
|
||||
}
|
||||
|
||||
func (sol *Solidity) Compile(source string) (contracts map[string]*Contract, err error) {
|
||||
|
||||
// Compile builds and returns all the contracts contained within a source string.
|
||||
func (sol *Solidity) Compile(source string) (map[string]*Contract, error) {
|
||||
// Short circuit if no source code was specified
|
||||
if len(source) == 0 {
|
||||
err = fmt.Errorf("empty source")
|
||||
return
|
||||
return nil, errors.New("solc: empty source string")
|
||||
}
|
||||
|
||||
// Create a safe place to dump compilation output
|
||||
wd, err := ioutil.TempDir("", "solc")
|
||||
if err != nil {
|
||||
return
|
||||
return nil, fmt.Errorf("solc: failed to create temporary build folder: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(wd)
|
||||
|
||||
in := strings.NewReader(source)
|
||||
var out bytes.Buffer
|
||||
// cwd set to temp dir
|
||||
// Assemble the compiler command, change to the temp folder and capture any errors
|
||||
stderr := new(bytes.Buffer)
|
||||
|
||||
var params []string
|
||||
if sol.legacy {
|
||||
params = paramsLegacy
|
||||
} else {
|
||||
params = paramsNew
|
||||
params = append(params, wd)
|
||||
}
|
||||
compilerOptions := strings.Join(params, " ")
|
||||
|
||||
cmd := exec.Command(sol.solcPath, params...)
|
||||
cmd.Dir = wd
|
||||
cmd.Stdin = in
|
||||
cmd.Stdout = &out
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("solc error: %v", err)
|
||||
return
|
||||
}
|
||||
cmd.Stdin = strings.NewReader(source)
|
||||
cmd.Stderr = stderr
|
||||
|
||||
matches, _ := filepath.Glob(wd + "/*.binary")
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf("solc: %v\n%s", err, string(stderr.Bytes()))
|
||||
}
|
||||
// Sanity check that something was actually built
|
||||
matches, _ := filepath.Glob(wd + "/*\\.bin*")
|
||||
if len(matches) < 1 {
|
||||
err = fmt.Errorf("solc error: missing code output")
|
||||
return
|
||||
return nil, fmt.Errorf("solc: no build results found")
|
||||
}
|
||||
|
||||
contracts = make(map[string]*Contract)
|
||||
// Compilation succeeded, assemble and return the contracts
|
||||
contracts := make(map[string]*Contract)
|
||||
for _, path := range matches {
|
||||
_, file := filepath.Split(path)
|
||||
base := strings.Split(file, ".")[0]
|
||||
|
||||
codeFile := filepath.Join(wd, base+".binary")
|
||||
abiDefinitionFile := filepath.Join(wd, base+".abi")
|
||||
userDocFile := filepath.Join(wd, base+".docuser")
|
||||
developerDocFile := filepath.Join(wd, base+".docdev")
|
||||
|
||||
var code, abiDefinitionJson, userDocJson, developerDocJson []byte
|
||||
code, err = ioutil.ReadFile(codeFile)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error reading compiler output for code: %v", err)
|
||||
return
|
||||
// Parse the individual compilation results (code binary, ABI definitions, user and dev docs)
|
||||
var binary []byte
|
||||
binext := ".bin"
|
||||
if sol.legacy {
|
||||
binext = ".binary"
|
||||
}
|
||||
abiDefinitionJson, err = ioutil.ReadFile(abiDefinitionFile)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error reading compiler output for abiDefinition: %v", err)
|
||||
return
|
||||
if binary, err = ioutil.ReadFile(filepath.Join(wd, base+binext)); err != nil {
|
||||
return nil, fmt.Errorf("solc: error reading compiler output for code: %v", err)
|
||||
}
|
||||
var abiDefinition interface{}
|
||||
err = json.Unmarshal(abiDefinitionJson, &abiDefinition)
|
||||
|
||||
userDocJson, err = ioutil.ReadFile(userDocFile)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error reading compiler output for userDoc: %v", err)
|
||||
return
|
||||
var abi interface{}
|
||||
if blob, err := ioutil.ReadFile(filepath.Join(wd, base+".abi")); err != nil {
|
||||
return nil, fmt.Errorf("solc: error reading abi definition: %v", err)
|
||||
} else if err = json.Unmarshal(blob, &abi); err != nil {
|
||||
return nil, fmt.Errorf("solc: error parsing abi definition: %v", err)
|
||||
}
|
||||
var userDoc interface{}
|
||||
err = json.Unmarshal(userDocJson, &userDoc)
|
||||
|
||||
developerDocJson, err = ioutil.ReadFile(developerDocFile)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error reading compiler output for developerDoc: %v", err)
|
||||
return
|
||||
var userdoc interface{}
|
||||
if blob, err := ioutil.ReadFile(filepath.Join(wd, base+".docuser")); err != nil {
|
||||
return nil, fmt.Errorf("solc: error reading user doc: %v", err)
|
||||
} else if err = json.Unmarshal(blob, &userdoc); err != nil {
|
||||
return nil, fmt.Errorf("solc: error parsing user doc: %v", err)
|
||||
}
|
||||
var developerDoc interface{}
|
||||
err = json.Unmarshal(developerDocJson, &developerDoc)
|
||||
|
||||
contract := &Contract{
|
||||
Code: "0x" + string(code),
|
||||
var devdoc interface{}
|
||||
if blob, err := ioutil.ReadFile(filepath.Join(wd, base+".docdev")); err != nil {
|
||||
return nil, fmt.Errorf("solc: error reading dev doc: %v", err)
|
||||
} else if err = json.Unmarshal(blob, &devdoc); err != nil {
|
||||
return nil, fmt.Errorf("solc: error parsing dev doc: %v", err)
|
||||
}
|
||||
// Assemble the final contract
|
||||
contracts[base] = &Contract{
|
||||
Code: "0x" + string(binary),
|
||||
Info: ContractInfo{
|
||||
Source: source,
|
||||
Language: "Solidity",
|
||||
LanguageVersion: languageVersion,
|
||||
LanguageVersion: sol.version,
|
||||
CompilerVersion: sol.version,
|
||||
AbiDefinition: abiDefinition,
|
||||
UserDoc: userDoc,
|
||||
DeveloperDoc: developerDoc,
|
||||
CompilerOptions: compilerOptions,
|
||||
AbiDefinition: abi,
|
||||
UserDoc: userdoc,
|
||||
DeveloperDoc: devdoc,
|
||||
},
|
||||
}
|
||||
|
||||
contracts[base] = contract
|
||||
}
|
||||
|
||||
return
|
||||
return contracts, nil
|
||||
}
|
||||
|
||||
func SaveInfo(info *ContractInfo, filename string) (contenthash common.Hash, err error) {
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package compiler
|
||||
|
||||
@ -20,12 +20,13 @@ import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
const solcVersion = "0.9.23"
|
||||
const solcVersion = "0.1.1"
|
||||
|
||||
var (
|
||||
source = `
|
||||
@ -36,18 +37,18 @@ contract test {
|
||||
}
|
||||
}
|
||||
`
|
||||
code = "0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"
|
||||
info = `{"source":"\ncontract test {\n /// @notice Will multiply ` + "`a`" + ` by 7.\n function multiply(uint a) returns(uint d) {\n return a * 7;\n }\n}\n","language":"Solidity","languageVersion":"0","compilerVersion":"0.9.23","abiDefinition":[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}],"userDoc":{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}},"developerDoc":{"methods":{}}}`
|
||||
code = "0x6060604052606d8060116000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa1146037576035565b005b6046600480359060200150605c565b6040518082815260200191505060405180910390f35b60006007820290506068565b91905056"
|
||||
info = `{"source":"\ncontract test {\n /// @notice Will multiply ` + "`a`" + ` by 7.\n function multiply(uint a) returns(uint d) {\n return a * 7;\n }\n}\n","language":"Solidity","languageVersion":"0.1.1","compilerVersion":"0.1.1","compilerOptions":"--binary file --json-abi file --natspec-user file --natspec-dev file --add-std 1","abiDefinition":[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}],"userDoc":{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}},"developerDoc":{"methods":{}}}`
|
||||
|
||||
infohash = common.HexToHash("0xea782f674eb898e477c20e8a7cf11c2c28b09fa68b5278732104f7a101aed255")
|
||||
infohash = common.HexToHash("0x9f3803735e7f16120c5a140ab3f02121fd3533a9655c69b33a10e78752cc49b0")
|
||||
)
|
||||
|
||||
func TestCompiler(t *testing.T) {
|
||||
sol, err := New("")
|
||||
if err != nil {
|
||||
t.Skip("solc not found: skip")
|
||||
t.Skipf("solc not found: %v", err)
|
||||
} else if sol.Version() != solcVersion {
|
||||
t.Skip("WARNING: skipping due to a newer version of solc found (%v, expect %v)", sol.Version(), solcVersion)
|
||||
t.Skipf("WARNING: a newer version of solc found (%v, expect %v)", sol.Version(), solcVersion)
|
||||
}
|
||||
contracts, err := sol.Compile(source)
|
||||
if err != nil {
|
||||
@ -82,7 +83,7 @@ func TestCompileError(t *testing.T) {
|
||||
func TestNoCompiler(t *testing.T) {
|
||||
_, err := New("/path/to/solc")
|
||||
if err != nil {
|
||||
t.Log("solidity quits with error: %v", err)
|
||||
t.Logf("solidity quits with error: %v", err)
|
||||
} else {
|
||||
t.Errorf("no solc installed, but got no error")
|
||||
}
|
||||
@ -94,7 +95,7 @@ func TestSaveInfo(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
filename := "/tmp/solctest.info.json"
|
||||
filename := path.Join(os.TempDir(), "solctest.info.json")
|
||||
os.Remove(filename)
|
||||
cinfohash, err := SaveInfo(&cinfo, filename)
|
||||
if err != nil {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user