mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-23 00:46:30 +00:00
adding flag package to deps
This commit is contained in:
parent
0b98eb4186
commit
e28930f997
61 changed files with 2171 additions and 7492 deletions
17
Godeps/Godeps.json
generated
17
Godeps/Godeps.json
generated
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/drone/drone",
|
"ImportPath": "github.com/drone/drone",
|
||||||
"GoVersion": "go1.4.2",
|
"GoVersion": "go1.3.1",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"github.com/drone/drone..."
|
"./..."
|
||||||
],
|
],
|
||||||
"Deps": [
|
"Deps": [
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,11 @@
|
||||||
"Comment": "v2.2.0-16-gc48cfd5",
|
"Comment": "v2.2.0-16-gc48cfd5",
|
||||||
"Rev": "c48cfd5d9711c75acb6036d2698ef3aef7bb655a"
|
"Rev": "c48cfd5d9711c75acb6036d2698ef3aef7bb655a"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/docker/docker/pkg/units",
|
||||||
|
"Comment": "v1.4.1-4375-g9356c76",
|
||||||
|
"Rev": "9356c76d9f6e285e71f04df33ef7870455a42775"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/elazarl/go-bindata-assetfs",
|
"ImportPath": "github.com/elazarl/go-bindata-assetfs",
|
||||||
"Rev": "bea323321994103859d60197d229f1a94699dde3"
|
"Rev": "bea323321994103859d60197d229f1a94699dde3"
|
||||||
|
@ -76,12 +81,8 @@
|
||||||
"Rev": "542ae647f8601bafd96233961b150cae198e0295"
|
"Rev": "542ae647f8601bafd96233961b150cae198e0295"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/naoina/go-stringutil",
|
"ImportPath": "github.com/namsral/flag",
|
||||||
"Rev": "360db0db4b01d34e12a2ec042c09e7d37fece761"
|
"Rev": "881a43080604bcf99ab1118a814d1cb2c268fc36"
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/naoina/toml",
|
|
||||||
"Rev": "7b2dffbeaee47506726f29e36d19cf4ee90d361b"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/russross/meddler",
|
"ImportPath": "github.com/russross/meddler",
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/gitlab_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/gitlab_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/hook_payload_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/hook_payload_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/hooks_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/hooks_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/projects_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/projects_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/public_keys_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/public_keys_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/repositories_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/repositories_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/session_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/session_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/users_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/users_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/util_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client/util_test.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
package gogitlab
|
package gogitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
31
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go
generated
vendored
Normal file
31
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package units
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HumanDuration returns a human-readable approximation of a duration
|
||||||
|
// (eg. "About a minute", "4 hours ago", etc.)
|
||||||
|
func HumanDuration(d time.Duration) string {
|
||||||
|
if seconds := int(d.Seconds()); seconds < 1 {
|
||||||
|
return "Less than a second"
|
||||||
|
} else if seconds < 60 {
|
||||||
|
return fmt.Sprintf("%d seconds", seconds)
|
||||||
|
} else if minutes := int(d.Minutes()); minutes == 1 {
|
||||||
|
return "About a minute"
|
||||||
|
} else if minutes < 60 {
|
||||||
|
return fmt.Sprintf("%d minutes", minutes)
|
||||||
|
} else if hours := int(d.Hours()); hours == 1 {
|
||||||
|
return "About an hour"
|
||||||
|
} else if hours < 48 {
|
||||||
|
return fmt.Sprintf("%d hours", hours)
|
||||||
|
} else if hours < 24*7*2 {
|
||||||
|
return fmt.Sprintf("%d days", hours/24)
|
||||||
|
} else if hours < 24*30*3 {
|
||||||
|
return fmt.Sprintf("%d weeks", hours/24/7)
|
||||||
|
} else if hours < 24*365*2 {
|
||||||
|
return fmt.Sprintf("%d months", hours/24/30)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d years", int(d.Hours())/24/365)
|
||||||
|
}
|
46
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go
generated
vendored
Normal file
46
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package units
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHumanDuration(t *testing.T) {
|
||||||
|
// Useful duration abstractions
|
||||||
|
day := 24 * time.Hour
|
||||||
|
week := 7 * day
|
||||||
|
month := 30 * day
|
||||||
|
year := 365 * day
|
||||||
|
|
||||||
|
assertEquals(t, "Less than a second", HumanDuration(450*time.Millisecond))
|
||||||
|
assertEquals(t, "47 seconds", HumanDuration(47*time.Second))
|
||||||
|
assertEquals(t, "About a minute", HumanDuration(1*time.Minute))
|
||||||
|
assertEquals(t, "3 minutes", HumanDuration(3*time.Minute))
|
||||||
|
assertEquals(t, "35 minutes", HumanDuration(35*time.Minute))
|
||||||
|
assertEquals(t, "35 minutes", HumanDuration(35*time.Minute+40*time.Second))
|
||||||
|
assertEquals(t, "About an hour", HumanDuration(1*time.Hour))
|
||||||
|
assertEquals(t, "About an hour", HumanDuration(1*time.Hour+45*time.Minute))
|
||||||
|
assertEquals(t, "3 hours", HumanDuration(3*time.Hour))
|
||||||
|
assertEquals(t, "3 hours", HumanDuration(3*time.Hour+59*time.Minute))
|
||||||
|
assertEquals(t, "4 hours", HumanDuration(3*time.Hour+60*time.Minute))
|
||||||
|
assertEquals(t, "24 hours", HumanDuration(24*time.Hour))
|
||||||
|
assertEquals(t, "36 hours", HumanDuration(1*day+12*time.Hour))
|
||||||
|
assertEquals(t, "2 days", HumanDuration(2*day))
|
||||||
|
assertEquals(t, "7 days", HumanDuration(7*day))
|
||||||
|
assertEquals(t, "13 days", HumanDuration(13*day+5*time.Hour))
|
||||||
|
assertEquals(t, "2 weeks", HumanDuration(2*week))
|
||||||
|
assertEquals(t, "2 weeks", HumanDuration(2*week+4*day))
|
||||||
|
assertEquals(t, "3 weeks", HumanDuration(3*week))
|
||||||
|
assertEquals(t, "4 weeks", HumanDuration(4*week))
|
||||||
|
assertEquals(t, "4 weeks", HumanDuration(4*week+3*day))
|
||||||
|
assertEquals(t, "4 weeks", HumanDuration(1*month))
|
||||||
|
assertEquals(t, "6 weeks", HumanDuration(1*month+2*week))
|
||||||
|
assertEquals(t, "8 weeks", HumanDuration(2*month))
|
||||||
|
assertEquals(t, "3 months", HumanDuration(3*month+1*week))
|
||||||
|
assertEquals(t, "5 months", HumanDuration(5*month+2*week))
|
||||||
|
assertEquals(t, "13 months", HumanDuration(13*month))
|
||||||
|
assertEquals(t, "23 months", HumanDuration(23*month))
|
||||||
|
assertEquals(t, "24 months", HumanDuration(24*month))
|
||||||
|
assertEquals(t, "2 years", HumanDuration(24*month+2*week))
|
||||||
|
assertEquals(t, "3 years", HumanDuration(3*year+2*month))
|
||||||
|
}
|
93
Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go
generated
vendored
Normal file
93
Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
package units
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// See: http://en.wikipedia.org/wiki/Binary_prefix
|
||||||
|
const (
|
||||||
|
// Decimal
|
||||||
|
|
||||||
|
KB = 1000
|
||||||
|
MB = 1000 * KB
|
||||||
|
GB = 1000 * MB
|
||||||
|
TB = 1000 * GB
|
||||||
|
PB = 1000 * TB
|
||||||
|
|
||||||
|
// Binary
|
||||||
|
|
||||||
|
KiB = 1024
|
||||||
|
MiB = 1024 * KiB
|
||||||
|
GiB = 1024 * MiB
|
||||||
|
TiB = 1024 * GiB
|
||||||
|
PiB = 1024 * TiB
|
||||||
|
)
|
||||||
|
|
||||||
|
type unitMap map[string]int64
|
||||||
|
|
||||||
|
var (
|
||||||
|
decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB}
|
||||||
|
binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB}
|
||||||
|
sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
|
||||||
|
var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
|
||||||
|
|
||||||
|
// CustomSize returns a human-readable approximation of a size
|
||||||
|
// using custom format
|
||||||
|
func CustomSize(format string, size float64, base float64, _map []string) string {
|
||||||
|
i := 0
|
||||||
|
for size >= base {
|
||||||
|
size = size / base
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(format, size, _map[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// HumanSize returns a human-readable approximation of a size
|
||||||
|
// using SI standard (eg. "44kB", "17MB")
|
||||||
|
func HumanSize(size float64) string {
|
||||||
|
return CustomSize("%.4g %s", size, 1000.0, decimapAbbrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BytesSize(size float64) string {
|
||||||
|
return CustomSize("%.4g %s", size, 1024.0, binaryAbbrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromHumanSize returns an integer from a human-readable specification of a
|
||||||
|
// size using SI standard (eg. "44kB", "17MB")
|
||||||
|
func FromHumanSize(size string) (int64, error) {
|
||||||
|
return parseSize(size, decimalMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAMInBytes parses a human-readable string representing an amount of RAM
|
||||||
|
// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and
|
||||||
|
// returns the number of bytes, or -1 if the string is unparseable.
|
||||||
|
// Units are case-insensitive, and the 'b' suffix is optional.
|
||||||
|
func RAMInBytes(size string) (int64, error) {
|
||||||
|
return parseSize(size, binaryMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses the human-readable size string into the amount it represents
|
||||||
|
func parseSize(sizeStr string, uMap unitMap) (int64, error) {
|
||||||
|
matches := sizeRegex.FindStringSubmatch(sizeStr)
|
||||||
|
if len(matches) != 3 {
|
||||||
|
return -1, fmt.Errorf("invalid size: '%s'", sizeStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
size, err := strconv.ParseInt(matches[1], 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
unitPrefix := strings.ToLower(matches[2])
|
||||||
|
if mul, ok := uMap[unitPrefix]; ok {
|
||||||
|
size *= mul
|
||||||
|
}
|
||||||
|
|
||||||
|
return size, nil
|
||||||
|
}
|
108
Godeps/_workspace/src/github.com/docker/docker/pkg/units/size_test.go
generated
vendored
Normal file
108
Godeps/_workspace/src/github.com/docker/docker/pkg/units/size_test.go
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
package units
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBytesSize(t *testing.T) {
|
||||||
|
assertEquals(t, "1 KiB", BytesSize(1024))
|
||||||
|
assertEquals(t, "1 MiB", BytesSize(1024*1024))
|
||||||
|
assertEquals(t, "1 MiB", BytesSize(1048576))
|
||||||
|
assertEquals(t, "2 MiB", BytesSize(2*MiB))
|
||||||
|
assertEquals(t, "3.42 GiB", BytesSize(3.42*GiB))
|
||||||
|
assertEquals(t, "5.372 TiB", BytesSize(5.372*TiB))
|
||||||
|
assertEquals(t, "2.22 PiB", BytesSize(2.22*PiB))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHumanSize(t *testing.T) {
|
||||||
|
assertEquals(t, "1 kB", HumanSize(1000))
|
||||||
|
assertEquals(t, "1.024 kB", HumanSize(1024))
|
||||||
|
assertEquals(t, "1 MB", HumanSize(1000000))
|
||||||
|
assertEquals(t, "1.049 MB", HumanSize(1048576))
|
||||||
|
assertEquals(t, "2 MB", HumanSize(2*MB))
|
||||||
|
assertEquals(t, "3.42 GB", HumanSize(float64(3.42*GB)))
|
||||||
|
assertEquals(t, "5.372 TB", HumanSize(float64(5.372*TB)))
|
||||||
|
assertEquals(t, "2.22 PB", HumanSize(float64(2.22*PB)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFromHumanSize(t *testing.T) {
|
||||||
|
assertSuccessEquals(t, 32, FromHumanSize, "32")
|
||||||
|
assertSuccessEquals(t, 32, FromHumanSize, "32b")
|
||||||
|
assertSuccessEquals(t, 32, FromHumanSize, "32B")
|
||||||
|
assertSuccessEquals(t, 32*KB, FromHumanSize, "32k")
|
||||||
|
assertSuccessEquals(t, 32*KB, FromHumanSize, "32K")
|
||||||
|
assertSuccessEquals(t, 32*KB, FromHumanSize, "32kb")
|
||||||
|
assertSuccessEquals(t, 32*KB, FromHumanSize, "32Kb")
|
||||||
|
assertSuccessEquals(t, 32*MB, FromHumanSize, "32Mb")
|
||||||
|
assertSuccessEquals(t, 32*GB, FromHumanSize, "32Gb")
|
||||||
|
assertSuccessEquals(t, 32*TB, FromHumanSize, "32Tb")
|
||||||
|
assertSuccessEquals(t, 32*PB, FromHumanSize, "32Pb")
|
||||||
|
|
||||||
|
assertError(t, FromHumanSize, "")
|
||||||
|
assertError(t, FromHumanSize, "hello")
|
||||||
|
assertError(t, FromHumanSize, "-32")
|
||||||
|
assertError(t, FromHumanSize, "32.3")
|
||||||
|
assertError(t, FromHumanSize, " 32 ")
|
||||||
|
assertError(t, FromHumanSize, "32.3Kb")
|
||||||
|
assertError(t, FromHumanSize, "32 mb")
|
||||||
|
assertError(t, FromHumanSize, "32m b")
|
||||||
|
assertError(t, FromHumanSize, "32bm")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRAMInBytes(t *testing.T) {
|
||||||
|
assertSuccessEquals(t, 32, RAMInBytes, "32")
|
||||||
|
assertSuccessEquals(t, 32, RAMInBytes, "32b")
|
||||||
|
assertSuccessEquals(t, 32, RAMInBytes, "32B")
|
||||||
|
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32k")
|
||||||
|
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32K")
|
||||||
|
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32kb")
|
||||||
|
assertSuccessEquals(t, 32*KiB, RAMInBytes, "32Kb")
|
||||||
|
assertSuccessEquals(t, 32*MiB, RAMInBytes, "32Mb")
|
||||||
|
assertSuccessEquals(t, 32*GiB, RAMInBytes, "32Gb")
|
||||||
|
assertSuccessEquals(t, 32*TiB, RAMInBytes, "32Tb")
|
||||||
|
assertSuccessEquals(t, 32*PiB, RAMInBytes, "32Pb")
|
||||||
|
assertSuccessEquals(t, 32*PiB, RAMInBytes, "32PB")
|
||||||
|
assertSuccessEquals(t, 32*PiB, RAMInBytes, "32P")
|
||||||
|
|
||||||
|
assertError(t, RAMInBytes, "")
|
||||||
|
assertError(t, RAMInBytes, "hello")
|
||||||
|
assertError(t, RAMInBytes, "-32")
|
||||||
|
assertError(t, RAMInBytes, "32.3")
|
||||||
|
assertError(t, RAMInBytes, " 32 ")
|
||||||
|
assertError(t, RAMInBytes, "32.3Kb")
|
||||||
|
assertError(t, RAMInBytes, "32 mb")
|
||||||
|
assertError(t, RAMInBytes, "32m b")
|
||||||
|
assertError(t, RAMInBytes, "32bm")
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertEquals(t *testing.T, expected, actual interface{}) {
|
||||||
|
if expected != actual {
|
||||||
|
t.Errorf("Expected '%v' but got '%v'", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func that maps to the parse function signatures as testing abstraction
|
||||||
|
type parseFn func(string) (int64, error)
|
||||||
|
|
||||||
|
// Define 'String()' for pretty-print
|
||||||
|
func (fn parseFn) String() string {
|
||||||
|
fnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
|
||||||
|
return fnName[strings.LastIndex(fnName, ".")+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertSuccessEquals(t *testing.T, expected int64, fn parseFn, arg string) {
|
||||||
|
res, err := fn(arg)
|
||||||
|
if err != nil || res != expected {
|
||||||
|
t.Errorf("%s(\"%s\") -> expected '%d' but got '%d' with error '%v'", fn, arg, expected, res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertError(t *testing.T, fn parseFn, arg string) {
|
||||||
|
res, err := fn(arg)
|
||||||
|
if err == nil && res != -1 {
|
||||||
|
t.Errorf("%s(\"%s\") -> expected error but got '%d'", fn, arg, res)
|
||||||
|
}
|
||||||
|
}
|
7
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/README.md
generated
vendored
7
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/README.md
generated
vendored
|
@ -1,7 +0,0 @@
|
||||||
# Guide to run Gin under App Engine LOCAL Development Server
|
|
||||||
|
|
||||||
1. Download, install and setup Go in your computer. (That includes setting your `$GOPATH`.)
|
|
||||||
2. Download SDK for your platform from here: `https://developers.google.com/appengine/downloads?hl=es#Google_App_Engine_SDK_for_Go`
|
|
||||||
3. Download Gin source code using: `$ go get github.com/gin-gonic/gin`
|
|
||||||
4. Navigate to examples folder: `$ cd $GOPATH/src/github.com/gin-gonic/gin/examples/`
|
|
||||||
5. Run it: `$ goapp serve app-engine/`
|
|
8
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/app.yaml
generated
vendored
8
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/app.yaml
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
application: hello
|
|
||||||
version: 1
|
|
||||||
runtime: go
|
|
||||||
api_version: go1
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- url: /.*
|
|
||||||
script: _go_app
|
|
23
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/hello.go
generated
vendored
23
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/hello.go
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
package hello
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This function's name is a must. App Engine uses it to drive the requests properly.
|
|
||||||
func init() {
|
|
||||||
// Starts a new Gin instance with no middle-ware
|
|
||||||
r := gin.New()
|
|
||||||
|
|
||||||
// Define your handlers
|
|
||||||
r.GET("/", func(c *gin.Context) {
|
|
||||||
c.String(200, "Hello World!")
|
|
||||||
})
|
|
||||||
r.GET("/ping", func(c *gin.Context) {
|
|
||||||
c.String(200, "pong")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Handle all requests using net/http
|
|
||||||
http.Handle("/", r)
|
|
||||||
}
|
|
56
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/example_basic.go
generated
vendored
56
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/example_basic.go
generated
vendored
|
@ -1,56 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DB = make(map[string]string)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := gin.Default()
|
|
||||||
|
|
||||||
// Ping test
|
|
||||||
r.GET("/ping", func(c *gin.Context) {
|
|
||||||
c.String(200, "pong")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Get user value
|
|
||||||
r.GET("/user/:name", func(c *gin.Context) {
|
|
||||||
user := c.Params.ByName("name")
|
|
||||||
value, ok := DB[user]
|
|
||||||
if ok {
|
|
||||||
c.JSON(200, gin.H{"user": user, "value": value})
|
|
||||||
} else {
|
|
||||||
c.JSON(200, gin.H{"user": user, "status": "no value"})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Authorized group (uses gin.BasicAuth() middleware)
|
|
||||||
// Same than:
|
|
||||||
// authorized := r.Group("/")
|
|
||||||
// authorized.Use(gin.BasicAuth(gin.Credentials{
|
|
||||||
// "foo": "bar",
|
|
||||||
// "manu": "123",
|
|
||||||
//}))
|
|
||||||
authorized := r.Group("/", gin.BasicAuth(gin.Accounts{
|
|
||||||
"foo": "bar", // user:foo password:bar
|
|
||||||
"manu": "123", // user:manu password:123
|
|
||||||
}))
|
|
||||||
|
|
||||||
authorized.POST("admin", func(c *gin.Context) {
|
|
||||||
user := c.MustGet(gin.AuthUserKey).(string)
|
|
||||||
|
|
||||||
// Parse JSON
|
|
||||||
var json struct {
|
|
||||||
Value string `json:"value" binding:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Bind(&json) {
|
|
||||||
DB[user] = json.Value
|
|
||||||
c.JSON(200, gin.H{"status": "ok"})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Listen and Server in 0.0.0.0:8080
|
|
||||||
r.Run(":8080")
|
|
||||||
}
|
|
39
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/main.go
generated
vendored
39
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/main.go
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
ConfigRuntime()
|
|
||||||
StartWorkers()
|
|
||||||
StartGin()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConfigRuntime() {
|
|
||||||
nuCPU := runtime.NumCPU()
|
|
||||||
runtime.GOMAXPROCS(nuCPU)
|
|
||||||
fmt.Printf("Running with %d CPUs\n", nuCPU)
|
|
||||||
}
|
|
||||||
|
|
||||||
func StartWorkers() {
|
|
||||||
go statsWorker()
|
|
||||||
}
|
|
||||||
|
|
||||||
func StartGin() {
|
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
|
|
||||||
router := gin.New()
|
|
||||||
router.Use(rateLimit, gin.Recovery())
|
|
||||||
router.LoadHTMLGlob("resources/*.templ.html")
|
|
||||||
router.Static("/static", "resources/static")
|
|
||||||
router.GET("/", index)
|
|
||||||
router.GET("/room/:roomid", roomGET)
|
|
||||||
router.POST("/room-post/:roomid", roomPOST)
|
|
||||||
router.GET("/stream/:roomid", streamRoom)
|
|
||||||
|
|
||||||
router.Run(":80")
|
|
||||||
}
|
|
|
@ -1,208 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title>Server-Sent Events. Room "{{.roomid}}"</title>
|
|
||||||
<!-- jQuery -->
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
|
||||||
<script src="http://malsup.github.com/jquery.form.js"></script>
|
|
||||||
<!-- EPOCH -->
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js"></script>
|
|
||||||
<script src="/static/epoch.min.js"></script>
|
|
||||||
<link rel="stylesheet" href="/static/epoch.min.css">
|
|
||||||
<script src="/static/realtime.js"></script>
|
|
||||||
<!-- Latest compiled and minified CSS -->
|
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
|
|
||||||
<!-- Optional theme -->
|
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
|
|
||||||
<!-- Latest compiled and minified JavaScript -->
|
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
|
||||||
<!-- Primjs -->
|
|
||||||
<link href="/static/prismjs.min.css" rel="stylesheet" />
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(document).ready(function() {
|
|
||||||
StartRealtime({{.roomid}}, {{.timestamp}});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
body { padding-top: 50px; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav class="navbar navbar-fixed-top navbar-inverse">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" href="#">Server-Sent Events</a>
|
|
||||||
</div>
|
|
||||||
<div id="navbar" class="collapse navbar-collapse">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li class="active"><a href="#">Demo</a></li>
|
|
||||||
<li><a href="http://www.w3.org/TR/2009/WD-eventsource-20091029/">W3 Standard</a></li>
|
|
||||||
<li><a href="http://caniuse.com/#feat=eventsource">Browser Support</a></li>
|
|
||||||
<li><a href="http://gin-gonic.github.io/gin/">Gin Framework</a></li>
|
|
||||||
<li><a href="https://github.com/gin-gonic/gin/tree/develop/examples/realtime-advanced">Github</a></li>
|
|
||||||
</ul>
|
|
||||||
</div><!-- /.nav-collapse -->
|
|
||||||
</div><!-- /.container -->
|
|
||||||
</nav><!-- /.navbar -->
|
|
||||||
<!-- Main jumbotron for a primary marketing message or call to action -->
|
|
||||||
<div class="jumbotron">
|
|
||||||
<div class="container">
|
|
||||||
<h1>Server-Sent Events in Go</h1>
|
|
||||||
<p>Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. It is not websockets. <a href="http://www.html5rocks.com/en/tutorials/eventsource/basics/">Learn more.</a></p>
|
|
||||||
<p>The chat and the charts data is provided in realtime using the SSE implemention of <a href="https://github.com/gin-gonic/gin/blob/15b0c49da556d58a3d934b86e3aa552ff224026d/examples/realtime-chat/main.go#L23-L32">Gin Framework</a>.</p>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div id="chat-scroll" style="overflow-y:scroll; overflow-x:scroll; height:290px">
|
|
||||||
<table id="table-style" class="table" data-show-header="false">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-field="nick" class="col-md-2">Nick</th>
|
|
||||||
<th data-field="message" class="col-md-8">Message</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="chat"></tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{{if .nick}}
|
|
||||||
<form autocomplete="off" class="form-inline" id="chat-form" action="/room-post/{{.roomid}}?nick={{.nick}}" method="post">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="sr-only" for="chat-message">Message</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon">{{.nick}}</div>
|
|
||||||
<input type="text" name="message" id="chat-message" class="form-control" placeholder="a message" value="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<input type="submit" class="btn btn-primary" value="Send" />
|
|
||||||
</form>
|
|
||||||
{{else}}
|
|
||||||
<form action="" method="get" class="form-inline">
|
|
||||||
<legend>Join the SSE real-time chat</legend>
|
|
||||||
<div class="form-group">
|
|
||||||
<input value='' name="nick" id="nick" placeholder="Your Name" type="text" class="form-control" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group text-center">
|
|
||||||
<input type="submit" class="btn btn-success btn-login-submit" value="Join" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div id="messagesChart" class="epoch category10"></div>
|
|
||||||
<p>
|
|
||||||
<span style="font-size:20px; color:#1f77b4">◼︎</span> Users<br>
|
|
||||||
<span style="font-size:20px; color:#ff7f0e">◼︎</span> Inbound messages / sec<br>
|
|
||||||
<span style="font-size:20px; color:#2ca02c">◼︎</span> Outbound messages / sec<br>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<h2>Realtime server Go stats</h2>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h3>Memory usage</h3>
|
|
||||||
<p>
|
|
||||||
<div id="heapChart" class="epoch category20c"></div>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span style="font-size:20px; color:#1f77b4">◼︎</span> Heap bytes<br>
|
|
||||||
<span style="font-size:20px; color:#aec7e8">◼︎</span> Stack bytes<br>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h3>Allocations per second</h3>
|
|
||||||
<p>
|
|
||||||
<div id="mallocsChart" class="epoch category20b"></div>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span style="font-size:20px; color:#393b79">◼︎</span> Mallocs / sec<br>
|
|
||||||
<span style="font-size:20px; color:#5254a3">◼︎</span> Frees / sec<br>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<h2>MIT Open Sourced</h2>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/gin-gonic/gin/tree/develop/examples/realtime-advanced">This demo website (JS and Go)</a></li>
|
|
||||||
<li><a href="https://github.com/manucorporat/sse">The SSE implementation in Go</a></li>
|
|
||||||
<li><a href="https://github.com/gin-gonic/gin">The Web Framework (Gin)</a></li>
|
|
||||||
</ul>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<script src="/static/prismjs.min.js"></script>
|
|
||||||
<h3>Server-side (Go)</h3>
|
|
||||||
<pre><code class="language-go">func streamRoom(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
listener := openListener(roomid)
|
|
||||||
statsTicker := time.NewTicker(1 * time.Second)
|
|
||||||
defer closeListener(roomid, listener)
|
|
||||||
defer statsTicker.Stop()
|
|
||||||
|
|
||||||
c.Stream(func(w io.Writer) bool {
|
|
||||||
select {
|
|
||||||
case msg := <-listener:
|
|
||||||
c.SSEvent("message", msg)
|
|
||||||
case <-statsTicker.C:
|
|
||||||
c.SSEvent("stats", Stats())
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}</code></pre>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h3>Client-side (JS)</h3>
|
|
||||||
<pre><code class="language-javascript">function StartSSE(roomid) {
|
|
||||||
var source = new EventSource('/stream/'+roomid);
|
|
||||||
source.addEventListener('message', newChatMessage, false);
|
|
||||||
source.addEventListener('stats', stats, false);
|
|
||||||
}</code></pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h3>SSE package</h3>
|
|
||||||
<pre><code class="language-go">import "github.com/manucorporat/sse"
|
|
||||||
|
|
||||||
func httpHandler(w http.ResponseWriter, req *http.Request) {
|
|
||||||
// data can be a primitive like a string, an integer or a float
|
|
||||||
sse.Encode(w, sse.Event{
|
|
||||||
Event: "message",
|
|
||||||
Data: "some data\nmore data",
|
|
||||||
})
|
|
||||||
|
|
||||||
// also a complex type, like a map, a struct or a slice
|
|
||||||
sse.Encode(w, sse.Event{
|
|
||||||
Id: "124",
|
|
||||||
Event: "message",
|
|
||||||
Data: map[string]interface{}{
|
|
||||||
"user": "manu",
|
|
||||||
"date": time.Now().Unix(),
|
|
||||||
"content": "hi!",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}</code></pre>
|
|
||||||
<pre>event: message
|
|
||||||
data: some data\\nmore data
|
|
||||||
|
|
||||||
id: 124
|
|
||||||
event: message
|
|
||||||
data: {"content":"hi!","date":1431540810,"user":"manu"}</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<footer>
|
|
||||||
<p>Created with <span class="glyphicon glyphicon-heart"></span> by <a href="https://github.com/manucorporat">Manu Martinez-Almeida</a></p>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
File diff suppressed because one or more lines are too long
|
@ -1,137 +0,0 @@
|
||||||
/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+go */
|
|
||||||
/**
|
|
||||||
* prism.js default theme for JavaScript, CSS and HTML
|
|
||||||
* Based on dabblet (http://dabblet.com)
|
|
||||||
* @author Lea Verou
|
|
||||||
*/
|
|
||||||
|
|
||||||
code[class*="language-"],
|
|
||||||
pre[class*="language-"] {
|
|
||||||
color: black;
|
|
||||||
text-shadow: 0 1px white;
|
|
||||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
|
||||||
direction: ltr;
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre;
|
|
||||||
word-spacing: normal;
|
|
||||||
word-break: normal;
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
-moz-tab-size: 4;
|
|
||||||
-o-tab-size: 4;
|
|
||||||
tab-size: 4;
|
|
||||||
|
|
||||||
-webkit-hyphens: none;
|
|
||||||
-moz-hyphens: none;
|
|
||||||
-ms-hyphens: none;
|
|
||||||
hyphens: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
|
||||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
|
||||||
text-shadow: none;
|
|
||||||
background: #b3d4fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
|
||||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
|
||||||
text-shadow: none;
|
|
||||||
background: #b3d4fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
code[class*="language-"],
|
|
||||||
pre[class*="language-"] {
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Code blocks */
|
|
||||||
pre[class*="language-"] {
|
|
||||||
padding: 1em;
|
|
||||||
margin: .5em 0;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:not(pre) > code[class*="language-"],
|
|
||||||
pre[class*="language-"] {
|
|
||||||
background: #f5f2f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
:not(pre) > code[class*="language-"] {
|
|
||||||
padding: .1em;
|
|
||||||
border-radius: .3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.comment,
|
|
||||||
.token.prolog,
|
|
||||||
.token.doctype,
|
|
||||||
.token.cdata {
|
|
||||||
color: slategray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.punctuation {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.namespace {
|
|
||||||
opacity: .7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.property,
|
|
||||||
.token.tag,
|
|
||||||
.token.boolean,
|
|
||||||
.token.number,
|
|
||||||
.token.constant,
|
|
||||||
.token.symbol,
|
|
||||||
.token.deleted {
|
|
||||||
color: #905;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.selector,
|
|
||||||
.token.attr-name,
|
|
||||||
.token.string,
|
|
||||||
.token.char,
|
|
||||||
.token.builtin,
|
|
||||||
.token.inserted {
|
|
||||||
color: #690;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.operator,
|
|
||||||
.token.entity,
|
|
||||||
.token.url,
|
|
||||||
.language-css .token.string,
|
|
||||||
.style .token.string {
|
|
||||||
color: #a67f59;
|
|
||||||
background: hsla(0, 0%, 100%, .5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.atrule,
|
|
||||||
.token.attr-value,
|
|
||||||
.token.keyword {
|
|
||||||
color: #07a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.function {
|
|
||||||
color: #DD4A68;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.regex,
|
|
||||||
.token.important,
|
|
||||||
.token.variable {
|
|
||||||
color: #e90;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.important,
|
|
||||||
.token.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.token.italic {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.entity {
|
|
||||||
cursor: help;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
function StartRealtime(roomid, timestamp) {
|
|
||||||
StartEpoch(timestamp);
|
|
||||||
StartSSE(roomid);
|
|
||||||
StartForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
function StartForm() {
|
|
||||||
$('#chat-message').focus();
|
|
||||||
$('#chat-form').ajaxForm(function() {
|
|
||||||
$('#chat-message').val('');
|
|
||||||
$('#chat-message').focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function StartEpoch(timestamp) {
|
|
||||||
var windowSize = 60;
|
|
||||||
var height = 200;
|
|
||||||
var defaultData = histogram(windowSize, timestamp);
|
|
||||||
|
|
||||||
window.heapChart = $('#heapChart').epoch({
|
|
||||||
type: 'time.area',
|
|
||||||
axes: ['bottom', 'left'],
|
|
||||||
height: height,
|
|
||||||
historySize: 10,
|
|
||||||
data: [
|
|
||||||
{values: defaultData},
|
|
||||||
{values: defaultData}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
window.mallocsChart = $('#mallocsChart').epoch({
|
|
||||||
type: 'time.area',
|
|
||||||
axes: ['bottom', 'left'],
|
|
||||||
height: height,
|
|
||||||
historySize: 10,
|
|
||||||
data: [
|
|
||||||
{values: defaultData},
|
|
||||||
{values: defaultData}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
window.messagesChart = $('#messagesChart').epoch({
|
|
||||||
type: 'time.line',
|
|
||||||
axes: ['bottom', 'left'],
|
|
||||||
height: 240,
|
|
||||||
historySize: 10,
|
|
||||||
data: [
|
|
||||||
{values: defaultData},
|
|
||||||
{values: defaultData},
|
|
||||||
{values: defaultData}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function StartSSE(roomid) {
|
|
||||||
if (!window.EventSource) {
|
|
||||||
alert("EventSource is not enabled in this browser");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var source = new EventSource('/stream/'+roomid);
|
|
||||||
source.addEventListener('message', newChatMessage, false);
|
|
||||||
source.addEventListener('stats', stats, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function stats(e) {
|
|
||||||
var data = parseJSONStats(e.data);
|
|
||||||
heapChart.push(data.heap);
|
|
||||||
mallocsChart.push(data.mallocs);
|
|
||||||
messagesChart.push(data.messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseJSONStats(e) {
|
|
||||||
var data = jQuery.parseJSON(e);
|
|
||||||
var timestamp = data.timestamp;
|
|
||||||
|
|
||||||
var heap = [
|
|
||||||
{time: timestamp, y: data.HeapInuse},
|
|
||||||
{time: timestamp, y: data.StackInuse}
|
|
||||||
];
|
|
||||||
|
|
||||||
var mallocs = [
|
|
||||||
{time: timestamp, y: data.Mallocs},
|
|
||||||
{time: timestamp, y: data.Frees}
|
|
||||||
];
|
|
||||||
var messages = [
|
|
||||||
{time: timestamp, y: data.Connected},
|
|
||||||
{time: timestamp, y: data.Inbound},
|
|
||||||
{time: timestamp, y: data.Outbound}
|
|
||||||
];
|
|
||||||
|
|
||||||
return {
|
|
||||||
heap: heap,
|
|
||||||
mallocs: mallocs,
|
|
||||||
messages: messages
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function newChatMessage(e) {
|
|
||||||
var data = jQuery.parseJSON(e.data);
|
|
||||||
var nick = data.nick;
|
|
||||||
var message = data.message;
|
|
||||||
var style = rowStyle(nick);
|
|
||||||
var html = "<tr class=\""+style+"\"><td>"+nick+"</td><td>"+message+"</td></tr>";
|
|
||||||
$('#chat').append(html);
|
|
||||||
|
|
||||||
$("#chat-scroll").scrollTop($("#chat-scroll")[0].scrollHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
function histogram(windowSize, timestamp) {
|
|
||||||
var entries = new Array(windowSize);
|
|
||||||
for(var i = 0; i < windowSize; i++) {
|
|
||||||
entries[i] = {time: (timestamp-windowSize+i-1), y:0};
|
|
||||||
}
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
var entityMap = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
'"': '"',
|
|
||||||
"'": ''',
|
|
||||||
"/": '/'
|
|
||||||
};
|
|
||||||
|
|
||||||
function rowStyle(nick) {
|
|
||||||
var classes = ['active', 'success', 'info', 'warning', 'danger'];
|
|
||||||
var index = hashCode(nick)%5;
|
|
||||||
return classes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
function hashCode(s){
|
|
||||||
return Math.abs(s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0));
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeHtml(string) {
|
|
||||||
return String(string).replace(/[&<>"'\/]/g, function (s) {
|
|
||||||
return entityMap[s];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.StartRealtime = StartRealtime
|
|
25
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/rooms.go
generated
vendored
25
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/rooms.go
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/dustin/go-broadcast"
|
|
||||||
|
|
||||||
var roomChannels = make(map[string]broadcast.Broadcaster)
|
|
||||||
|
|
||||||
func openListener(roomid string) chan interface{} {
|
|
||||||
listener := make(chan interface{})
|
|
||||||
room(roomid).Register(listener)
|
|
||||||
return listener
|
|
||||||
}
|
|
||||||
|
|
||||||
func closeListener(roomid string, listener chan interface{}) {
|
|
||||||
room(roomid).Unregister(listener)
|
|
||||||
close(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
func room(roomid string) broadcast.Broadcaster {
|
|
||||||
b, ok := roomChannels[roomid]
|
|
||||||
if !ok {
|
|
||||||
b = broadcast.NewBroadcaster(10)
|
|
||||||
roomChannels[roomid] = b
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
96
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/routes.go
generated
vendored
96
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/routes.go
generated
vendored
|
@ -1,96 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"html"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func rateLimit(c *gin.Context) {
|
|
||||||
|
|
||||||
ip := c.ClientIP()
|
|
||||||
value := int(ips.Add(ip, 1))
|
|
||||||
if value%50 == 0 {
|
|
||||||
fmt.Printf("ip: %s, count: %d\n", ip, value)
|
|
||||||
}
|
|
||||||
if value >= 200 {
|
|
||||||
if value%200 == 0 {
|
|
||||||
fmt.Println("ip blocked")
|
|
||||||
}
|
|
||||||
c.Abort()
|
|
||||||
c.String(503, "you were automatically banned :)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func index(c *gin.Context) {
|
|
||||||
c.Redirect(301, "/room/hn")
|
|
||||||
}
|
|
||||||
|
|
||||||
func roomGET(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
nick := c.FormValue("nick")
|
|
||||||
if len(nick) < 2 {
|
|
||||||
nick = ""
|
|
||||||
}
|
|
||||||
if len(nick) > 13 {
|
|
||||||
nick = nick[0:12] + "..."
|
|
||||||
}
|
|
||||||
c.HTML(200, "room_login.templ.html", gin.H{
|
|
||||||
"roomid": roomid,
|
|
||||||
"nick": nick,
|
|
||||||
"timestamp": time.Now().Unix(),
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func roomPOST(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
nick := c.FormValue("nick")
|
|
||||||
message := c.PostFormValue("message")
|
|
||||||
message = strings.TrimSpace(message)
|
|
||||||
|
|
||||||
validMessage := len(message) > 1 && len(message) < 200
|
|
||||||
validNick := len(nick) > 1 && len(nick) < 14
|
|
||||||
if !validMessage || !validNick {
|
|
||||||
c.JSON(400, gin.H{
|
|
||||||
"status": "failed",
|
|
||||||
"error": "the message or nickname is too long",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
post := gin.H{
|
|
||||||
"nick": html.EscapeString(nick),
|
|
||||||
"message": html.EscapeString(message),
|
|
||||||
}
|
|
||||||
messages.Add("inbound", 1)
|
|
||||||
room(roomid).Submit(post)
|
|
||||||
c.JSON(200, post)
|
|
||||||
}
|
|
||||||
|
|
||||||
func streamRoom(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
listener := openListener(roomid)
|
|
||||||
ticker := time.NewTicker(1 * time.Second)
|
|
||||||
users.Add("connected", 1)
|
|
||||||
defer func() {
|
|
||||||
closeListener(roomid, listener)
|
|
||||||
ticker.Stop()
|
|
||||||
users.Add("disconnected", 1)
|
|
||||||
}()
|
|
||||||
|
|
||||||
c.Stream(func(w io.Writer) bool {
|
|
||||||
select {
|
|
||||||
case msg := <-listener:
|
|
||||||
messages.Add("outbound", 1)
|
|
||||||
c.SSEvent("message", msg)
|
|
||||||
case <-ticker.C:
|
|
||||||
c.SSEvent("stats", Stats())
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
56
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/stats.go
generated
vendored
56
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/stats.go
generated
vendored
|
@ -1,56 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/manucorporat/stats"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ips = stats.New()
|
|
||||||
var messages = stats.New()
|
|
||||||
var users = stats.New()
|
|
||||||
var mutexStats sync.RWMutex
|
|
||||||
var savedStats map[string]uint64
|
|
||||||
|
|
||||||
func statsWorker() {
|
|
||||||
c := time.Tick(1 * time.Second)
|
|
||||||
var lastMallocs uint64 = 0
|
|
||||||
var lastFrees uint64 = 0
|
|
||||||
for range c {
|
|
||||||
var stats runtime.MemStats
|
|
||||||
runtime.ReadMemStats(&stats)
|
|
||||||
|
|
||||||
mutexStats.Lock()
|
|
||||||
savedStats = map[string]uint64{
|
|
||||||
"timestamp": uint64(time.Now().Unix()),
|
|
||||||
"HeapInuse": stats.HeapInuse,
|
|
||||||
"StackInuse": stats.StackInuse,
|
|
||||||
"Mallocs": (stats.Mallocs - lastMallocs),
|
|
||||||
"Frees": (stats.Frees - lastFrees),
|
|
||||||
"Inbound": uint64(messages.Get("inbound")),
|
|
||||||
"Outbound": uint64(messages.Get("outbound")),
|
|
||||||
"Connected": connectedUsers(),
|
|
||||||
}
|
|
||||||
lastMallocs = stats.Mallocs
|
|
||||||
lastFrees = stats.Frees
|
|
||||||
messages.Reset()
|
|
||||||
mutexStats.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectedUsers() uint64 {
|
|
||||||
connected := users.Get("connected") - users.Get("disconnected")
|
|
||||||
if connected < 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return uint64(connected)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Stats() map[string]uint64 {
|
|
||||||
mutexStats.RLock()
|
|
||||||
defer mutexStats.RUnlock()
|
|
||||||
|
|
||||||
return savedStats
|
|
||||||
}
|
|
58
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/main.go
generated
vendored
58
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/main.go
generated
vendored
|
@ -1,58 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"math/rand"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
router := gin.Default()
|
|
||||||
router.SetHTMLTemplate(html)
|
|
||||||
|
|
||||||
router.GET("/room/:roomid", roomGET)
|
|
||||||
router.POST("/room/:roomid", roomPOST)
|
|
||||||
router.DELETE("/room/:roomid", roomDELETE)
|
|
||||||
router.GET("/stream/:roomid", stream)
|
|
||||||
|
|
||||||
router.Run(":8080")
|
|
||||||
}
|
|
||||||
|
|
||||||
func stream(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
listener := openListener(roomid)
|
|
||||||
defer closeListener(roomid, listener)
|
|
||||||
|
|
||||||
c.Stream(func(w io.Writer) bool {
|
|
||||||
c.SSEvent("message", <-listener)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func roomGET(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
userid := fmt.Sprint(rand.Int31())
|
|
||||||
c.HTML(200, "chat_room", gin.H{
|
|
||||||
"roomid": roomid,
|
|
||||||
"userid": userid,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func roomPOST(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
userid := c.PostFormValue("user")
|
|
||||||
message := c.PostFormValue("message")
|
|
||||||
room(roomid).Submit(userid + ": " + message)
|
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
|
||||||
"status": "success",
|
|
||||||
"message": message,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func roomDELETE(c *gin.Context) {
|
|
||||||
roomid := c.ParamValue("roomid")
|
|
||||||
deleteBroadcast(roomid)
|
|
||||||
}
|
|
33
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/rooms.go
generated
vendored
33
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/rooms.go
generated
vendored
|
@ -1,33 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/dustin/go-broadcast"
|
|
||||||
|
|
||||||
var roomChannels = make(map[string]broadcast.Broadcaster)
|
|
||||||
|
|
||||||
func openListener(roomid string) chan interface{} {
|
|
||||||
listener := make(chan interface{})
|
|
||||||
room(roomid).Register(listener)
|
|
||||||
return listener
|
|
||||||
}
|
|
||||||
|
|
||||||
func closeListener(roomid string, listener chan interface{}) {
|
|
||||||
room(roomid).Unregister(listener)
|
|
||||||
close(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteBroadcast(roomid string) {
|
|
||||||
b, ok := roomChannels[roomid]
|
|
||||||
if ok {
|
|
||||||
b.Close()
|
|
||||||
delete(roomChannels, roomid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func room(roomid string) broadcast.Broadcaster {
|
|
||||||
b, ok := roomChannels[roomid]
|
|
||||||
if !ok {
|
|
||||||
b = broadcast.NewBroadcaster(10)
|
|
||||||
roomChannels[roomid] = b
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
44
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/template.go
generated
vendored
44
Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/template.go
generated
vendored
|
@ -1,44 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "html/template"
|
|
||||||
|
|
||||||
var html = template.Must(template.New("chat_room").Parse(`
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{{.roomid}}</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="http://meyerweb.com/eric/tools/css/reset/reset.css"/>
|
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
|
|
||||||
<script src="http://malsup.github.com/jquery.form.js"></script>
|
|
||||||
<script>
|
|
||||||
$('#message_form').focus();
|
|
||||||
$(document).ready(function() {
|
|
||||||
// bind 'myForm' and provide a simple callback function
|
|
||||||
$('#myForm').ajaxForm(function() {
|
|
||||||
$('#message_form').val('');
|
|
||||||
$('#message_form').focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!!window.EventSource) {
|
|
||||||
var source = new EventSource('/stream/{{.roomid}}');
|
|
||||||
source.addEventListener('message', function(e) {
|
|
||||||
$('#messages').append(e.data + "</br>");
|
|
||||||
$('html, body').animate({scrollTop:$(document).height()}, 'slow');
|
|
||||||
|
|
||||||
}, false);
|
|
||||||
} else {
|
|
||||||
alert("NOT SUPPORTED");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Welcome to {{.roomid}} room</h1>
|
|
||||||
<div id="messages"></div>
|
|
||||||
<form id="myForm" action="/room/{{.roomid}}" method="post">
|
|
||||||
User: <input id="user_form" name="user" value="{{.userid}}"></input>
|
|
||||||
Message: <input id="message_form" name="message"></input>
|
|
||||||
<input type="submit" value="Submit" />
|
|
||||||
</form>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`))
|
|
27
Godeps/_workspace/src/github.com/namsral/flag/LICENSE
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/namsral/flag/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
184
Godeps/_workspace/src/github.com/namsral/flag/README.md
generated
vendored
Normal file
184
Godeps/_workspace/src/github.com/namsral/flag/README.md
generated
vendored
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
Flag
|
||||||
|
===
|
||||||
|
|
||||||
|
Flag is a drop in replacement for Go's flag package with the addition to parse files and environment variables. If you support the [twelve-factor app methodology][], Flag complies with the third factor; "Store config in the environment".
|
||||||
|
|
||||||
|
[twelve-factor app methodology]: http://12factor.net
|
||||||
|
|
||||||
|
An example using a gopher:
|
||||||
|
|
||||||
|
```go
|
||||||
|
$ cat > gopher.go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/namsral/flag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var age int
|
||||||
|
|
||||||
|
flag.IntVar(&age, "age", 0, "age of gopher")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
fmt.Print("age:", age)
|
||||||
|
|
||||||
|
$ go run gopher.go -age 1
|
||||||
|
age: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Same code but using an environment variable:
|
||||||
|
|
||||||
|
```go
|
||||||
|
$ export AGE=2
|
||||||
|
$ go run gopher.go
|
||||||
|
age: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Same code but using a configuration file:
|
||||||
|
|
||||||
|
```go
|
||||||
|
$ cat > gopher.conf
|
||||||
|
age 3
|
||||||
|
|
||||||
|
$ go run gopher.go -config gopher.conf
|
||||||
|
age: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
The following table shows how flags are translated to environment variables and configuration files:
|
||||||
|
|
||||||
|
| Type | Flag | Environment | File |
|
||||||
|
| ------ | :------------ |:------------ |:------------ |
|
||||||
|
| int | -age 2 | AGE=2 | age 2 |
|
||||||
|
| bool | -female | FEMALE=true | female true |
|
||||||
|
| float | -length 175.5 | LENGTH=175.5 | length 175.5 |
|
||||||
|
| string | -name Gloria | NAME=Gloria | name Gloria |
|
||||||
|
|
||||||
|
This package is a port of Go's [flag][] package from the standard library with the addition of two functions `ParseEnv` and `ParseFile`.
|
||||||
|
|
||||||
|
[flag]: http://golang.org/src/pkg/flagconfiguration
|
||||||
|
|
||||||
|
|
||||||
|
Why?
|
||||||
|
---
|
||||||
|
|
||||||
|
Why not use one of the many INI, JSON or YAML parsers?
|
||||||
|
|
||||||
|
I find it best practice to have simple configuration options to control the behaviour of an applications when it starts up. Use basic types like ints, floats and strings for configuration options and store more complex data structures in the "datastore" layer.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
---
|
||||||
|
|
||||||
|
It's intended for projects which require a simple configuration made available through command-line flags, configuration files and shell environments. It's similar to the original `flag` package.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github/namsral/flag"
|
||||||
|
|
||||||
|
flag.String("config", "", "help message for config")
|
||||||
|
flag.Int("age", 24, "help message for age")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
```
|
||||||
|
|
||||||
|
Order of precedence:
|
||||||
|
|
||||||
|
1. Command line options
|
||||||
|
2. Environment variables
|
||||||
|
3. Configuration file
|
||||||
|
4. Default values
|
||||||
|
|
||||||
|
|
||||||
|
#### Parsing Configuration Files
|
||||||
|
|
||||||
|
Create a configuration file:
|
||||||
|
|
||||||
|
```go
|
||||||
|
$ cat > ./gopher.conf
|
||||||
|
# empty newlines and lines beginning with a "#" character are ignored.
|
||||||
|
name bob
|
||||||
|
|
||||||
|
# keys and values can also be separated by the "=" character
|
||||||
|
age=20
|
||||||
|
|
||||||
|
# booleans can be empty, set with 0, 1, true, false, etc
|
||||||
|
hacker
|
||||||
|
```
|
||||||
|
|
||||||
|
Add a "config" flag:
|
||||||
|
|
||||||
|
```go
|
||||||
|
flag.String("config", "", "help message for config")
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the command:
|
||||||
|
|
||||||
|
```go
|
||||||
|
$ go run ./gopher.go -config ./gopher.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Parsing Environment Variables
|
||||||
|
|
||||||
|
Environment variables are parsed 1-on-1 with defined flags:
|
||||||
|
|
||||||
|
```go
|
||||||
|
$ export AGE=44
|
||||||
|
$ go run ./gopher.go
|
||||||
|
age=44
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
You can also parse prefixed environment variables by setting a prefix name when creating a new empty flag set:
|
||||||
|
|
||||||
|
```go
|
||||||
|
fs := flag.NewFlagSetWithEnvPrefix(os.Args[0], "GO", 0)
|
||||||
|
fs.Int("age", 24, "help message for age")
|
||||||
|
fs.Parse(os.Args[1:])
|
||||||
|
...
|
||||||
|
$ go export GO_AGE=33
|
||||||
|
$ go run ./gopher.go
|
||||||
|
age=33
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
For more examples see the [examples][] directory in the project repository.
|
||||||
|
|
||||||
|
[examples]: https://github.com/namsral/flag/tree/master/examples
|
||||||
|
|
||||||
|
That's it.
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
82
Godeps/_workspace/src/github.com/namsral/flag/example_test.go
generated
vendored
Normal file
82
Godeps/_workspace/src/github.com/namsral/flag/example_test.go
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// These examples demonstrate more intricate uses of the flag package.
|
||||||
|
package flag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Example 1: A single string flag called "species" with default value "gopher".
|
||||||
|
var species = String("species", "gopher", "the species we are studying")
|
||||||
|
|
||||||
|
// Example 2: Two flags sharing a variable, so we can have a shorthand.
|
||||||
|
// The order of initialization is undefined, so make sure both use the
|
||||||
|
// same default value. They must be set up with an init function.
|
||||||
|
var gopherType string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
const (
|
||||||
|
defaultGopher = "pocket"
|
||||||
|
usage = "the variety of gopher"
|
||||||
|
)
|
||||||
|
StringVar(&gopherType, "gopher_type", defaultGopher, usage)
|
||||||
|
StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example 3: A user-defined flag type, a slice of durations.
|
||||||
|
type interval []time.Duration
|
||||||
|
|
||||||
|
// String is the method to format the flag's value, part of the Value interface.
|
||||||
|
// The String method's output will be used in diagnostics.
|
||||||
|
func (i *interval) String() string {
|
||||||
|
return fmt.Sprint(*i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set is the method to set the flag value, part of the Value interface.
|
||||||
|
// Set's argument is a string to be parsed to set the
|
||||||
|
// It's a comma-separated list, so we split it.
|
||||||
|
func (i *interval) Set(value string) error {
|
||||||
|
// If we wanted to allow the flag to be set multiple times,
|
||||||
|
// accumulating values, we would delete this if statement.
|
||||||
|
// That would permit usages such as
|
||||||
|
// -deltaT 10s -deltaT 15s
|
||||||
|
// and other combinations.
|
||||||
|
if len(*i) > 0 {
|
||||||
|
return errors.New("interval flag already set")
|
||||||
|
}
|
||||||
|
for _, dt := range strings.Split(value, ",") {
|
||||||
|
duration, err := time.ParseDuration(dt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*i = append(*i, duration)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a flag to accumulate durations. Because it has a special type,
|
||||||
|
// we need to use the Var function and therefore create the flag during
|
||||||
|
// init.
|
||||||
|
|
||||||
|
var intervalFlag interval
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Tie the command-line flag to the intervalFlag variable and
|
||||||
|
// set a usage message.
|
||||||
|
Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example() {
|
||||||
|
// All the interesting pieces are with the variables declared above, but
|
||||||
|
// to enable the flag package to see the flags defined there, one must
|
||||||
|
// execute, typically at the start of main (not init!):
|
||||||
|
// flag.Parse()
|
||||||
|
// We don't run it here because this is not a main function and
|
||||||
|
// the testing suite has already parsed the flags.
|
||||||
|
}
|
5
Godeps/_workspace/src/github.com/namsral/flag/examples/gopher.conf
generated
vendored
Normal file
5
Godeps/_workspace/src/github.com/namsral/flag/examples/gopher.conf
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# this is a comment followed by an empty line
|
||||||
|
|
||||||
|
length 175.5
|
||||||
|
age 2
|
||||||
|
name Gloria
|
29
Godeps/_workspace/src/github.com/namsral/flag/examples/gopher.go
generated
vendored
Normal file
29
Godeps/_workspace/src/github.com/namsral/flag/examples/gopher.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/namsral/flag"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
config string
|
||||||
|
length float64
|
||||||
|
age int
|
||||||
|
name string
|
||||||
|
female bool
|
||||||
|
)
|
||||||
|
|
||||||
|
flag.StringVar(&config, "config", "", "help message")
|
||||||
|
flag.StringVar(&name, "name", "", "help message")
|
||||||
|
flag.IntVar(&age, "age", 0, "help message")
|
||||||
|
flag.Float64Var(&length, "length", 0, "help message")
|
||||||
|
flag.BoolVar(&female, "female", false, "help message")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
fmt.Println("length:", length)
|
||||||
|
fmt.Println("age:", age)
|
||||||
|
fmt.Println("name:", name)
|
||||||
|
fmt.Println("female:", female)
|
||||||
|
}
|
17
Godeps/_workspace/src/github.com/namsral/flag/export_test.go
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/namsral/flag/export_test.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package flag
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// Additional routines compiled into the package only during testing.
|
||||||
|
|
||||||
|
// ResetForTesting clears all flag state and sets the usage function as directed.
|
||||||
|
// After calling ResetForTesting, parse errors in flag handling will not
|
||||||
|
// exit the program.
|
||||||
|
func ResetForTesting(usage func()) {
|
||||||
|
CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
|
||||||
|
Usage = usage
|
||||||
|
}
|
1040
Godeps/_workspace/src/github.com/namsral/flag/flag.go
generated
vendored
Normal file
1040
Godeps/_workspace/src/github.com/namsral/flag/flag.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
475
Godeps/_workspace/src/github.com/namsral/flag/flag_test.go
generated
vendored
Normal file
475
Godeps/_workspace/src/github.com/namsral/flag/flag_test.go
generated
vendored
Normal file
|
@ -0,0 +1,475 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package flag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func boolString(s string) string {
|
||||||
|
if s == "0" {
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
return "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEverything(t *testing.T) {
|
||||||
|
ResetForTesting(nil)
|
||||||
|
Bool("test_bool", false, "bool value")
|
||||||
|
Int("test_int", 0, "int value")
|
||||||
|
Int64("test_int64", 0, "int64 value")
|
||||||
|
Uint("test_uint", 0, "uint value")
|
||||||
|
Uint64("test_uint64", 0, "uint64 value")
|
||||||
|
String("test_string", "0", "string value")
|
||||||
|
Float64("test_float64", 0, "float64 value")
|
||||||
|
Duration("test_duration", 0, "time.Duration value")
|
||||||
|
|
||||||
|
m := make(map[string]*Flag)
|
||||||
|
desired := "0"
|
||||||
|
visitor := func(f *Flag) {
|
||||||
|
if len(f.Name) > 5 && f.Name[0:5] == "test_" {
|
||||||
|
m[f.Name] = f
|
||||||
|
ok := false
|
||||||
|
switch {
|
||||||
|
case f.Value.String() == desired:
|
||||||
|
ok = true
|
||||||
|
case f.Name == "test_bool" && f.Value.String() == boolString(desired):
|
||||||
|
ok = true
|
||||||
|
case f.Name == "test_duration" && f.Value.String() == desired+"s":
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VisitAll(visitor)
|
||||||
|
if len(m) != 8 {
|
||||||
|
t.Error("VisitAll misses some flags")
|
||||||
|
for k, v := range m {
|
||||||
|
t.Log(k, *v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m = make(map[string]*Flag)
|
||||||
|
Visit(visitor)
|
||||||
|
if len(m) != 0 {
|
||||||
|
t.Errorf("Visit sees unset flags")
|
||||||
|
for k, v := range m {
|
||||||
|
t.Log(k, *v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now set all flags
|
||||||
|
Set("test_bool", "true")
|
||||||
|
Set("test_int", "1")
|
||||||
|
Set("test_int64", "1")
|
||||||
|
Set("test_uint", "1")
|
||||||
|
Set("test_uint64", "1")
|
||||||
|
Set("test_string", "1")
|
||||||
|
Set("test_float64", "1")
|
||||||
|
Set("test_duration", "1s")
|
||||||
|
desired = "1"
|
||||||
|
Visit(visitor)
|
||||||
|
if len(m) != 8 {
|
||||||
|
t.Error("Visit fails after set")
|
||||||
|
for k, v := range m {
|
||||||
|
t.Log(k, *v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now test they're visited in sort order.
|
||||||
|
var flagNames []string
|
||||||
|
Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) })
|
||||||
|
if !sort.StringsAreSorted(flagNames) {
|
||||||
|
t.Errorf("flag names not sorted: %v", flagNames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGet(t *testing.T) {
|
||||||
|
ResetForTesting(nil)
|
||||||
|
Bool("test_bool", true, "bool value")
|
||||||
|
Int("test_int", 1, "int value")
|
||||||
|
Int64("test_int64", 2, "int64 value")
|
||||||
|
Uint("test_uint", 3, "uint value")
|
||||||
|
Uint64("test_uint64", 4, "uint64 value")
|
||||||
|
String("test_string", "5", "string value")
|
||||||
|
Float64("test_float64", 6, "float64 value")
|
||||||
|
Duration("test_duration", 7, "time.Duration value")
|
||||||
|
|
||||||
|
visitor := func(f *Flag) {
|
||||||
|
if len(f.Name) > 5 && f.Name[0:5] == "test_" {
|
||||||
|
g, ok := f.Value.(Getter)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch f.Name {
|
||||||
|
case "test_bool":
|
||||||
|
ok = g.Get() == true
|
||||||
|
case "test_int":
|
||||||
|
ok = g.Get() == int(1)
|
||||||
|
case "test_int64":
|
||||||
|
ok = g.Get() == int64(2)
|
||||||
|
case "test_uint":
|
||||||
|
ok = g.Get() == uint(3)
|
||||||
|
case "test_uint64":
|
||||||
|
ok = g.Get() == uint64(4)
|
||||||
|
case "test_string":
|
||||||
|
ok = g.Get() == "5"
|
||||||
|
case "test_float64":
|
||||||
|
ok = g.Get() == float64(6)
|
||||||
|
case "test_duration":
|
||||||
|
ok = g.Get() == time.Duration(7)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), f.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VisitAll(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUsage(t *testing.T) {
|
||||||
|
called := false
|
||||||
|
ResetForTesting(func() { called = true })
|
||||||
|
if CommandLine.Parse([]string{"-x"}) == nil {
|
||||||
|
t.Error("parse did not fail for unknown flag")
|
||||||
|
}
|
||||||
|
if !called {
|
||||||
|
t.Error("did not call Usage for unknown flag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParse(f *FlagSet, t *testing.T) {
|
||||||
|
if f.Parsed() {
|
||||||
|
t.Error("f.Parse() = true before Parse")
|
||||||
|
}
|
||||||
|
boolFlag := f.Bool("bool", false, "bool value")
|
||||||
|
bool2Flag := f.Bool("bool2", false, "bool2 value")
|
||||||
|
intFlag := f.Int("int", 0, "int value")
|
||||||
|
int64Flag := f.Int64("int64", 0, "int64 value")
|
||||||
|
uintFlag := f.Uint("uint", 0, "uint value")
|
||||||
|
uint64Flag := f.Uint64("uint64", 0, "uint64 value")
|
||||||
|
stringFlag := f.String("string", "0", "string value")
|
||||||
|
float64Flag := f.Float64("float64", 0, "float64 value")
|
||||||
|
durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
|
||||||
|
extra := "one-extra-argument"
|
||||||
|
args := []string{
|
||||||
|
"-bool",
|
||||||
|
"-bool2=true",
|
||||||
|
"--int", "22",
|
||||||
|
"--int64", "0x23",
|
||||||
|
"-uint", "24",
|
||||||
|
"--uint64", "25",
|
||||||
|
"-string", "hello",
|
||||||
|
"-float64", "2718e28",
|
||||||
|
"-duration", "2m",
|
||||||
|
extra,
|
||||||
|
}
|
||||||
|
if err := f.Parse(args); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !f.Parsed() {
|
||||||
|
t.Error("f.Parse() = false after Parse")
|
||||||
|
}
|
||||||
|
if *boolFlag != true {
|
||||||
|
t.Error("bool flag should be true, is ", *boolFlag)
|
||||||
|
}
|
||||||
|
if *bool2Flag != true {
|
||||||
|
t.Error("bool2 flag should be true, is ", *bool2Flag)
|
||||||
|
}
|
||||||
|
if *intFlag != 22 {
|
||||||
|
t.Error("int flag should be 22, is ", *intFlag)
|
||||||
|
}
|
||||||
|
if *int64Flag != 0x23 {
|
||||||
|
t.Error("int64 flag should be 0x23, is ", *int64Flag)
|
||||||
|
}
|
||||||
|
if *uintFlag != 24 {
|
||||||
|
t.Error("uint flag should be 24, is ", *uintFlag)
|
||||||
|
}
|
||||||
|
if *uint64Flag != 25 {
|
||||||
|
t.Error("uint64 flag should be 25, is ", *uint64Flag)
|
||||||
|
}
|
||||||
|
if *stringFlag != "hello" {
|
||||||
|
t.Error("string flag should be `hello`, is ", *stringFlag)
|
||||||
|
}
|
||||||
|
if *float64Flag != 2718e28 {
|
||||||
|
t.Error("float64 flag should be 2718e28, is ", *float64Flag)
|
||||||
|
}
|
||||||
|
if *durationFlag != 2*time.Minute {
|
||||||
|
t.Error("duration flag should be 2m, is ", *durationFlag)
|
||||||
|
}
|
||||||
|
if len(f.Args()) != 1 {
|
||||||
|
t.Error("expected one argument, got", len(f.Args()))
|
||||||
|
} else if f.Args()[0] != extra {
|
||||||
|
t.Errorf("expected argument %q got %q", extra, f.Args()[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
ResetForTesting(func() { t.Error("bad parse") })
|
||||||
|
testParse(CommandLine, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFlagSetParse(t *testing.T) {
|
||||||
|
testParse(NewFlagSet("test", ContinueOnError), t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Declare a user-defined flag type.
|
||||||
|
type flagVar []string
|
||||||
|
|
||||||
|
func (f *flagVar) String() string {
|
||||||
|
return fmt.Sprint([]string(*f))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *flagVar) Set(value string) error {
|
||||||
|
*f = append(*f, value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserDefined(t *testing.T) {
|
||||||
|
var flags FlagSet
|
||||||
|
flags.Init("test", ContinueOnError)
|
||||||
|
var v flagVar
|
||||||
|
flags.Var(&v, "v", "usage")
|
||||||
|
if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(v) != 3 {
|
||||||
|
t.Fatal("expected 3 args; got ", len(v))
|
||||||
|
}
|
||||||
|
expect := "[1 2 3]"
|
||||||
|
if v.String() != expect {
|
||||||
|
t.Errorf("expected value %q got %q", expect, v.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Declare a user-defined boolean flag type.
|
||||||
|
type boolFlagVar struct {
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *boolFlagVar) String() string {
|
||||||
|
return fmt.Sprintf("%d", b.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *boolFlagVar) Set(value string) error {
|
||||||
|
if value == "true" {
|
||||||
|
b.count++
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *boolFlagVar) IsBoolFlag() bool {
|
||||||
|
return b.count < 4
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserDefinedBool(t *testing.T) {
|
||||||
|
var flags FlagSet
|
||||||
|
flags.Init("test", ContinueOnError)
|
||||||
|
var b boolFlagVar
|
||||||
|
var err error
|
||||||
|
flags.Var(&b, "b", "usage")
|
||||||
|
if err = flags.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
|
||||||
|
if b.count < 4 {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.count != 4 {
|
||||||
|
t.Errorf("want: %d; got: %d", 4, b.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error; got none")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetOutput(t *testing.T) {
|
||||||
|
var flags FlagSet
|
||||||
|
var buf bytes.Buffer
|
||||||
|
flags.SetOutput(&buf)
|
||||||
|
flags.Init("test", ContinueOnError)
|
||||||
|
flags.Parse([]string{"-unknown"})
|
||||||
|
if out := buf.String(); !strings.Contains(out, "-unknown") {
|
||||||
|
t.Logf("expected output mentioning unknown; got %q", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This tests that one can reset the flags. This still works but not well, and is
|
||||||
|
// superseded by FlagSet.
|
||||||
|
func TestChangingArgs(t *testing.T) {
|
||||||
|
ResetForTesting(func() { t.Fatal("bad parse") })
|
||||||
|
oldArgs := os.Args
|
||||||
|
defer func() { os.Args = oldArgs }()
|
||||||
|
os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
|
||||||
|
before := Bool("before", false, "")
|
||||||
|
if err := CommandLine.Parse(os.Args[1:]); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cmd := Arg(0)
|
||||||
|
os.Args = Args()
|
||||||
|
after := Bool("after", false, "")
|
||||||
|
Parse()
|
||||||
|
args := Args()
|
||||||
|
|
||||||
|
if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
|
||||||
|
t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that -help invokes the usage message and returns ErrHelp.
|
||||||
|
func TestHelp(t *testing.T) {
|
||||||
|
var helpCalled = false
|
||||||
|
fs := NewFlagSet("help test", ContinueOnError)
|
||||||
|
fs.Usage = func() { helpCalled = true }
|
||||||
|
var flag bool
|
||||||
|
fs.BoolVar(&flag, "flag", false, "regular flag")
|
||||||
|
// Regular flag invocation should work
|
||||||
|
err := fs.Parse([]string{"-flag=true"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("expected no error; got ", err)
|
||||||
|
}
|
||||||
|
if !flag {
|
||||||
|
t.Error("flag was not set by -flag")
|
||||||
|
}
|
||||||
|
if helpCalled {
|
||||||
|
t.Error("help called for regular flag")
|
||||||
|
helpCalled = false // reset for next test
|
||||||
|
}
|
||||||
|
// Help flag should work as expected.
|
||||||
|
err = fs.Parse([]string{"-help"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("error expected")
|
||||||
|
}
|
||||||
|
if err != ErrHelp {
|
||||||
|
t.Fatal("expected ErrHelp; got ", err)
|
||||||
|
}
|
||||||
|
if !helpCalled {
|
||||||
|
t.Fatal("help was not called")
|
||||||
|
}
|
||||||
|
// If we define a help flag, that should override.
|
||||||
|
var help bool
|
||||||
|
fs.BoolVar(&help, "help", false, "help flag")
|
||||||
|
helpCalled = false
|
||||||
|
err = fs.Parse([]string{"-help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("expected no error for defined -help; got ", err)
|
||||||
|
}
|
||||||
|
if helpCalled {
|
||||||
|
t.Fatal("help was called; should not have been for defined help flag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test parsing a environment variables
|
||||||
|
func TestParseEnv(t *testing.T) {
|
||||||
|
|
||||||
|
syscall.Setenv("BOOL", "")
|
||||||
|
syscall.Setenv("BOOL2", "true")
|
||||||
|
syscall.Setenv("INT", "22")
|
||||||
|
syscall.Setenv("INT64", "0x23")
|
||||||
|
syscall.Setenv("UINT", "24")
|
||||||
|
syscall.Setenv("UINT64", "25")
|
||||||
|
syscall.Setenv("STRING", "hello")
|
||||||
|
syscall.Setenv("FLOAT64", "2718e28")
|
||||||
|
syscall.Setenv("DURATION", "2m")
|
||||||
|
|
||||||
|
f := NewFlagSet(os.Args[0], ContinueOnError)
|
||||||
|
|
||||||
|
boolFlag := f.Bool("bool", false, "bool value")
|
||||||
|
bool2Flag := f.Bool("bool2", false, "bool2 value")
|
||||||
|
intFlag := f.Int("int", 0, "int value")
|
||||||
|
int64Flag := f.Int64("int64", 0, "int64 value")
|
||||||
|
uintFlag := f.Uint("uint", 0, "uint value")
|
||||||
|
uint64Flag := f.Uint64("uint64", 0, "uint64 value")
|
||||||
|
stringFlag := f.String("string", "0", "string value")
|
||||||
|
float64Flag := f.Float64("float64", 0, "float64 value")
|
||||||
|
durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
|
||||||
|
|
||||||
|
err := f.ParseEnv(os.Environ())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("expected no error; got ", err)
|
||||||
|
}
|
||||||
|
if *boolFlag != true {
|
||||||
|
t.Error("bool flag should be true, is ", *boolFlag)
|
||||||
|
}
|
||||||
|
if *bool2Flag != true {
|
||||||
|
t.Error("bool2 flag should be true, is ", *bool2Flag)
|
||||||
|
}
|
||||||
|
if *intFlag != 22 {
|
||||||
|
t.Error("int flag should be 22, is ", *intFlag)
|
||||||
|
}
|
||||||
|
if *int64Flag != 0x23 {
|
||||||
|
t.Error("int64 flag should be 0x23, is ", *int64Flag)
|
||||||
|
}
|
||||||
|
if *uintFlag != 24 {
|
||||||
|
t.Error("uint flag should be 24, is ", *uintFlag)
|
||||||
|
}
|
||||||
|
if *uint64Flag != 25 {
|
||||||
|
t.Error("uint64 flag should be 25, is ", *uint64Flag)
|
||||||
|
}
|
||||||
|
if *stringFlag != "hello" {
|
||||||
|
t.Error("string flag should be `hello`, is ", *stringFlag)
|
||||||
|
}
|
||||||
|
if *float64Flag != 2718e28 {
|
||||||
|
t.Error("float64 flag should be 2718e28, is ", *float64Flag)
|
||||||
|
}
|
||||||
|
if *durationFlag != 2*time.Minute {
|
||||||
|
t.Error("duration flag should be 2m, is ", *durationFlag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test parsing a configuration file
|
||||||
|
func TestParseFile(t *testing.T) {
|
||||||
|
|
||||||
|
f := NewFlagSet(os.Args[0], ContinueOnError)
|
||||||
|
|
||||||
|
boolFlag := f.Bool("bool", false, "bool value")
|
||||||
|
bool2Flag := f.Bool("bool2", false, "bool2 value")
|
||||||
|
intFlag := f.Int("int", 0, "int value")
|
||||||
|
int64Flag := f.Int64("int64", 0, "int64 value")
|
||||||
|
uintFlag := f.Uint("uint", 0, "uint value")
|
||||||
|
uint64Flag := f.Uint64("uint64", 0, "uint64 value")
|
||||||
|
stringFlag := f.String("string", "0", "string value")
|
||||||
|
float64Flag := f.Float64("float64", 0, "float64 value")
|
||||||
|
durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
|
||||||
|
|
||||||
|
err := f.ParseFile("./testdata/test.conf")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("expected no error; got ", err)
|
||||||
|
}
|
||||||
|
if *boolFlag != true {
|
||||||
|
t.Error("bool flag should be true, is ", *boolFlag)
|
||||||
|
}
|
||||||
|
if *bool2Flag != true {
|
||||||
|
t.Error("bool2 flag should be true, is ", *bool2Flag)
|
||||||
|
}
|
||||||
|
if *intFlag != 22 {
|
||||||
|
t.Error("int flag should be 22, is ", *intFlag)
|
||||||
|
}
|
||||||
|
if *int64Flag != 0x23 {
|
||||||
|
t.Error("int64 flag should be 0x23, is ", *int64Flag)
|
||||||
|
}
|
||||||
|
if *uintFlag != 24 {
|
||||||
|
t.Error("uint flag should be 24, is ", *uintFlag)
|
||||||
|
}
|
||||||
|
if *uint64Flag != 25 {
|
||||||
|
t.Error("uint64 flag should be 25, is ", *uint64Flag)
|
||||||
|
}
|
||||||
|
if *stringFlag != "hello" {
|
||||||
|
t.Error("string flag should be `hello`, is ", *stringFlag)
|
||||||
|
}
|
||||||
|
if *float64Flag != 2718e28 {
|
||||||
|
t.Error("float64 flag should be 2718e28, is ", *float64Flag)
|
||||||
|
}
|
||||||
|
if *durationFlag != 2*time.Minute {
|
||||||
|
t.Error("duration flag should be 2m, is ", *durationFlag)
|
||||||
|
}
|
||||||
|
}
|
11
Godeps/_workspace/src/github.com/namsral/flag/testdata/test.conf
generated
vendored
Normal file
11
Godeps/_workspace/src/github.com/namsral/flag/testdata/test.conf
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# this is a comment followed by an empty line
|
||||||
|
|
||||||
|
bool
|
||||||
|
bool2=true
|
||||||
|
int 22
|
||||||
|
int64 0x23
|
||||||
|
uint 24
|
||||||
|
uint64 25
|
||||||
|
string hello
|
||||||
|
float64 2718e28
|
||||||
|
duration 2m
|
9
Godeps/_workspace/src/github.com/naoina/go-stringutil/.travis.yml
generated
vendored
9
Godeps/_workspace/src/github.com/naoina/go-stringutil/.travis.yml
generated
vendored
|
@ -1,9 +0,0 @@
|
||||||
language: go
|
|
||||||
go:
|
|
||||||
- 1.3
|
|
||||||
- 1.4
|
|
||||||
- tip
|
|
||||||
install:
|
|
||||||
- go get -v github.com/naoina/go-stringutil
|
|
||||||
script:
|
|
||||||
- go test -v ./... -bench . -benchmem
|
|
19
Godeps/_workspace/src/github.com/naoina/go-stringutil/LICENSE
generated
vendored
19
Godeps/_workspace/src/github.com/naoina/go-stringutil/LICENSE
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
Copyright (c) 2015 Naoya Inada <naoina@kuune.org>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
13
Godeps/_workspace/src/github.com/naoina/go-stringutil/README.md
generated
vendored
13
Godeps/_workspace/src/github.com/naoina/go-stringutil/README.md
generated
vendored
|
@ -1,13 +0,0 @@
|
||||||
# stringutil [![Build Status](https://travis-ci.org/naoina/go-stringutil.png?branch=master)](https://travis-ci.org/naoina/go-stringutil)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
go get -u github.com/naoina/go-stringutil
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
See https://godoc.org/github.com/naoina/go-stringutil
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
120
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings.go
generated
vendored
120
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings.go
generated
vendored
|
@ -1,120 +0,0 @@
|
||||||
package stringutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToUpperCamelCase returns a copy of the string s with all Unicode letters mapped to their camel case.
|
|
||||||
// It will convert to upper case previous letter of '_' and first letter, and remove letter of '_'.
|
|
||||||
func ToUpperCamelCase(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
upper := true
|
|
||||||
var result bytes.Buffer
|
|
||||||
for _, c := range s {
|
|
||||||
if c == '_' {
|
|
||||||
upper = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if upper {
|
|
||||||
result.WriteRune(unicode.ToUpper(c))
|
|
||||||
upper = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result.WriteRune(c)
|
|
||||||
}
|
|
||||||
return result.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToUpperCamelCaseASCII is similar to ToUpperCamelCase, but optimized for
|
|
||||||
// only the ASCII characters.
|
|
||||||
// ToUpperCamelCaseASCII is faster than ToUpperCamelCase, but doesn't work if
|
|
||||||
// contains non-ASCII characters.
|
|
||||||
func ToUpperCamelCaseASCII(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
upper := true
|
|
||||||
result := make([]byte, 0, len(s))
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
c := s[i]
|
|
||||||
if c == '_' {
|
|
||||||
upper = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if upper {
|
|
||||||
result = append(result, toUpperASCII(c))
|
|
||||||
upper = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result = append(result, c)
|
|
||||||
}
|
|
||||||
return string(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToSnakeCase returns a copy of the string s with all Unicode letters mapped to their snake case.
|
|
||||||
// It will insert letter of '_' at position of previous letter of uppercase and all
|
|
||||||
// letters convert to lower case.
|
|
||||||
func ToSnakeCase(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
var result bytes.Buffer
|
|
||||||
for _, c := range s {
|
|
||||||
if unicode.IsUpper(c) {
|
|
||||||
result.WriteByte('_')
|
|
||||||
}
|
|
||||||
result.WriteRune(unicode.ToLower(c))
|
|
||||||
}
|
|
||||||
s = result.String()
|
|
||||||
if s[0] == '_' {
|
|
||||||
return s[1:]
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToSnakeCaseASCII is similar to ToSnakeCase, but optimized for only the ASCII
|
|
||||||
// characters.
|
|
||||||
// ToSnakeCaseASCII is faster than ToSnakeCase, but doesn't work correctly if
|
|
||||||
// contains non-ASCII characters.
|
|
||||||
func ToSnakeCaseASCII(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := make([]byte, 0, len(s))
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
c := s[i]
|
|
||||||
if isUpperASCII(c) {
|
|
||||||
result = append(result, '_')
|
|
||||||
}
|
|
||||||
result = append(result, toLowerASCII(c))
|
|
||||||
}
|
|
||||||
if result[0] == '_' {
|
|
||||||
return string(result[1:])
|
|
||||||
}
|
|
||||||
return string(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isUpperASCII(c byte) bool {
|
|
||||||
return 'A' <= c && c <= 'Z'
|
|
||||||
}
|
|
||||||
|
|
||||||
func isLowerASCII(c byte) bool {
|
|
||||||
return 'a' <= c && c <= 'z'
|
|
||||||
}
|
|
||||||
|
|
||||||
func toUpperASCII(c byte) byte {
|
|
||||||
if isLowerASCII(c) {
|
|
||||||
return c - ('a' - 'A')
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func toLowerASCII(c byte) byte {
|
|
||||||
if isUpperASCII(c) {
|
|
||||||
return c + 'a' - 'A'
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
35
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go
generated
vendored
35
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go
generated
vendored
|
@ -1,35 +0,0 @@
|
||||||
package stringutil_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/go-stringutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
var benchcaseForCamelCase = "the_quick_brown_fox_jumps_over_the_lazy_dog"
|
|
||||||
|
|
||||||
func BenchmarkToUpperCamelCase(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
stringutil.ToUpperCamelCase(benchcaseForCamelCase)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkToUpperCamelCaseASCII(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
stringutil.ToUpperCamelCaseASCII(benchcaseForCamelCase)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var benchcaseForSnakeCase = "TheQuickBrownFoxJumpsOverTheLazyDog"
|
|
||||||
|
|
||||||
func BenchmarkToSnakeCase(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
stringutil.ToSnakeCase(benchcaseForSnakeCase)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkToSnakeCaseASCII(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
stringutil.ToSnakeCaseASCII(benchcaseForSnakeCase)
|
|
||||||
}
|
|
||||||
}
|
|
88
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go
generated
vendored
88
Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go
generated
vendored
|
@ -1,88 +0,0 @@
|
||||||
package stringutil_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/go-stringutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestToUpperCamelCase(t *testing.T) {
|
|
||||||
for _, v := range []struct {
|
|
||||||
input, expect string
|
|
||||||
}{
|
|
||||||
{"", ""},
|
|
||||||
{"thequickbrownfoxoverthelazydog", "Thequickbrownfoxoverthelazydog"},
|
|
||||||
{"thequickbrownfoxoverthelazydoG", "ThequickbrownfoxoverthelazydoG"},
|
|
||||||
{"thequickbrownfoxoverthelazydo_g", "ThequickbrownfoxoverthelazydoG"},
|
|
||||||
{"TheQuickBrownFoxJumpsOverTheLazyDog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
|
|
||||||
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
|
|
||||||
{"the_Quick_Brown_Fox_Jumps_Over_The_Lazy_Dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
|
|
||||||
{"the_quick_brown_fox_over_the_lazy_dog", "TheQuickBrownFoxOverTheLazyDog"},
|
|
||||||
} {
|
|
||||||
actual := stringutil.ToUpperCamelCase(v.input)
|
|
||||||
expect := v.expect
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`stringutil.ToUpperCamelCase(%#v) => %#v; want %#v`, v.input, actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToUpperCamelCaseASCII(t *testing.T) {
|
|
||||||
for _, v := range []struct {
|
|
||||||
input, expect string
|
|
||||||
}{
|
|
||||||
{"", ""},
|
|
||||||
{"thequickbrownfoxoverthelazydog", "Thequickbrownfoxoverthelazydog"},
|
|
||||||
{"thequickbrownfoxoverthelazydoG", "ThequickbrownfoxoverthelazydoG"},
|
|
||||||
{"thequickbrownfoxoverthelazydo_g", "ThequickbrownfoxoverthelazydoG"},
|
|
||||||
{"TheQuickBrownFoxJumpsOverTheLazyDog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
|
|
||||||
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
|
|
||||||
{"the_Quick_Brown_Fox_Jumps_Over_The_Lazy_Dog", "TheQuickBrownFoxJumpsOverTheLazyDog"},
|
|
||||||
} {
|
|
||||||
actual := stringutil.ToUpperCamelCaseASCII(v.input)
|
|
||||||
expect := v.expect
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`stringutil.ToUpperCamelCaseASCII(%#v) => %#v; want %#v`, v.input, actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToSnakeCase(t *testing.T) {
|
|
||||||
for _, v := range []struct {
|
|
||||||
input, expect string
|
|
||||||
}{
|
|
||||||
{"", ""},
|
|
||||||
{"thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
|
|
||||||
{"Thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
|
|
||||||
{"ThequickbrownfoxjumpsoverthelazydoG", "thequickbrownfoxjumpsoverthelazydo_g"},
|
|
||||||
{"TheQuickBrownFoxJumpsOverTheLazyDog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
|
|
||||||
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
|
|
||||||
{"TheQuickBrownFoxOverTheLazyDog", "the_quick_brown_fox_over_the_lazy_dog"},
|
|
||||||
} {
|
|
||||||
actual := stringutil.ToSnakeCase(v.input)
|
|
||||||
expect := v.expect
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`stringutil.ToSnakeCase(%#v) => %#v; want %#v`, v.input, actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToSnakeCaseASCII(t *testing.T) {
|
|
||||||
for _, v := range []struct {
|
|
||||||
input, expect string
|
|
||||||
}{
|
|
||||||
{"", ""},
|
|
||||||
{"thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
|
|
||||||
{"Thequickbrownfoxjumpsoverthelazydog", "thequickbrownfoxjumpsoverthelazydog"},
|
|
||||||
{"ThequickbrownfoxjumpsoverthelazydoG", "thequickbrownfoxjumpsoverthelazydo_g"},
|
|
||||||
{"TheQuickBrownFoxJumpsOverTheLazyDog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
|
|
||||||
{"the_quick_brown_fox_jumps_over_the_lazy_dog", "the_quick_brown_fox_jumps_over_the_lazy_dog"},
|
|
||||||
} {
|
|
||||||
actual := stringutil.ToSnakeCaseASCII(v.input)
|
|
||||||
expect := v.expect
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`stringutil.ToSnakeCaseASCII(%#v) => %#v; want %#v`, v.input, actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
11
Godeps/_workspace/src/github.com/naoina/toml/.travis.yml
generated
vendored
11
Godeps/_workspace/src/github.com/naoina/toml/.travis.yml
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.3
|
|
||||||
- tip
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go get -v ./...
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test ./...
|
|
19
Godeps/_workspace/src/github.com/naoina/toml/LICENSE
generated
vendored
19
Godeps/_workspace/src/github.com/naoina/toml/LICENSE
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
Copyright (c) 2014 Naoya Inada <naoina@kuune.org>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
16
Godeps/_workspace/src/github.com/naoina/toml/Makefile
generated
vendored
16
Godeps/_workspace/src/github.com/naoina/toml/Makefile
generated
vendored
|
@ -1,16 +0,0 @@
|
||||||
GO = go
|
|
||||||
PEG = peg
|
|
||||||
|
|
||||||
.SUFFIXES: .peg .peg.go
|
|
||||||
|
|
||||||
.PHONY: all test clean
|
|
||||||
all: parse.peg.go
|
|
||||||
|
|
||||||
.peg.peg.go:
|
|
||||||
$(PEG) -switch -inline $<
|
|
||||||
|
|
||||||
test: all
|
|
||||||
$(GO) test ./...
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) *.peg.go
|
|
364
Godeps/_workspace/src/github.com/naoina/toml/README.md
generated
vendored
364
Godeps/_workspace/src/github.com/naoina/toml/README.md
generated
vendored
|
@ -1,364 +0,0 @@
|
||||||
# TOML parser and encoder library for Golang [![Build Status](https://travis-ci.org/naoina/toml.png?branch=master)](https://travis-ci.org/naoina/toml)
|
|
||||||
|
|
||||||
[TOML](https://github.com/toml-lang/toml) parser and encoder library for [Golang](http://golang.org/).
|
|
||||||
|
|
||||||
This library is compatible with TOML version [v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md).
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
go get -u github.com/naoina/toml
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
The following TOML save as `example.toml`.
|
|
||||||
|
|
||||||
```toml
|
|
||||||
# This is a TOML document. Boom.
|
|
||||||
|
|
||||||
title = "TOML Example"
|
|
||||||
|
|
||||||
[owner]
|
|
||||||
name = "Lance Uppercut"
|
|
||||||
dob = 1979-05-27T07:32:00-08:00 # First class dates? Why not?
|
|
||||||
|
|
||||||
[database]
|
|
||||||
server = "192.168.1.1"
|
|
||||||
ports = [ 8001, 8001, 8002 ]
|
|
||||||
connection_max = 5000
|
|
||||||
enabled = true
|
|
||||||
|
|
||||||
[servers]
|
|
||||||
|
|
||||||
# You can indent as you please. Tabs or spaces. TOML don't care.
|
|
||||||
[servers.alpha]
|
|
||||||
ip = "10.0.0.1"
|
|
||||||
dc = "eqdc10"
|
|
||||||
|
|
||||||
[servers.beta]
|
|
||||||
ip = "10.0.0.2"
|
|
||||||
dc = "eqdc10"
|
|
||||||
|
|
||||||
[clients]
|
|
||||||
data = [ ["gamma", "delta"], [1, 2] ]
|
|
||||||
|
|
||||||
# Line breaks are OK when inside arrays
|
|
||||||
hosts = [
|
|
||||||
"alpha",
|
|
||||||
"omega"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
Then above TOML will mapping to `tomlConfig` struct using `toml.Unmarshal`.
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/naoina/toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
type tomlConfig struct {
|
|
||||||
Title string
|
|
||||||
Owner struct {
|
|
||||||
Name string
|
|
||||||
Dob time.Time
|
|
||||||
}
|
|
||||||
Database struct {
|
|
||||||
Server string
|
|
||||||
Ports []int
|
|
||||||
ConnectionMax uint
|
|
||||||
Enabled bool
|
|
||||||
}
|
|
||||||
Servers map[string]Server
|
|
||||||
Clients struct {
|
|
||||||
Data [][]interface{}
|
|
||||||
Hosts []string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
IP string
|
|
||||||
DC string
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
f, err := os.Open("example.toml")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
buf, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
var config tomlConfig
|
|
||||||
if err := toml.Unmarshal(buf, &config); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// then to use the unmarshaled config...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Mappings
|
|
||||||
|
|
||||||
A key and value of TOML will map to the corresponding field.
|
|
||||||
The fields of struct for mapping must be exported.
|
|
||||||
|
|
||||||
The rules of the mapping of key are following:
|
|
||||||
|
|
||||||
#### Exact matching
|
|
||||||
|
|
||||||
```toml
|
|
||||||
timeout_seconds = 256
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Timeout_seconds int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Camelcase matching
|
|
||||||
|
|
||||||
```toml
|
|
||||||
server_name = "srv1"
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
ServerName string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Uppercase matching
|
|
||||||
|
|
||||||
```toml
|
|
||||||
ip = "10.0.0.1"
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
IP string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
See the following examples for the value mappings.
|
|
||||||
|
|
||||||
### String
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val = "string"
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Integer
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val = 100
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
All types that can be used are following:
|
|
||||||
|
|
||||||
* int8 (from `-128` to `127`)
|
|
||||||
* int16 (from `-32768` to `32767`)
|
|
||||||
* int32 (from `-2147483648` to `2147483647`)
|
|
||||||
* int64 (from `-9223372036854775808` to `9223372036854775807`)
|
|
||||||
* int (same as `int32` on 32bit environment, or `int64` on 64bit environment)
|
|
||||||
* uint8 (from `0` to `255`)
|
|
||||||
* uint16 (from `0` to `65535`)
|
|
||||||
* uint32 (from `0` to `4294967295`)
|
|
||||||
* uint64 (from `0` to `18446744073709551615`)
|
|
||||||
* uint (same as `uint` on 32bit environment, or `uint64` on 64bit environment)
|
|
||||||
|
|
||||||
### Float
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val = 3.1415
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val float32
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
All types that can be used are following:
|
|
||||||
|
|
||||||
* float32
|
|
||||||
* float64
|
|
||||||
|
|
||||||
### Boolean
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val = true
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val bool
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Datetime
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val = 2014-09-28T21:27:39Z
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val time.Time
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Array
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val = ["a", "b", "c"]
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val []string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Also following examples all can be mapped:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
val1 = [1, 2, 3]
|
|
||||||
val2 = [["a", "b"], ["c", "d"]]
|
|
||||||
val3 = [[1, 2, 3], ["a", "b", "c"]]
|
|
||||||
val4 = [[1, 2, 3], [["a", "b"], [true, false]]]
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Val1 []int
|
|
||||||
Val2 [][]string
|
|
||||||
Val3 [][]interface{}
|
|
||||||
Val4 [][]interface{}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Table
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[server]
|
|
||||||
type = "app"
|
|
||||||
|
|
||||||
[server.development]
|
|
||||||
ip = "10.0.0.1"
|
|
||||||
|
|
||||||
[server.production]
|
|
||||||
ip = "10.0.0.2"
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Server map[string]Server
|
|
||||||
}
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
IP string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use the following struct instead of map of struct.
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Server struct {
|
|
||||||
Development Server
|
|
||||||
Production Server
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
IP string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Array of Tables
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[[fruit]]
|
|
||||||
name = "apple"
|
|
||||||
|
|
||||||
[fruit.physical]
|
|
||||||
color = "red"
|
|
||||||
shape = "round"
|
|
||||||
|
|
||||||
[[fruit.variety]]
|
|
||||||
name = "red delicious"
|
|
||||||
|
|
||||||
[[fruit.variety]]
|
|
||||||
name = "granny smith"
|
|
||||||
|
|
||||||
[[fruit]]
|
|
||||||
name = "banana"
|
|
||||||
|
|
||||||
[[fruit.variety]]
|
|
||||||
name = "plantain"
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Config struct {
|
|
||||||
Fruit []struct {
|
|
||||||
Name string
|
|
||||||
Physical struct {
|
|
||||||
Color string
|
|
||||||
Shape string
|
|
||||||
}
|
|
||||||
Variety []struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using `toml.UnmarshalTOML` interface
|
|
||||||
|
|
||||||
```toml
|
|
||||||
duration = "10s"
|
|
||||||
```
|
|
||||||
|
|
||||||
```go
|
|
||||||
import time
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Duration Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
type Duration struct {
|
|
||||||
time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Duration) UnmarshalTOML(data []byte) error {
|
|
||||||
d.Duration, err := time.ParseDuration(string(data))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## API documentation
|
|
||||||
|
|
||||||
See [Godoc](http://godoc.org/github.com/naoina/toml).
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
184
Godeps/_workspace/src/github.com/naoina/toml/ast/ast.go
generated
vendored
184
Godeps/_workspace/src/github.com/naoina/toml/ast/ast.go
generated
vendored
|
@ -1,184 +0,0 @@
|
||||||
package ast
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Position struct {
|
|
||||||
Begin int
|
|
||||||
End int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Value interface {
|
|
||||||
Pos() int
|
|
||||||
End() int
|
|
||||||
Source() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type String struct {
|
|
||||||
Position Position
|
|
||||||
Value string
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) Pos() int {
|
|
||||||
return s.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) End() int {
|
|
||||||
return s.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *String) Source() string {
|
|
||||||
return string(s.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Integer struct {
|
|
||||||
Position Position
|
|
||||||
Value string
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Integer) Pos() int {
|
|
||||||
return i.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Integer) End() int {
|
|
||||||
return i.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Integer) Source() string {
|
|
||||||
return string(i.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Integer) Int() (int64, error) {
|
|
||||||
return strconv.ParseInt(i.Value, 10, 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Float struct {
|
|
||||||
Position Position
|
|
||||||
Value string
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Float) Pos() int {
|
|
||||||
return f.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Float) End() int {
|
|
||||||
return f.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Float) Source() string {
|
|
||||||
return string(f.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Float) Float() (float64, error) {
|
|
||||||
return strconv.ParseFloat(f.Value, 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Boolean struct {
|
|
||||||
Position Position
|
|
||||||
Value string
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Boolean) Pos() int {
|
|
||||||
return b.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Boolean) End() int {
|
|
||||||
return b.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Boolean) Source() string {
|
|
||||||
return string(b.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Boolean) Boolean() (bool, error) {
|
|
||||||
return strconv.ParseBool(b.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Datetime struct {
|
|
||||||
Position Position
|
|
||||||
Value string
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Datetime) Pos() int {
|
|
||||||
return d.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Datetime) End() int {
|
|
||||||
return d.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Datetime) Source() string {
|
|
||||||
return string(d.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Datetime) Time() (time.Time, error) {
|
|
||||||
return time.Parse(time.RFC3339Nano, d.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Array struct {
|
|
||||||
Position Position
|
|
||||||
Value []Value
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Array) Pos() int {
|
|
||||||
return a.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Array) End() int {
|
|
||||||
return a.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Array) Source() string {
|
|
||||||
return string(a.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type TableType uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
TableTypeNormal TableType = iota
|
|
||||||
TableTypeArray
|
|
||||||
)
|
|
||||||
|
|
||||||
var tableTypes = [...]string{
|
|
||||||
"normal",
|
|
||||||
"array",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t TableType) String() string {
|
|
||||||
return tableTypes[t]
|
|
||||||
}
|
|
||||||
|
|
||||||
type Table struct {
|
|
||||||
Position Position
|
|
||||||
Line int
|
|
||||||
Name string
|
|
||||||
Fields map[string]interface{}
|
|
||||||
Type TableType
|
|
||||||
Data []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Table) Pos() int {
|
|
||||||
return t.Position.Begin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Table) End() int {
|
|
||||||
return t.Position.End
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Table) Source() string {
|
|
||||||
return string(t.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type KeyValue struct {
|
|
||||||
Key string
|
|
||||||
Value Value
|
|
||||||
Line int
|
|
||||||
}
|
|
649
Godeps/_workspace/src/github.com/naoina/toml/decode.go
generated
vendored
649
Godeps/_workspace/src/github.com/naoina/toml/decode.go
generated
vendored
|
@ -1,649 +0,0 @@
|
||||||
package toml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/toml/ast"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
tableSeparator = '.'
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
escapeReplacer = strings.NewReplacer(
|
|
||||||
"\b", "\\n",
|
|
||||||
"\f", "\\f",
|
|
||||||
"\n", "\\n",
|
|
||||||
"\r", "\\r",
|
|
||||||
"\t", "\\t",
|
|
||||||
)
|
|
||||||
underscoreReplacer = strings.NewReplacer(
|
|
||||||
"_", "",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unmarshal parses the TOML data and stores the result in the value pointed to by v.
|
|
||||||
//
|
|
||||||
// Unmarshal will mapped to v that according to following rules:
|
|
||||||
//
|
|
||||||
// TOML strings to string
|
|
||||||
// TOML integers to any int type
|
|
||||||
// TOML floats to float32 or float64
|
|
||||||
// TOML booleans to bool
|
|
||||||
// TOML datetimes to time.Time
|
|
||||||
// TOML arrays to any type of slice or []interface{}
|
|
||||||
// TOML tables to struct
|
|
||||||
// TOML array of tables to slice of struct
|
|
||||||
func Unmarshal(data []byte, v interface{}) error {
|
|
||||||
table, err := Parse(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := UnmarshalTable(table, v); err != nil {
|
|
||||||
return fmt.Errorf("toml: unmarshal: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshaler is the interface implemented by objects that can unmarshal a
|
|
||||||
// TOML description of themselves.
|
|
||||||
// The input can be assumed to be a valid encoding of a TOML value.
|
|
||||||
// UnmarshalJSON must copy the TOML data if it wishes to retain the data after
|
|
||||||
// returning.
|
|
||||||
type Unmarshaler interface {
|
|
||||||
UnmarshalTOML([]byte) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalTable applies the contents of an ast.Table to the value pointed at by v.
|
|
||||||
//
|
|
||||||
// UnmarshalTable will mapped to v that according to following rules:
|
|
||||||
//
|
|
||||||
// TOML strings to string
|
|
||||||
// TOML integers to any int type
|
|
||||||
// TOML floats to float32 or float64
|
|
||||||
// TOML booleans to bool
|
|
||||||
// TOML datetimes to time.Time
|
|
||||||
// TOML arrays to any type of slice or []interface{}
|
|
||||||
// TOML tables to struct
|
|
||||||
// TOML array of tables to slice of struct
|
|
||||||
func UnmarshalTable(t *ast.Table, v interface{}) (err error) {
|
|
||||||
if v == nil {
|
|
||||||
return fmt.Errorf("v must not be nil")
|
|
||||||
}
|
|
||||||
rv := reflect.ValueOf(v)
|
|
||||||
if kind := rv.Kind(); kind != reflect.Ptr && kind != reflect.Map {
|
|
||||||
return fmt.Errorf("v must be a pointer or map")
|
|
||||||
}
|
|
||||||
for rv.Kind() == reflect.Ptr {
|
|
||||||
rv = rv.Elem()
|
|
||||||
}
|
|
||||||
for key, val := range t.Fields {
|
|
||||||
switch av := val.(type) {
|
|
||||||
case *ast.KeyValue:
|
|
||||||
fv, fieldName, found := findField(rv, key)
|
|
||||||
if !found {
|
|
||||||
return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v)
|
|
||||||
}
|
|
||||||
switch fv.Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
mv := reflect.New(fv.Type().Elem()).Elem()
|
|
||||||
if err := UnmarshalTable(t, mv.Addr().Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fv.SetMapIndex(reflect.ValueOf(fieldName), mv)
|
|
||||||
default:
|
|
||||||
if err := setValue(fv, av.Value); err != nil {
|
|
||||||
return fmt.Errorf("line %d: %v.%s: %v", av.Line, rv.Type(), fieldName, err)
|
|
||||||
}
|
|
||||||
if rv.Kind() == reflect.Map {
|
|
||||||
rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *ast.Table:
|
|
||||||
fv, fieldName, found := findField(rv, key)
|
|
||||||
if !found {
|
|
||||||
return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v)
|
|
||||||
}
|
|
||||||
if err, ok := setUnmarshaler(fv, string(av.Data)); ok {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for fv.Kind() == reflect.Ptr {
|
|
||||||
fv.Set(reflect.New(fv.Type().Elem()))
|
|
||||||
fv = fv.Elem()
|
|
||||||
}
|
|
||||||
switch fv.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
vv := reflect.New(fv.Type()).Elem()
|
|
||||||
if err := UnmarshalTable(av, vv.Addr().Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fv.Set(vv)
|
|
||||||
if rv.Kind() == reflect.Map {
|
|
||||||
rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
mv := reflect.MakeMap(fv.Type())
|
|
||||||
if err := UnmarshalTable(av, mv.Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fv.Set(mv)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("line %d: `%v.%s' must be struct or map, but %v given", av.Line, rv.Type(), fieldName, fv.Kind())
|
|
||||||
}
|
|
||||||
case []*ast.Table:
|
|
||||||
fv, fieldName, found := findField(rv, key)
|
|
||||||
if !found {
|
|
||||||
return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av[0].Line, key, v)
|
|
||||||
}
|
|
||||||
data := make([]string, 0, len(av))
|
|
||||||
for _, tbl := range av {
|
|
||||||
data = append(data, string(tbl.Data))
|
|
||||||
}
|
|
||||||
if err, ok := setUnmarshaler(fv, strings.Join(data, "\n")); ok {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t := fv.Type().Elem()
|
|
||||||
pc := 0
|
|
||||||
for ; t.Kind() == reflect.Ptr; pc++ {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
if fv.Kind() != reflect.Slice {
|
|
||||||
return fmt.Errorf("line %d: `%v.%s' must be slice type, but %v given", av[0].Line, rv.Type(), fieldName, fv.Kind())
|
|
||||||
}
|
|
||||||
for _, tbl := range av {
|
|
||||||
var vv reflect.Value
|
|
||||||
switch t.Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
vv = reflect.MakeMap(t)
|
|
||||||
if err := UnmarshalTable(tbl, vv.Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
vv = reflect.New(t).Elem()
|
|
||||||
if err := UnmarshalTable(tbl, vv.Addr().Interface()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < pc; i++ {
|
|
||||||
vv = vv.Addr()
|
|
||||||
pv := reflect.New(vv.Type()).Elem()
|
|
||||||
pv.Set(vv)
|
|
||||||
vv = pv
|
|
||||||
}
|
|
||||||
fv.Set(reflect.Append(fv, vv))
|
|
||||||
}
|
|
||||||
if rv.Kind() == reflect.Map {
|
|
||||||
rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("BUG: unknown type `%T'", t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setUnmarshaler(lhs reflect.Value, data string) (error, bool) {
|
|
||||||
for lhs.Kind() == reflect.Ptr {
|
|
||||||
lhs.Set(reflect.New(lhs.Type().Elem()))
|
|
||||||
lhs = lhs.Elem()
|
|
||||||
}
|
|
||||||
if lhs.CanAddr() {
|
|
||||||
if u, ok := lhs.Addr().Interface().(Unmarshaler); ok {
|
|
||||||
return u.UnmarshalTOML([]byte(data)), true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func setValue(lhs reflect.Value, val ast.Value) error {
|
|
||||||
for lhs.Kind() == reflect.Ptr {
|
|
||||||
lhs.Set(reflect.New(lhs.Type().Elem()))
|
|
||||||
lhs = lhs.Elem()
|
|
||||||
}
|
|
||||||
if err, ok := setUnmarshaler(lhs, val.Source()); ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch v := val.(type) {
|
|
||||||
case *ast.Integer:
|
|
||||||
if err := setInt(lhs, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.Float:
|
|
||||||
if err := setFloat(lhs, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.String:
|
|
||||||
if err := setString(lhs, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.Boolean:
|
|
||||||
if err := setBoolean(lhs, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.Datetime:
|
|
||||||
if err := setDatetime(lhs, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case *ast.Array:
|
|
||||||
if err := setArray(lhs, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInt(fv reflect.Value, v *ast.Integer) error {
|
|
||||||
i, err := v.Int()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch fv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
if fv.OverflowInt(i) {
|
|
||||||
return &errorOutOfRange{fv.Kind(), i}
|
|
||||||
}
|
|
||||||
fv.SetInt(i)
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
fv.SetUint(uint64(i))
|
|
||||||
case reflect.Interface:
|
|
||||||
fv.Set(reflect.ValueOf(i))
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("`%v' is not any types of int", fv.Type())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFloat(fv reflect.Value, v *ast.Float) error {
|
|
||||||
f, err := v.Float()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch fv.Kind() {
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
if fv.OverflowFloat(f) {
|
|
||||||
return &errorOutOfRange{fv.Kind(), f}
|
|
||||||
}
|
|
||||||
fv.SetFloat(f)
|
|
||||||
case reflect.Interface:
|
|
||||||
fv.Set(reflect.ValueOf(f))
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("`%v' is not float32 or float64", fv.Type())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setString(fv reflect.Value, v *ast.String) error {
|
|
||||||
return set(fv, v.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setBoolean(fv reflect.Value, v *ast.Boolean) error {
|
|
||||||
b, err := v.Boolean()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return set(fv, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setDatetime(fv reflect.Value, v *ast.Datetime) error {
|
|
||||||
tm, err := v.Time()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return set(fv, tm)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setArray(fv reflect.Value, v *ast.Array) error {
|
|
||||||
if len(v.Value) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
typ := reflect.TypeOf(v.Value[0])
|
|
||||||
for _, vv := range v.Value[1:] {
|
|
||||||
if typ != reflect.TypeOf(vv) {
|
|
||||||
return fmt.Errorf("array cannot contain multiple types")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sliceType := fv.Type()
|
|
||||||
if fv.Kind() == reflect.Interface {
|
|
||||||
sliceType = reflect.SliceOf(sliceType)
|
|
||||||
}
|
|
||||||
slice := reflect.MakeSlice(sliceType, 0, len(v.Value))
|
|
||||||
t := sliceType.Elem()
|
|
||||||
for _, vv := range v.Value {
|
|
||||||
tmp := reflect.New(t).Elem()
|
|
||||||
if err := setValue(tmp, vv); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
slice = reflect.Append(slice, tmp)
|
|
||||||
}
|
|
||||||
fv.Set(slice)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func set(fv reflect.Value, v interface{}) error {
|
|
||||||
rhs := reflect.ValueOf(v)
|
|
||||||
if !rhs.Type().AssignableTo(fv.Type()) {
|
|
||||||
return fmt.Errorf("`%v' type is not assignable to `%v' type", rhs.Type(), fv.Type())
|
|
||||||
}
|
|
||||||
fv.Set(rhs)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type stack struct {
|
|
||||||
key string
|
|
||||||
table *ast.Table
|
|
||||||
}
|
|
||||||
|
|
||||||
type toml struct {
|
|
||||||
table *ast.Table
|
|
||||||
line int
|
|
||||||
currentTable *ast.Table
|
|
||||||
s string
|
|
||||||
key string
|
|
||||||
val ast.Value
|
|
||||||
arr *array
|
|
||||||
tableMap map[string]*ast.Table
|
|
||||||
stack []*stack
|
|
||||||
skip bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) init() {
|
|
||||||
p.line = 1
|
|
||||||
p.table = &ast.Table{
|
|
||||||
Line: p.line,
|
|
||||||
Type: ast.TableTypeNormal,
|
|
||||||
}
|
|
||||||
p.tableMap = map[string]*ast.Table{
|
|
||||||
"": p.table,
|
|
||||||
}
|
|
||||||
p.currentTable = p.table
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) Error(err error) {
|
|
||||||
panic(convertError{fmt.Errorf("toml: line %d: %v", p.line, err)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetTime(begin, end int) {
|
|
||||||
p.val = &ast.Datetime{
|
|
||||||
Position: ast.Position{Begin: begin, End: end},
|
|
||||||
Data: p.buffer[begin:end],
|
|
||||||
Value: string(p.buffer[begin:end]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetFloat64(begin, end int) {
|
|
||||||
p.val = &ast.Float{
|
|
||||||
Position: ast.Position{Begin: begin, End: end},
|
|
||||||
Data: p.buffer[begin:end],
|
|
||||||
Value: underscoreReplacer.Replace(string(p.buffer[begin:end])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetInt64(begin, end int) {
|
|
||||||
p.val = &ast.Integer{
|
|
||||||
Position: ast.Position{Begin: begin, End: end},
|
|
||||||
Data: p.buffer[begin:end],
|
|
||||||
Value: underscoreReplacer.Replace(string(p.buffer[begin:end])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetString(begin, end int) {
|
|
||||||
p.val = &ast.String{
|
|
||||||
Position: ast.Position{Begin: begin, End: end},
|
|
||||||
Data: p.buffer[begin:end],
|
|
||||||
Value: p.s,
|
|
||||||
}
|
|
||||||
p.s = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetBool(begin, end int) {
|
|
||||||
p.val = &ast.Boolean{
|
|
||||||
Position: ast.Position{Begin: begin, End: end},
|
|
||||||
Data: p.buffer[begin:end],
|
|
||||||
Value: string(p.buffer[begin:end]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) StartArray() {
|
|
||||||
if p.arr == nil {
|
|
||||||
p.arr = &array{line: p.line, current: &ast.Array{}}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.arr.child = &array{parent: p.arr, line: p.line, current: &ast.Array{}}
|
|
||||||
p.arr = p.arr.child
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) AddArrayVal() {
|
|
||||||
if p.arr.current == nil {
|
|
||||||
p.arr.current = &ast.Array{}
|
|
||||||
}
|
|
||||||
p.arr.current.Value = append(p.arr.current.Value, p.val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetArray(begin, end int) {
|
|
||||||
p.arr.current.Position = ast.Position{Begin: begin, End: end}
|
|
||||||
p.arr.current.Data = p.buffer[begin:end]
|
|
||||||
p.val = p.arr.current
|
|
||||||
p.arr = p.arr.parent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetTable(buf []rune, begin, end int) {
|
|
||||||
p.setTable(p.table, buf, begin, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) setTable(t *ast.Table, buf []rune, begin, end int) {
|
|
||||||
name := string(buf[begin:end])
|
|
||||||
names := splitTableKey(name)
|
|
||||||
if t, exists := p.tableMap[name]; exists {
|
|
||||||
if lt := p.tableMap[names[len(names)-1]]; t.Type == ast.TableTypeArray || lt != nil && lt.Type == ast.TableTypeNormal {
|
|
||||||
p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t, err := p.lookupTable(t, names)
|
|
||||||
if err != nil {
|
|
||||||
p.Error(err)
|
|
||||||
}
|
|
||||||
p.currentTable = t
|
|
||||||
p.tableMap[name] = p.currentTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *tomlParser) SetTableString(begin, end int) {
|
|
||||||
p.currentTable.Data = p.buffer[begin:end]
|
|
||||||
|
|
||||||
p.currentTable.Position.Begin = begin
|
|
||||||
p.currentTable.Position.End = end
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetArrayTable(buf []rune, begin, end int) {
|
|
||||||
p.setArrayTable(p.table, buf, begin, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) setArrayTable(t *ast.Table, buf []rune, begin, end int) {
|
|
||||||
name := string(buf[begin:end])
|
|
||||||
if t, exists := p.tableMap[name]; exists && t.Type == ast.TableTypeNormal {
|
|
||||||
p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line))
|
|
||||||
}
|
|
||||||
names := splitTableKey(name)
|
|
||||||
t, err := p.lookupTable(t, names[:len(names)-1])
|
|
||||||
if err != nil {
|
|
||||||
p.Error(err)
|
|
||||||
}
|
|
||||||
last := names[len(names)-1]
|
|
||||||
tbl := &ast.Table{
|
|
||||||
Position: ast.Position{begin, end},
|
|
||||||
Line: p.line,
|
|
||||||
Name: last,
|
|
||||||
Type: ast.TableTypeArray,
|
|
||||||
}
|
|
||||||
switch v := t.Fields[last].(type) {
|
|
||||||
case nil:
|
|
||||||
if t.Fields == nil {
|
|
||||||
t.Fields = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
t.Fields[last] = []*ast.Table{tbl}
|
|
||||||
case []*ast.Table:
|
|
||||||
t.Fields[last] = append(v, tbl)
|
|
||||||
case *ast.KeyValue:
|
|
||||||
p.Error(fmt.Errorf("key `%s' is in conflict with line %d", last, v.Line))
|
|
||||||
default:
|
|
||||||
p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", last, v))
|
|
||||||
}
|
|
||||||
p.currentTable = tbl
|
|
||||||
p.tableMap[name] = p.currentTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) StartInlineTable() {
|
|
||||||
p.skip = false
|
|
||||||
p.stack = append(p.stack, &stack{p.key, p.currentTable})
|
|
||||||
buf := []rune(p.key)
|
|
||||||
if p.arr == nil {
|
|
||||||
p.setTable(p.currentTable, buf, 0, len(buf))
|
|
||||||
} else {
|
|
||||||
p.setArrayTable(p.currentTable, buf, 0, len(buf))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) EndInlineTable() {
|
|
||||||
st := p.stack[len(p.stack)-1]
|
|
||||||
p.key, p.currentTable = st.key, st.table
|
|
||||||
p.stack[len(p.stack)-1] = nil
|
|
||||||
p.stack = p.stack[:len(p.stack)-1]
|
|
||||||
p.skip = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) AddLineCount(i int) {
|
|
||||||
p.line += i
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetKey(buf []rune, begin, end int) {
|
|
||||||
p.key = string(buf[begin:end])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) AddKeyValue() {
|
|
||||||
if p.skip {
|
|
||||||
p.skip = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if val, exists := p.currentTable.Fields[p.key]; exists {
|
|
||||||
switch v := val.(type) {
|
|
||||||
case *ast.Table:
|
|
||||||
p.Error(fmt.Errorf("key `%s' is in conflict with %v table in line %d", p.key, v.Type, v.Line))
|
|
||||||
case *ast.KeyValue:
|
|
||||||
p.Error(fmt.Errorf("key `%s' is in conflict with line %d", p.key, v.Line))
|
|
||||||
default:
|
|
||||||
p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", p.key, v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.currentTable.Fields == nil {
|
|
||||||
p.currentTable.Fields = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
p.currentTable.Fields[p.key] = &ast.KeyValue{
|
|
||||||
Key: p.key,
|
|
||||||
Value: p.val,
|
|
||||||
Line: p.line,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetBasicString(buf []rune, begin, end int) {
|
|
||||||
p.s = p.unquote(string(buf[begin:end]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetMultilineString() {
|
|
||||||
p.s = p.unquote(`"` + escapeReplacer.Replace(strings.TrimLeft(p.s, "\r\n")) + `"`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) AddMultilineBasicBody(buf []rune, begin, end int) {
|
|
||||||
p.s += string(buf[begin:end])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetLiteralString(buf []rune, begin, end int) {
|
|
||||||
p.s = string(buf[begin:end])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) SetMultilineLiteralString(buf []rune, begin, end int) {
|
|
||||||
p.s = strings.TrimLeft(string(buf[begin:end]), "\r\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) unquote(s string) string {
|
|
||||||
s, err := strconv.Unquote(s)
|
|
||||||
if err != nil {
|
|
||||||
p.Error(err)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *toml) lookupTable(t *ast.Table, keys []string) (*ast.Table, error) {
|
|
||||||
for _, s := range keys {
|
|
||||||
val, exists := t.Fields[s]
|
|
||||||
if !exists {
|
|
||||||
tbl := &ast.Table{
|
|
||||||
Line: p.line,
|
|
||||||
Name: s,
|
|
||||||
Type: ast.TableTypeNormal,
|
|
||||||
}
|
|
||||||
if t.Fields == nil {
|
|
||||||
t.Fields = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
t.Fields[s] = tbl
|
|
||||||
t = tbl
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch v := val.(type) {
|
|
||||||
case *ast.Table:
|
|
||||||
t = v
|
|
||||||
case []*ast.Table:
|
|
||||||
t = v[len(v)-1]
|
|
||||||
case *ast.KeyValue:
|
|
||||||
return nil, fmt.Errorf("key `%s' is in conflict with line %d", s, v.Line)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", s, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func splitTableKey(tk string) []string {
|
|
||||||
key := make([]byte, 0, 1)
|
|
||||||
keys := make([]string, 0, 1)
|
|
||||||
inQuote := false
|
|
||||||
for i := 0; i < len(tk); i++ {
|
|
||||||
k := tk[i]
|
|
||||||
switch {
|
|
||||||
case k == tableSeparator && !inQuote:
|
|
||||||
keys = append(keys, string(key))
|
|
||||||
key = key[:0] // reuse buffer.
|
|
||||||
case k == '"':
|
|
||||||
inQuote = !inQuote
|
|
||||||
case (k == ' ' || k == '\t') && !inQuote:
|
|
||||||
// skip.
|
|
||||||
default:
|
|
||||||
key = append(key, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keys = append(keys, string(key))
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
type convertError struct {
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e convertError) Error() string {
|
|
||||||
return e.err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
type array struct {
|
|
||||||
parent *array
|
|
||||||
child *array
|
|
||||||
current *ast.Array
|
|
||||||
line int
|
|
||||||
}
|
|
49
Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go
generated
vendored
49
Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go
generated
vendored
|
@ -1,49 +0,0 @@
|
||||||
package toml_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BenchmarkUnmarshal(b *testing.B) {
|
|
||||||
var v struct {
|
|
||||||
Title string
|
|
||||||
Owner struct {
|
|
||||||
Name string
|
|
||||||
Organization string
|
|
||||||
Bio string
|
|
||||||
Dob time.Time
|
|
||||||
}
|
|
||||||
Database struct {
|
|
||||||
Server string
|
|
||||||
Ports []int
|
|
||||||
ConnectionMax int
|
|
||||||
Enabled bool
|
|
||||||
}
|
|
||||||
Servers struct {
|
|
||||||
Alpha struct {
|
|
||||||
IP string
|
|
||||||
DC string
|
|
||||||
}
|
|
||||||
Beta struct {
|
|
||||||
IP string
|
|
||||||
DC string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Clients struct {
|
|
||||||
Data []interface{}
|
|
||||||
Hosts []string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data, err := loadTestData()
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
if err := toml.Unmarshal(data, &v); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1083
Godeps/_workspace/src/github.com/naoina/toml/decode_test.go
generated
vendored
1083
Godeps/_workspace/src/github.com/naoina/toml/decode_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
211
Godeps/_workspace/src/github.com/naoina/toml/encode.go
generated
vendored
211
Godeps/_workspace/src/github.com/naoina/toml/encode.go
generated
vendored
|
@ -1,211 +0,0 @@
|
||||||
package toml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go/ast"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/go-stringutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
tagOmitempty = "omitempty"
|
|
||||||
tagSkip = "-"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Marshal returns the TOML encoding of v.
|
|
||||||
//
|
|
||||||
// Struct values encode as TOML. Each exported struct field becomes a field of
|
|
||||||
// the TOML structure unless
|
|
||||||
// - the field's tag is "-", or
|
|
||||||
// - the field is empty and its tag specifies the "omitempty" option.
|
|
||||||
// The "toml" key in the struct field's tag value is the key name, followed by
|
|
||||||
// an optional comma and options. Examples:
|
|
||||||
//
|
|
||||||
// // Field is ignored by this package.
|
|
||||||
// Field int `toml:"-"`
|
|
||||||
//
|
|
||||||
// // Field appears in TOML as key "myName".
|
|
||||||
// Field int `toml:"myName"`
|
|
||||||
//
|
|
||||||
// // Field appears in TOML as key "myName" and the field is omitted from the
|
|
||||||
// // result of encoding if its value is empty.
|
|
||||||
// Field int `toml:"myName,omitempty"`
|
|
||||||
//
|
|
||||||
// // Field appears in TOML as key "field", but the field is skipped if
|
|
||||||
// // empty.
|
|
||||||
// // Note the leading comma.
|
|
||||||
// Field int `toml:",omitempty"`
|
|
||||||
func Marshal(v interface{}) ([]byte, error) {
|
|
||||||
return marshal(nil, "", reflect.ValueOf(v), false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshaler is the interface implemented by objects that can marshal themshelves into valid TOML.
|
|
||||||
type Marshaler interface {
|
|
||||||
MarshalTOML() ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshal(buf []byte, prefix string, rv reflect.Value, inArray, arrayTable bool) ([]byte, error) {
|
|
||||||
rt := rv.Type()
|
|
||||||
for i := 0; i < rv.NumField(); i++ {
|
|
||||||
ft := rt.Field(i)
|
|
||||||
if !ast.IsExported(ft.Name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
colName, rest := extractTag(rt.Field(i).Tag.Get(fieldTagName))
|
|
||||||
if colName == tagSkip {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if colName == "" {
|
|
||||||
colName = stringutil.ToSnakeCase(ft.Name)
|
|
||||||
}
|
|
||||||
fv := rv.Field(i)
|
|
||||||
switch rest {
|
|
||||||
case tagOmitempty:
|
|
||||||
if fv.Interface() == reflect.Zero(ft.Type).Interface() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
if buf, err = encodeValue(buf, prefix, colName, fv, inArray, arrayTable); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeValue(buf []byte, prefix, name string, fv reflect.Value, inArray, arrayTable bool) ([]byte, error) {
|
|
||||||
switch t := fv.Interface().(type) {
|
|
||||||
case Marshaler:
|
|
||||||
b, err := t.MarshalTOML()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return appendNewline(append(appendKey(buf, name, inArray, arrayTable), b...), inArray, arrayTable), nil
|
|
||||||
case time.Time:
|
|
||||||
return appendNewline(encodeTime(appendKey(buf, name, inArray, arrayTable), t), inArray, arrayTable), nil
|
|
||||||
}
|
|
||||||
switch fv.Kind() {
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return appendNewline(encodeInt(appendKey(buf, name, inArray, arrayTable), fv.Int()), inArray, arrayTable), nil
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
return appendNewline(encodeUint(appendKey(buf, name, inArray, arrayTable), fv.Uint()), inArray, arrayTable), nil
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return appendNewline(encodeFloat(appendKey(buf, name, inArray, arrayTable), fv.Float()), inArray, arrayTable), nil
|
|
||||||
case reflect.Bool:
|
|
||||||
return appendNewline(encodeBool(appendKey(buf, name, inArray, arrayTable), fv.Bool()), inArray, arrayTable), nil
|
|
||||||
case reflect.String:
|
|
||||||
return appendNewline(encodeString(appendKey(buf, name, inArray, arrayTable), fv.String()), inArray, arrayTable), nil
|
|
||||||
case reflect.Slice, reflect.Array:
|
|
||||||
ft := fv.Type().Elem()
|
|
||||||
for ft.Kind() == reflect.Ptr {
|
|
||||||
ft = ft.Elem()
|
|
||||||
}
|
|
||||||
if ft.Kind() == reflect.Struct {
|
|
||||||
name := tableName(prefix, name)
|
|
||||||
var err error
|
|
||||||
for i := 0; i < fv.Len(); i++ {
|
|
||||||
if buf, err = marshal(append(append(append(buf, '[', '['), name...), ']', ']', '\n'), name, fv.Index(i), false, true); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf, nil
|
|
||||||
}
|
|
||||||
buf = append(appendKey(buf, name, inArray, arrayTable), '[')
|
|
||||||
var err error
|
|
||||||
for i := 0; i < fv.Len(); i++ {
|
|
||||||
if i != 0 {
|
|
||||||
buf = append(buf, ',')
|
|
||||||
}
|
|
||||||
if buf, err = encodeValue(buf, prefix, name, fv.Index(i), true, false); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return appendNewline(append(buf, ']'), inArray, arrayTable), nil
|
|
||||||
case reflect.Struct:
|
|
||||||
name := tableName(prefix, name)
|
|
||||||
return marshal(append(append(append(buf, '['), name...), ']', '\n'), name, fv, inArray, arrayTable)
|
|
||||||
case reflect.Interface:
|
|
||||||
var err error
|
|
||||||
if buf, err = encodeInterface(appendKey(buf, name, inArray, arrayTable), fv.Interface()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return appendNewline(buf, inArray, arrayTable), nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("toml: marshal: unsupported type %v", fv.Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendKey(buf []byte, key string, inArray, arrayTable bool) []byte {
|
|
||||||
if !inArray {
|
|
||||||
return append(append(buf, key...), '=')
|
|
||||||
}
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendNewline(buf []byte, inArray, arrayTable bool) []byte {
|
|
||||||
if !inArray {
|
|
||||||
return append(buf, '\n')
|
|
||||||
}
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeInterface(buf []byte, v interface{}) ([]byte, error) {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case int:
|
|
||||||
return encodeInt(buf, int64(v)), nil
|
|
||||||
case int8:
|
|
||||||
return encodeInt(buf, int64(v)), nil
|
|
||||||
case int16:
|
|
||||||
return encodeInt(buf, int64(v)), nil
|
|
||||||
case int32:
|
|
||||||
return encodeInt(buf, int64(v)), nil
|
|
||||||
case int64:
|
|
||||||
return encodeInt(buf, v), nil
|
|
||||||
case uint:
|
|
||||||
return encodeUint(buf, uint64(v)), nil
|
|
||||||
case uint8:
|
|
||||||
return encodeUint(buf, uint64(v)), nil
|
|
||||||
case uint16:
|
|
||||||
return encodeUint(buf, uint64(v)), nil
|
|
||||||
case uint32:
|
|
||||||
return encodeUint(buf, uint64(v)), nil
|
|
||||||
case uint64:
|
|
||||||
return encodeUint(buf, v), nil
|
|
||||||
case float32:
|
|
||||||
return encodeFloat(buf, float64(v)), nil
|
|
||||||
case float64:
|
|
||||||
return encodeFloat(buf, v), nil
|
|
||||||
case bool:
|
|
||||||
return encodeBool(buf, v), nil
|
|
||||||
case string:
|
|
||||||
return encodeString(buf, v), nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("toml: marshal: unable to detect a type of value `%v'", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeInt(buf []byte, i int64) []byte {
|
|
||||||
return strconv.AppendInt(buf, i, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeUint(buf []byte, u uint64) []byte {
|
|
||||||
return strconv.AppendUint(buf, u, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeFloat(buf []byte, f float64) []byte {
|
|
||||||
return strconv.AppendFloat(buf, f, 'e', -1, 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeBool(buf []byte, b bool) []byte {
|
|
||||||
return strconv.AppendBool(buf, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeString(buf []byte, s string) []byte {
|
|
||||||
return strconv.AppendQuote(buf, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeTime(buf []byte, t time.Time) []byte {
|
|
||||||
return append(buf, t.Format(time.RFC3339Nano)...)
|
|
||||||
}
|
|
298
Godeps/_workspace/src/github.com/naoina/toml/encode_test.go
generated
vendored
298
Godeps/_workspace/src/github.com/naoina/toml/encode_test.go
generated
vendored
|
@ -1,298 +0,0 @@
|
||||||
package toml_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMarshal(t *testing.T) {
|
|
||||||
for _, v := range []struct {
|
|
||||||
v interface{}
|
|
||||||
expect string
|
|
||||||
}{
|
|
||||||
{struct{ Name string }{"alice"}, "name=\"alice\"\n"},
|
|
||||||
{struct{ Age int }{7}, "age=7\n"},
|
|
||||||
{struct {
|
|
||||||
Name string
|
|
||||||
Age int
|
|
||||||
}{"alice", 7}, "name=\"alice\"\nage=7\n"},
|
|
||||||
{struct {
|
|
||||||
Name string `toml:"-"`
|
|
||||||
Age int
|
|
||||||
}{"alice", 7}, "age=7\n"},
|
|
||||||
{struct {
|
|
||||||
Name string `toml:"my_name"`
|
|
||||||
}{"bob"}, "my_name=\"bob\"\n"},
|
|
||||||
{struct {
|
|
||||||
Name string `toml:"my_name,omitempty"`
|
|
||||||
}{"bob"}, "my_name=\"bob\"\n"},
|
|
||||||
{struct {
|
|
||||||
Name string `toml:",omitempty"`
|
|
||||||
}{"bob"}, "name=\"bob\"\n"},
|
|
||||||
{struct {
|
|
||||||
Name string `toml:",omitempty"`
|
|
||||||
}{""}, ""},
|
|
||||||
} {
|
|
||||||
b, err := toml.Marshal(v.v)
|
|
||||||
var actual interface{} = err
|
|
||||||
var expect interface{} = nil
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`Marshal(%#v) => %#v; want %#v`, v.v, actual, expect)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual = string(b)
|
|
||||||
expect = v.expect
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`Marshal(%#v); v => %#v; want %#v`, v, actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMarshalWhole(t *testing.T) {
|
|
||||||
for _, v := range []struct {
|
|
||||||
v interface{}
|
|
||||||
expect string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
testStruct{
|
|
||||||
Table: Table{
|
|
||||||
Key: "value",
|
|
||||||
Subtable: Subtable{
|
|
||||||
Key: "another value",
|
|
||||||
},
|
|
||||||
Inline: Inline{
|
|
||||||
Name: Name{
|
|
||||||
First: "Tom",
|
|
||||||
Last: "Preston-Werner",
|
|
||||||
},
|
|
||||||
Point: Point{
|
|
||||||
X: 1,
|
|
||||||
Y: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
X: X{},
|
|
||||||
String: String{
|
|
||||||
Basic: Basic{
|
|
||||||
Basic: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.",
|
|
||||||
},
|
|
||||||
Multiline: Multiline{
|
|
||||||
Key1: "One\nTwo",
|
|
||||||
Continued: Continued{
|
|
||||||
Key1: "The quick brown fox jumps over the lazy dog.",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Literal: Literal{
|
|
||||||
Winpath: `C:\Users\nodejs\templates`,
|
|
||||||
Winpath2: `\\ServerX\admin$\system32\`,
|
|
||||||
Quoted: `Tom "Dubs" Preston-Werner`,
|
|
||||||
Regex: `<\i\c*\s*>`,
|
|
||||||
Multiline: LiteralMultiline{
|
|
||||||
Regex2: `I [dw]on't need \d{2} apples`,
|
|
||||||
Lines: "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Integer: Integer{
|
|
||||||
Key1: 99,
|
|
||||||
Key2: 42,
|
|
||||||
Key3: 0,
|
|
||||||
Key4: -17,
|
|
||||||
Underscores: IntegerUnderscores{
|
|
||||||
Key1: 1000,
|
|
||||||
Key2: 5349221,
|
|
||||||
Key3: 12345,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Float: Float{
|
|
||||||
Fractional: Fractional{
|
|
||||||
Key1: 1.0,
|
|
||||||
Key2: 3.1415,
|
|
||||||
Key3: -0.01,
|
|
||||||
},
|
|
||||||
Exponent: Exponent{
|
|
||||||
Key1: 5e22,
|
|
||||||
Key2: 1e6,
|
|
||||||
Key3: -2e-2,
|
|
||||||
},
|
|
||||||
Both: Both{
|
|
||||||
Key: 6.626e-34,
|
|
||||||
},
|
|
||||||
Underscores: FloatUnderscores{
|
|
||||||
Key1: 9224617.445991228313,
|
|
||||||
Key2: 1e100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Boolean: Boolean{
|
|
||||||
True: true,
|
|
||||||
False: false,
|
|
||||||
},
|
|
||||||
Datetime: Datetime{
|
|
||||||
Key1: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T07:32:00Z")),
|
|
||||||
Key2: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00-07:00")),
|
|
||||||
Key3: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00.999999-07:00")),
|
|
||||||
},
|
|
||||||
Array: Array{
|
|
||||||
Key1: []int{1, 2, 3},
|
|
||||||
Key2: []string{"red", "yellow", "green"},
|
|
||||||
Key3: [][]int{{1, 2}, {3, 4, 5}},
|
|
||||||
Key4: [][]interface{}{{int64(1), int64(2)}, {"a", "b", "c"}},
|
|
||||||
Key5: []int{1, 2, 3},
|
|
||||||
Key6: []int{1, 2},
|
|
||||||
},
|
|
||||||
Products: []Product{
|
|
||||||
{Name: "Hammer", Sku: 738594937},
|
|
||||||
{},
|
|
||||||
{Name: "Nail", Sku: 284758393, Color: "gray"},
|
|
||||||
},
|
|
||||||
Fruit: []Fruit{
|
|
||||||
{
|
|
||||||
Name: "apple",
|
|
||||||
Physical: Physical{
|
|
||||||
Color: "red",
|
|
||||||
Shape: "round",
|
|
||||||
},
|
|
||||||
Variety: []Variety{
|
|
||||||
{Name: "red delicious"},
|
|
||||||
{Name: "granny smith"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "banana",
|
|
||||||
Variety: []Variety{
|
|
||||||
{Name: "plantain"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
`[table]
|
|
||||||
key="value"
|
|
||||||
[table.subtable]
|
|
||||||
key="another value"
|
|
||||||
[table.inline]
|
|
||||||
[table.inline.name]
|
|
||||||
first="Tom"
|
|
||||||
last="Preston-Werner"
|
|
||||||
[table.inline.point]
|
|
||||||
x=1
|
|
||||||
y=2
|
|
||||||
[x]
|
|
||||||
[x.y]
|
|
||||||
[x.y.z]
|
|
||||||
[x.y.z.w]
|
|
||||||
[string]
|
|
||||||
[string.basic]
|
|
||||||
basic="I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."
|
|
||||||
[string.multiline]
|
|
||||||
key1="One\nTwo"
|
|
||||||
key2=""
|
|
||||||
key3=""
|
|
||||||
[string.multiline.continued]
|
|
||||||
key1="The quick brown fox jumps over the lazy dog."
|
|
||||||
key2=""
|
|
||||||
key3=""
|
|
||||||
[string.literal]
|
|
||||||
winpath="C:\\Users\\nodejs\\templates"
|
|
||||||
winpath2="\\\\ServerX\\admin$\\system32\\"
|
|
||||||
quoted="Tom \"Dubs\" Preston-Werner"
|
|
||||||
regex="<\\i\\c*\\s*>"
|
|
||||||
[string.literal.multiline]
|
|
||||||
regex2="I [dw]on't need \\d{2} apples"
|
|
||||||
lines="The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n"
|
|
||||||
[integer]
|
|
||||||
key1=99
|
|
||||||
key2=42
|
|
||||||
key3=0
|
|
||||||
key4=-17
|
|
||||||
[integer.underscores]
|
|
||||||
key1=1000
|
|
||||||
key2=5349221
|
|
||||||
key3=12345
|
|
||||||
[float]
|
|
||||||
[float.fractional]
|
|
||||||
key1=1e+00
|
|
||||||
key2=3.1415e+00
|
|
||||||
key3=-1e-02
|
|
||||||
[float.exponent]
|
|
||||||
key1=5e+22
|
|
||||||
key2=1e+06
|
|
||||||
key3=-2e-02
|
|
||||||
[float.both]
|
|
||||||
key=6.626e-34
|
|
||||||
[float.underscores]
|
|
||||||
key1=9.224617445991227e+06
|
|
||||||
key2=1e+100
|
|
||||||
[boolean]
|
|
||||||
true=true
|
|
||||||
false=false
|
|
||||||
[datetime]
|
|
||||||
key1=1979-05-27T07:32:00Z
|
|
||||||
key2=1979-05-27T00:32:00-07:00
|
|
||||||
key3=1979-05-27T00:32:00.999999-07:00
|
|
||||||
[array]
|
|
||||||
key1=[1,2,3]
|
|
||||||
key2=["red","yellow","green"]
|
|
||||||
key3=[[1,2],[3,4,5]]
|
|
||||||
key4=[[1,2],["a","b","c"]]
|
|
||||||
key5=[1,2,3]
|
|
||||||
key6=[1,2]
|
|
||||||
[[products]]
|
|
||||||
name="Hammer"
|
|
||||||
sku=738594937
|
|
||||||
color=""
|
|
||||||
[[products]]
|
|
||||||
name=""
|
|
||||||
sku=0
|
|
||||||
color=""
|
|
||||||
[[products]]
|
|
||||||
name="Nail"
|
|
||||||
sku=284758393
|
|
||||||
color="gray"
|
|
||||||
[[fruit]]
|
|
||||||
name="apple"
|
|
||||||
[fruit.physical]
|
|
||||||
color="red"
|
|
||||||
shape="round"
|
|
||||||
[[fruit.variety]]
|
|
||||||
name="red delicious"
|
|
||||||
[[fruit.variety]]
|
|
||||||
name="granny smith"
|
|
||||||
[[fruit]]
|
|
||||||
name="banana"
|
|
||||||
[fruit.physical]
|
|
||||||
color=""
|
|
||||||
shape=""
|
|
||||||
[[fruit.variety]]
|
|
||||||
name="plantain"
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
b, err := toml.Marshal(v.v)
|
|
||||||
var actual interface{} = err
|
|
||||||
var expect interface{} = nil
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`Marshal(%#v) => %#v; want %#v`, v.v, actual, expect)
|
|
||||||
}
|
|
||||||
actual = string(b)
|
|
||||||
expect = v.expect
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`Marshal(%#v); v => %#v; want %#v`, v.v, actual, expect)
|
|
||||||
}
|
|
||||||
|
|
||||||
// test for reversible.
|
|
||||||
dest := testStruct{}
|
|
||||||
actual = toml.Unmarshal(b, &dest)
|
|
||||||
expect = nil
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`Unmarshal after Marshal => %#v; want %#v`, actual, expect)
|
|
||||||
}
|
|
||||||
actual = dest
|
|
||||||
expect = v.v
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
|
||||||
t.Errorf(`Unmarshal after Marshal => %#v; want %#v`, v, actual, expect)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
31
Godeps/_workspace/src/github.com/naoina/toml/error.go
generated
vendored
31
Godeps/_workspace/src/github.com/naoina/toml/error.go
generated
vendored
|
@ -1,31 +0,0 @@
|
||||||
package toml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (e *parseError) Line() int {
|
|
||||||
tokens := e.p.tokenTree.Error()
|
|
||||||
positions := make([]int, len(tokens)*2)
|
|
||||||
p := 0
|
|
||||||
for _, token := range tokens {
|
|
||||||
positions[p], p = int(token.begin), p+1
|
|
||||||
positions[p], p = int(token.end), p+1
|
|
||||||
}
|
|
||||||
for _, t := range translatePositions(e.p.Buffer, positions) {
|
|
||||||
if e.p.line < t.line {
|
|
||||||
e.p.line = t.line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return e.p.line
|
|
||||||
}
|
|
||||||
|
|
||||||
type errorOutOfRange struct {
|
|
||||||
kind reflect.Kind
|
|
||||||
v interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *errorOutOfRange) Error() string {
|
|
||||||
return fmt.Sprintf("value %d is out of range for `%v` type", err.v, err.kind)
|
|
||||||
}
|
|
54
Godeps/_workspace/src/github.com/naoina/toml/parse.go
generated
vendored
54
Godeps/_workspace/src/github.com/naoina/toml/parse.go
generated
vendored
|
@ -1,54 +0,0 @@
|
||||||
package toml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/naoina/toml/ast"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parse returns an AST representation of TOML.
|
|
||||||
// The toplevel is represented by a table.
|
|
||||||
func Parse(data []byte) (*ast.Table, error) {
|
|
||||||
d := &parseState{p: &tomlParser{Buffer: string(data)}}
|
|
||||||
d.init()
|
|
||||||
|
|
||||||
if err := d.parse(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return d.p.toml.table, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type parseState struct {
|
|
||||||
p *tomlParser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *parseState) init() {
|
|
||||||
d.p.Init()
|
|
||||||
d.p.toml.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *parseState) parse() error {
|
|
||||||
if err := d.p.Parse(); err != nil {
|
|
||||||
if err, ok := err.(*parseError); ok {
|
|
||||||
return fmt.Errorf("toml: line %d: parse error", err.Line())
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return d.execute()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *parseState) execute() (err error) {
|
|
||||||
defer func() {
|
|
||||||
e := recover()
|
|
||||||
if e != nil {
|
|
||||||
cerr, ok := e.(convertError)
|
|
||||||
if !ok {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
err = cerr.err
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
d.p.Execute()
|
|
||||||
return nil
|
|
||||||
}
|
|
138
Godeps/_workspace/src/github.com/naoina/toml/parse.peg
generated
vendored
138
Godeps/_workspace/src/github.com/naoina/toml/parse.peg
generated
vendored
|
@ -1,138 +0,0 @@
|
||||||
package toml
|
|
||||||
|
|
||||||
type tomlParser Peg {
|
|
||||||
toml
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML <- Expression (newline Expression)* newline? !. { _ = buffer }
|
|
||||||
|
|
||||||
Expression <- (
|
|
||||||
<ws table ws comment? (wsnl keyval ws comment?)*> { p.SetTableString(begin, end) }
|
|
||||||
/ ws keyval ws comment?
|
|
||||||
/ ws comment?
|
|
||||||
/ ws
|
|
||||||
)
|
|
||||||
|
|
||||||
newline <- <[\r\n]+> { p.AddLineCount(end - begin) }
|
|
||||||
|
|
||||||
ws <- [ \t]*
|
|
||||||
wsnl <- (
|
|
||||||
[ \t]
|
|
||||||
/ <[\r\n]> { p.AddLineCount(end - begin) }
|
|
||||||
)*
|
|
||||||
|
|
||||||
comment <- '#' <[\t -\0x10FFFF]*>
|
|
||||||
|
|
||||||
keyval <- key ws '=' ws val { p.AddKeyValue() }
|
|
||||||
|
|
||||||
key <- bareKey / quotedKey
|
|
||||||
|
|
||||||
bareKey <- <[0-9A-Za-z\-_]+> { p.SetKey(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
quotedKey <- '"' <basicChar+> '"' { p.SetKey(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
val <- (
|
|
||||||
<datetime> { p.SetTime(begin, end) }
|
|
||||||
/ <float> { p.SetFloat64(begin, end) }
|
|
||||||
/ <integer> { p.SetInt64(begin, end) }
|
|
||||||
/ <string> { p.SetString(begin, end) }
|
|
||||||
/ <boolean> { p.SetBool(begin, end) }
|
|
||||||
/ <array> { p.SetArray(begin, end) }
|
|
||||||
/ inlineTable
|
|
||||||
)
|
|
||||||
|
|
||||||
table <- stdTable / arrayTable
|
|
||||||
|
|
||||||
stdTable <- '[' ws <tableKey> ws ']' { p.SetTable(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
arrayTable <- '[[' ws <tableKey> ws ']]' { p.SetArrayTable(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
inlineTable <- (
|
|
||||||
'{' { p.StartInlineTable() }
|
|
||||||
ws inlineTableKeyValues ws
|
|
||||||
'}' { p.EndInlineTable() }
|
|
||||||
)
|
|
||||||
|
|
||||||
inlineTableKeyValues <- (keyval inlineTableValSep?)*
|
|
||||||
|
|
||||||
tableKey <- key (tableKeySep key)*
|
|
||||||
|
|
||||||
tableKeySep <- ws '.' ws
|
|
||||||
|
|
||||||
inlineTableValSep <- ws ',' ws
|
|
||||||
|
|
||||||
integer <- [\-+]? int
|
|
||||||
int <- [1-9] (digit / '_' digit)+ / digit
|
|
||||||
|
|
||||||
float <- integer (frac exp? / frac? exp)
|
|
||||||
frac <- '.' digit (digit / '_' digit)*
|
|
||||||
exp <- [eE] [\-+]? digit (digit / '_' digit)*
|
|
||||||
|
|
||||||
string <- (
|
|
||||||
mlLiteralString
|
|
||||||
/ literalString
|
|
||||||
/ mlBasicString
|
|
||||||
/ basicString
|
|
||||||
)
|
|
||||||
|
|
||||||
basicString <- <'"' basicChar* '"'> { p.SetBasicString(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
basicChar <- basicUnescaped / escaped
|
|
||||||
escaped <- escape ([btnfr"/\\] / 'u' hexQuad / 'U' hexQuad hexQuad)
|
|
||||||
|
|
||||||
basicUnescaped <- [ -!#-\[\]-\0x10FFFF]
|
|
||||||
|
|
||||||
escape <- '\\'
|
|
||||||
|
|
||||||
mlBasicString <- '"""' mlBasicBody '"""' { p.SetMultilineString() }
|
|
||||||
|
|
||||||
mlBasicBody <- (
|
|
||||||
<basicChar / newline> { p.AddMultilineBasicBody(p.buffer, begin, end) }
|
|
||||||
/ escape newline wsnl
|
|
||||||
)*
|
|
||||||
|
|
||||||
literalString <- "'" <literalChar*> "'" { p.SetLiteralString(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
literalChar <- [\t -&(-\0x10FFFF]
|
|
||||||
|
|
||||||
mlLiteralString <- "'''" <mlLiteralBody> "'''" { p.SetMultilineLiteralString(p.buffer, begin, end) }
|
|
||||||
|
|
||||||
mlLiteralBody <- (!"'''" (mlLiteralChar / newline))*
|
|
||||||
|
|
||||||
mlLiteralChar <- [\t -\0x10FFFF]
|
|
||||||
|
|
||||||
hexdigit <- [0-9A-Fa-f]
|
|
||||||
hexQuad <- hexdigit hexdigit hexdigit hexdigit
|
|
||||||
|
|
||||||
boolean <- 'true' / 'false'
|
|
||||||
|
|
||||||
dateFullYear <- digitQuad
|
|
||||||
dateMonth <- digitDual
|
|
||||||
dateMDay <- digitDual
|
|
||||||
timeHour <- digitDual
|
|
||||||
timeMinute <- digitDual
|
|
||||||
timeSecond <- digitDual
|
|
||||||
timeSecfrac <- '.' digit+
|
|
||||||
timeNumoffset <- [\-+] timeHour ':' timeMinute
|
|
||||||
timeOffset <- 'Z' / timeNumoffset
|
|
||||||
partialTime <- timeHour ':' timeMinute ':' timeSecond timeSecfrac?
|
|
||||||
fullDate <- dateFullYear '-' dateMonth '-' dateMDay
|
|
||||||
fullTime <- partialTime timeOffset
|
|
||||||
datetime <- fullDate 'T' fullTime
|
|
||||||
|
|
||||||
digit <- [0-9]
|
|
||||||
digitDual <- digit digit
|
|
||||||
digitQuad <- digitDual digitDual
|
|
||||||
|
|
||||||
array <- (
|
|
||||||
'[' { p.StartArray() }
|
|
||||||
wsnl arrayValues wsnl
|
|
||||||
']'
|
|
||||||
)
|
|
||||||
|
|
||||||
arrayValues <- (
|
|
||||||
val { p.AddArrayVal() }
|
|
||||||
arraySep? (comment? newline)?
|
|
||||||
)*
|
|
||||||
|
|
||||||
arraySep <- ws ',' wsnl
|
|
3065
Godeps/_workspace/src/github.com/naoina/toml/parse.peg.go
generated
vendored
3065
Godeps/_workspace/src/github.com/naoina/toml/parse.peg.go
generated
vendored
File diff suppressed because it is too large
Load diff
79
Godeps/_workspace/src/github.com/naoina/toml/util.go
generated
vendored
79
Godeps/_workspace/src/github.com/naoina/toml/util.go
generated
vendored
|
@ -1,79 +0,0 @@
|
||||||
package toml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go/ast"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// toCamelCase returns a copy of the string s with all Unicode letters mapped to their camel case.
|
|
||||||
// It will convert to upper case previous letter of '_' and first letter, and remove letter of '_'.
|
|
||||||
func toCamelCase(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
result := make([]rune, 0, len(s))
|
|
||||||
upper := false
|
|
||||||
for _, r := range s {
|
|
||||||
if r == '_' {
|
|
||||||
upper = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if upper {
|
|
||||||
result = append(result, unicode.ToUpper(r))
|
|
||||||
upper = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result = append(result, r)
|
|
||||||
}
|
|
||||||
result[0] = unicode.ToUpper(result[0])
|
|
||||||
return string(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
fieldTagName = "toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
func findField(rv reflect.Value, name string) (field reflect.Value, fieldName string, found bool) {
|
|
||||||
switch rv.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
rt := rv.Type()
|
|
||||||
for i := 0; i < rt.NumField(); i++ {
|
|
||||||
ft := rt.Field(i)
|
|
||||||
if !ast.IsExported(ft.Name) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if col, _ := extractTag(ft.Tag.Get(fieldTagName)); col == name {
|
|
||||||
return rv.Field(i), ft.Name, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, name := range []string{
|
|
||||||
strings.Title(name),
|
|
||||||
toCamelCase(name),
|
|
||||||
strings.ToUpper(name),
|
|
||||||
} {
|
|
||||||
if field := rv.FieldByName(name); field.IsValid() {
|
|
||||||
return field, name, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
return reflect.New(rv.Type().Elem()).Elem(), name, true
|
|
||||||
}
|
|
||||||
return field, "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractTag(tag string) (col, rest string) {
|
|
||||||
tags := strings.SplitN(tag, ",", 2)
|
|
||||||
if len(tags) == 2 {
|
|
||||||
return strings.TrimSpace(tags[0]), strings.TrimSpace(tags[1])
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(tags[0]), ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func tableName(prefix, name string) string {
|
|
||||||
if prefix != "" {
|
|
||||||
return prefix + string(tableSeparator) + name
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/namsral/flag"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/namsral/flag"
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@ var (
|
||||||
DockerHost = os.Getenv("DOCKER_HOST")
|
DockerHost = os.Getenv("DOCKER_HOST")
|
||||||
|
|
||||||
// Docker TLS variables
|
// Docker TLS variables
|
||||||
DockerHostCa = os.Getenv("DOCKER_CA")
|
DockerHostCa = os.Getenv("DOCKER_CA")
|
||||||
DockerHostKey = os.Getenv("DOCKER_KEY")
|
DockerHostKey = os.Getenv("DOCKER_KEY")
|
||||||
DockerHostCert = os.Getenv("DOCKER_CERT")
|
DockerHostCert = os.Getenv("DOCKER_CERT")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -111,8 +111,8 @@ func (r *Runner) Run(w *queue.Work) error {
|
||||||
caCertPool := x509.NewCertPool()
|
caCertPool := x509.NewCertPool()
|
||||||
caCertPool.AppendCertsFromPEM(caCert)
|
caCertPool.AppendCertsFromPEM(caCert)
|
||||||
tlc = &tls.Config{
|
tlc = &tls.Config{
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{cert},
|
||||||
RootCAs: caCertPool,
|
RootCAs: caCertPool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue