Add glide.yaml and vendor deps

This commit is contained in:
Dalton Hubble 2016-12-03 22:43:32 -08:00
parent db918f12ad
commit 5b3d5e81bd
18880 changed files with 5166045 additions and 1 deletions

View 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.

View file

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View file

@ -0,0 +1,25 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["expand.go"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["expand_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = ["//pkg/api:go_default_library"],
)

View file

@ -0,0 +1,102 @@
package expansion
import (
"bytes"
)
const (
operator = '$'
referenceOpener = '('
referenceCloser = ')'
)
// syntaxWrap returns the input string wrapped by the expansion syntax.
func syntaxWrap(input string) string {
return string(operator) + string(referenceOpener) + input + string(referenceCloser)
}
// MappingFuncFor returns a mapping function for use with Expand that
// implements the expansion semantics defined in the expansion spec; it
// returns the input string wrapped in the expansion syntax if no mapping
// for the input is found.
func MappingFuncFor(context ...map[string]string) func(string) string {
return func(input string) string {
for _, vars := range context {
val, ok := vars[input]
if ok {
return val
}
}
return syntaxWrap(input)
}
}
// Expand replaces variable references in the input string according to
// the expansion spec using the given mapping function to resolve the
// values of variables.
func Expand(input string, mapping func(string) string) string {
var buf bytes.Buffer
checkpoint := 0
for cursor := 0; cursor < len(input); cursor++ {
if input[cursor] == operator && cursor+1 < len(input) {
// Copy the portion of the input string since the last
// checkpoint into the buffer
buf.WriteString(input[checkpoint:cursor])
// Attempt to read the variable name as defined by the
// syntax from the input string
read, isVar, advance := tryReadVariableName(input[cursor+1:])
if isVar {
// We were able to read a variable name correctly;
// apply the mapping to the variable name and copy the
// bytes into the buffer
buf.WriteString(mapping(read))
} else {
// Not a variable name; copy the read bytes into the buffer
buf.WriteString(read)
}
// Advance the cursor in the input string to account for
// bytes consumed to read the variable name expression
cursor += advance
// Advance the checkpoint in the input string
checkpoint = cursor + 1
}
}
// Return the buffer and any remaining unwritten bytes in the
// input string.
return buf.String() + input[checkpoint:]
}
// tryReadVariableName attempts to read a variable name from the input
// string and returns the content read from the input, whether that content
// represents a variable name to perform mapping on, and the number of bytes
// consumed in the input string.
//
// The input string is assumed not to contain the initial operator.
func tryReadVariableName(input string) (string, bool, int) {
switch input[0] {
case operator:
// Escaped operator; return it.
return input[0:1], false, 1
case referenceOpener:
// Scan to expression closer
for i := 1; i < len(input); i++ {
if input[i] == referenceCloser {
return input[1:i], true, i + 1
}
}
// Incomplete reference; return it.
return string(operator) + string(referenceOpener), false, 1
default:
// Not the beginning of an expression, ie, an operator
// that doesn't begin an expression. Return the operator
// and the first rune in the string.
return (string(operator) + string(input[0])), false, 1
}
}

View file

@ -0,0 +1,285 @@
package expansion
import (
"testing"
"k8s.io/kubernetes/pkg/api"
)
func TestMapReference(t *testing.T) {
envs := []api.EnvVar{
{
Name: "FOO",
Value: "bar",
},
{
Name: "ZOO",
Value: "$(FOO)-1",
},
{
Name: "BLU",
Value: "$(ZOO)-2",
},
}
declaredEnv := map[string]string{
"FOO": "bar",
"ZOO": "$(FOO)-1",
"BLU": "$(ZOO)-2",
}
serviceEnv := map[string]string{}
mapping := MappingFuncFor(declaredEnv, serviceEnv)
for _, env := range envs {
declaredEnv[env.Name] = Expand(env.Value, mapping)
}
expectedEnv := map[string]string{
"FOO": "bar",
"ZOO": "bar-1",
"BLU": "bar-1-2",
}
for k, v := range expectedEnv {
if e, a := v, declaredEnv[k]; e != a {
t.Errorf("Expected %v, got %v", e, a)
} else {
delete(declaredEnv, k)
}
}
if len(declaredEnv) != 0 {
t.Errorf("Unexpected keys in declared env: %v", declaredEnv)
}
}
func TestMapping(t *testing.T) {
context := map[string]string{
"VAR_A": "A",
"VAR_B": "B",
"VAR_C": "C",
"VAR_REF": "$(VAR_A)",
"VAR_EMPTY": "",
}
mapping := MappingFuncFor(context)
doExpansionTest(t, mapping)
}
func TestMappingDual(t *testing.T) {
context := map[string]string{
"VAR_A": "A",
"VAR_EMPTY": "",
}
context2 := map[string]string{
"VAR_B": "B",
"VAR_C": "C",
"VAR_REF": "$(VAR_A)",
}
mapping := MappingFuncFor(context, context2)
doExpansionTest(t, mapping)
}
func doExpansionTest(t *testing.T, mapping func(string) string) {
cases := []struct {
name string
input string
expected string
}{
{
name: "whole string",
input: "$(VAR_A)",
expected: "A",
},
{
name: "repeat",
input: "$(VAR_A)-$(VAR_A)",
expected: "A-A",
},
{
name: "beginning",
input: "$(VAR_A)-1",
expected: "A-1",
},
{
name: "middle",
input: "___$(VAR_B)___",
expected: "___B___",
},
{
name: "end",
input: "___$(VAR_C)",
expected: "___C",
},
{
name: "compound",
input: "$(VAR_A)_$(VAR_B)_$(VAR_C)",
expected: "A_B_C",
},
{
name: "escape & expand",
input: "$$(VAR_B)_$(VAR_A)",
expected: "$(VAR_B)_A",
},
{
name: "compound escape",
input: "$$(VAR_A)_$$(VAR_B)",
expected: "$(VAR_A)_$(VAR_B)",
},
{
name: "mixed in escapes",
input: "f000-$$VAR_A",
expected: "f000-$VAR_A",
},
{
name: "backslash escape ignored",
input: "foo\\$(VAR_C)bar",
expected: "foo\\Cbar",
},
{
name: "backslash escape ignored",
input: "foo\\\\$(VAR_C)bar",
expected: "foo\\\\Cbar",
},
{
name: "lots of backslashes",
input: "foo\\\\\\\\$(VAR_A)bar",
expected: "foo\\\\\\\\Abar",
},
{
name: "nested var references",
input: "$(VAR_A$(VAR_B))",
expected: "$(VAR_A$(VAR_B))",
},
{
name: "nested var references second type",
input: "$(VAR_A$(VAR_B)",
expected: "$(VAR_A$(VAR_B)",
},
{
name: "value is a reference",
input: "$(VAR_REF)",
expected: "$(VAR_A)",
},
{
name: "value is a reference x 2",
input: "%%$(VAR_REF)--$(VAR_REF)%%",
expected: "%%$(VAR_A)--$(VAR_A)%%",
},
{
name: "empty var",
input: "foo$(VAR_EMPTY)bar",
expected: "foobar",
},
{
name: "unterminated expression",
input: "foo$(VAR_Awhoops!",
expected: "foo$(VAR_Awhoops!",
},
{
name: "expression without operator",
input: "f00__(VAR_A)__",
expected: "f00__(VAR_A)__",
},
{
name: "shell special vars pass through",
input: "$?_boo_$!",
expected: "$?_boo_$!",
},
{
name: "bare operators are ignored",
input: "$VAR_A",
expected: "$VAR_A",
},
{
name: "undefined vars are passed through",
input: "$(VAR_DNE)",
expected: "$(VAR_DNE)",
},
{
name: "multiple (even) operators, var undefined",
input: "$$$$$$(BIG_MONEY)",
expected: "$$$(BIG_MONEY)",
},
{
name: "multiple (even) operators, var defined",
input: "$$$$$$(VAR_A)",
expected: "$$$(VAR_A)",
},
{
name: "multiple (odd) operators, var undefined",
input: "$$$$$$$(GOOD_ODDS)",
expected: "$$$$(GOOD_ODDS)",
},
{
name: "multiple (odd) operators, var defined",
input: "$$$$$$$(VAR_A)",
expected: "$$$A",
},
{
name: "missing open expression",
input: "$VAR_A)",
expected: "$VAR_A)",
},
{
name: "shell syntax ignored",
input: "${VAR_A}",
expected: "${VAR_A}",
},
{
name: "trailing incomplete expression not consumed",
input: "$(VAR_B)_______$(A",
expected: "B_______$(A",
},
{
name: "trailing incomplete expression, no content, is not consumed",
input: "$(VAR_C)_______$(",
expected: "C_______$(",
},
{
name: "operator at end of input string is preserved",
input: "$(VAR_A)foobarzab$",
expected: "Afoobarzab$",
},
{
name: "shell escaped incomplete expr",
input: "foo-\\$(VAR_A",
expected: "foo-\\$(VAR_A",
},
{
name: "lots of $( in middle",
input: "--$($($($($--",
expected: "--$($($($($--",
},
{
name: "lots of $( in beginning",
input: "$($($($($--foo$(",
expected: "$($($($($--foo$(",
},
{
name: "lots of $( at end",
input: "foo0--$($($($(",
expected: "foo0--$($($($(",
},
{
name: "escaped operators in variable names are not escaped",
input: "$(foo$$var)",
expected: "$(foo$$var)",
},
{
name: "newline not expanded",
input: "\n",
expected: "\n",
},
}
for _, tc := range cases {
expanded := Expand(tc.input, mapping)
if e, a := tc.expected, expanded; e != a {
t.Errorf("%v: expected %q, got %q", tc.name, e, a)
}
}
}

View file

@ -0,0 +1,17 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["fields.go"],
tags = ["automanaged"],
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["addr.go"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,27 @@
package netutil
import (
"net/url"
"strings"
)
// FROM: http://golang.org/src/net/http/client.go
// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
// return true if the string includes a port.
func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
// FROM: http://golang.org/src/net/http/transport.go
var portMap = map[string]string{
"http": "80",
"https": "443",
}
// FROM: http://golang.org/src/net/http/transport.go
// canonicalAddr returns url.Host but always with a ":port" suffix
func CanonicalAddr(url *url.URL) string {
addr := url.Host
if !hasPort(addr) {
return addr + ":" + portMap[url.Scheme]
}
return addr
}

View file

@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = [
"deep_equal.go",
"type.go",
],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["deep_equal_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = [],
)

View file

@ -0,0 +1,388 @@
// 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 reflect is a fork of go's standard library reflection package, which
// allows for deep equal with equality functions defined.
package reflect
import (
"fmt"
"reflect"
"strings"
)
// Equalities is a map from type to a function comparing two values of
// that type.
type Equalities map[reflect.Type]reflect.Value
// For convenience, panics on errrors
func EqualitiesOrDie(funcs ...interface{}) Equalities {
e := Equalities{}
if err := e.AddFuncs(funcs...); err != nil {
panic(err)
}
return e
}
// AddFuncs is a shortcut for multiple calls to AddFunc.
func (e Equalities) AddFuncs(funcs ...interface{}) error {
for _, f := range funcs {
if err := e.AddFunc(f); err != nil {
return err
}
}
return nil
}
// AddFunc uses func as an equality function: it must take
// two parameters of the same type, and return a boolean.
func (e Equalities) AddFunc(eqFunc interface{}) error {
fv := reflect.ValueOf(eqFunc)
ft := fv.Type()
if ft.Kind() != reflect.Func {
return fmt.Errorf("expected func, got: %v", ft)
}
if ft.NumIn() != 2 {
return fmt.Errorf("expected three 'in' params, got: %v", ft)
}
if ft.NumOut() != 1 {
return fmt.Errorf("expected one 'out' param, got: %v", ft)
}
if ft.In(0) != ft.In(1) {
return fmt.Errorf("expected arg 1 and 2 to have same type, but got %v", ft)
}
var forReturnType bool
boolType := reflect.TypeOf(forReturnType)
if ft.Out(0) != boolType {
return fmt.Errorf("expected bool return, got: %v", ft)
}
e[ft.In(0)] = fv
return nil
}
// Below here is forked from go's reflect/deepequal.go
// During deepValueEqual, must keep track of checks that are
// in progress. The comparison algorithm assumes that all
// checks in progress are true when it reencounters them.
// Visited comparisons are stored in a map indexed by visit.
type visit struct {
a1 uintptr
a2 uintptr
typ reflect.Type
}
// unexportedTypePanic is thrown when you use this DeepEqual on something that has an
// unexported type. It indicates a programmer error, so should not occur at runtime,
// which is why it's not public and thus impossible to catch.
type unexportedTypePanic []reflect.Type
func (u unexportedTypePanic) Error() string { return u.String() }
func (u unexportedTypePanic) String() string {
strs := make([]string, len(u))
for i, t := range u {
strs[i] = fmt.Sprintf("%v", t)
}
return "an unexported field was encountered, nested like this: " + strings.Join(strs, " -> ")
}
func makeUsefulPanic(v reflect.Value) {
if x := recover(); x != nil {
if u, ok := x.(unexportedTypePanic); ok {
u = append(unexportedTypePanic{v.Type()}, u...)
x = u
}
panic(x)
}
}
// Tests for deep equality using reflected types. The map argument tracks
// comparisons that have already been seen, which allows short circuiting on
// recursive types.
func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool {
defer makeUsefulPanic(v1)
if !v1.IsValid() || !v2.IsValid() {
return v1.IsValid() == v2.IsValid()
}
if v1.Type() != v2.Type() {
return false
}
if fv, ok := e[v1.Type()]; ok {
return fv.Call([]reflect.Value{v1, v2})[0].Bool()
}
hard := func(k reflect.Kind) bool {
switch k {
case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
return true
}
return false
}
if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
addr1 := v1.UnsafeAddr()
addr2 := v2.UnsafeAddr()
if addr1 > addr2 {
// Canonicalize order to reduce number of entries in visited.
addr1, addr2 = addr2, addr1
}
// Short circuit if references are identical ...
if addr1 == addr2 {
return true
}
// ... or already seen
typ := v1.Type()
v := visit{addr1, addr2, typ}
if visited[v] {
return true
}
// Remember for later.
visited[v] = true
}
switch v1.Kind() {
case reflect.Array:
// We don't need to check length here because length is part of
// an array's type, which has already been filtered for.
for i := 0; i < v1.Len(); i++ {
if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) {
return false
}
}
return true
case reflect.Slice:
if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) {
return false
}
if v1.IsNil() || v1.Len() == 0 {
return true
}
if v1.Len() != v2.Len() {
return false
}
if v1.Pointer() == v2.Pointer() {
return true
}
for i := 0; i < v1.Len(); i++ {
if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) {
return false
}
}
return true
case reflect.Interface:
if v1.IsNil() || v2.IsNil() {
return v1.IsNil() == v2.IsNil()
}
return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1)
case reflect.Ptr:
return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1)
case reflect.Struct:
for i, n := 0, v1.NumField(); i < n; i++ {
if !e.deepValueEqual(v1.Field(i), v2.Field(i), visited, depth+1) {
return false
}
}
return true
case reflect.Map:
if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) {
return false
}
if v1.IsNil() || v1.Len() == 0 {
return true
}
if v1.Len() != v2.Len() {
return false
}
if v1.Pointer() == v2.Pointer() {
return true
}
for _, k := range v1.MapKeys() {
if !e.deepValueEqual(v1.MapIndex(k), v2.MapIndex(k), visited, depth+1) {
return false
}
}
return true
case reflect.Func:
if v1.IsNil() && v2.IsNil() {
return true
}
// Can't do better than this:
return false
default:
// Normal equality suffices
if !v1.CanInterface() || !v2.CanInterface() {
panic(unexportedTypePanic{})
}
return v1.Interface() == v2.Interface()
}
}
// DeepEqual is like reflect.DeepEqual, but focused on semantic equality
// instead of memory equality.
//
// It will use e's equality functions if it finds types that match.
//
// An empty slice *is* equal to a nil slice for our purposes; same for maps.
//
// Unexported field members cannot be compared and will cause an imformative panic; you must add an Equality
// function for these types.
func (e Equalities) DeepEqual(a1, a2 interface{}) bool {
if a1 == nil || a2 == nil {
return a1 == a2
}
v1 := reflect.ValueOf(a1)
v2 := reflect.ValueOf(a2)
if v1.Type() != v2.Type() {
return false
}
return e.deepValueEqual(v1, v2, make(map[visit]bool), 0)
}
func (e Equalities) deepValueDerive(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool {
defer makeUsefulPanic(v1)
if !v1.IsValid() || !v2.IsValid() {
return v1.IsValid() == v2.IsValid()
}
if v1.Type() != v2.Type() {
return false
}
if fv, ok := e[v1.Type()]; ok {
return fv.Call([]reflect.Value{v1, v2})[0].Bool()
}
hard := func(k reflect.Kind) bool {
switch k {
case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
return true
}
return false
}
if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
addr1 := v1.UnsafeAddr()
addr2 := v2.UnsafeAddr()
if addr1 > addr2 {
// Canonicalize order to reduce number of entries in visited.
addr1, addr2 = addr2, addr1
}
// Short circuit if references are identical ...
if addr1 == addr2 {
return true
}
// ... or already seen
typ := v1.Type()
v := visit{addr1, addr2, typ}
if visited[v] {
return true
}
// Remember for later.
visited[v] = true
}
switch v1.Kind() {
case reflect.Array:
// We don't need to check length here because length is part of
// an array's type, which has already been filtered for.
for i := 0; i < v1.Len(); i++ {
if !e.deepValueDerive(v1.Index(i), v2.Index(i), visited, depth+1) {
return false
}
}
return true
case reflect.Slice:
if v1.IsNil() || v1.Len() == 0 {
return true
}
if v1.Len() > v2.Len() {
return false
}
if v1.Pointer() == v2.Pointer() {
return true
}
for i := 0; i < v1.Len(); i++ {
if !e.deepValueDerive(v1.Index(i), v2.Index(i), visited, depth+1) {
return false
}
}
return true
case reflect.String:
if v1.Len() == 0 {
return true
}
if v1.Len() > v2.Len() {
return false
}
return v1.String() == v2.String()
case reflect.Interface:
if v1.IsNil() {
return true
}
return e.deepValueDerive(v1.Elem(), v2.Elem(), visited, depth+1)
case reflect.Ptr:
if v1.IsNil() {
return true
}
return e.deepValueDerive(v1.Elem(), v2.Elem(), visited, depth+1)
case reflect.Struct:
for i, n := 0, v1.NumField(); i < n; i++ {
if !e.deepValueDerive(v1.Field(i), v2.Field(i), visited, depth+1) {
return false
}
}
return true
case reflect.Map:
if v1.IsNil() || v1.Len() == 0 {
return true
}
if v1.Len() > v2.Len() {
return false
}
if v1.Pointer() == v2.Pointer() {
return true
}
for _, k := range v1.MapKeys() {
if !e.deepValueDerive(v1.MapIndex(k), v2.MapIndex(k), visited, depth+1) {
return false
}
}
return true
case reflect.Func:
if v1.IsNil() && v2.IsNil() {
return true
}
// Can't do better than this:
return false
default:
// Normal equality suffices
if !v1.CanInterface() || !v2.CanInterface() {
panic(unexportedTypePanic{})
}
return v1.Interface() == v2.Interface()
}
}
// DeepDerivative is similar to DeepEqual except that unset fields in a1 are
// ignored (not compared). This allows us to focus on the fields that matter to
// the semantic comparison.
//
// The unset fields include a nil pointer and an empty string.
func (e Equalities) DeepDerivative(a1, a2 interface{}) bool {
if a1 == nil {
return true
}
v1 := reflect.ValueOf(a1)
v2 := reflect.ValueOf(a2)
if v1.Type() != v2.Type() {
return false
}
return e.deepValueDerive(v1, v2, make(map[visit]bool), 0)
}

View file

@ -0,0 +1,137 @@
// 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 reflect
import (
"testing"
)
func TestEqualities(t *testing.T) {
e := Equalities{}
type Bar struct {
X int
}
type Baz struct {
Y Bar
}
err := e.AddFuncs(
func(a, b int) bool {
return a+1 == b
},
func(a, b Bar) bool {
return a.X*10 == b.X
},
)
if err != nil {
t.Fatalf("Unexpected: %v", err)
}
type Foo struct {
X int
}
table := []struct {
a, b interface{}
equal bool
}{
{1, 2, true},
{2, 1, false},
{"foo", "fo", false},
{"foo", "foo", true},
{"foo", "foobar", false},
{Foo{1}, Foo{2}, true},
{Foo{2}, Foo{1}, false},
{Bar{1}, Bar{10}, true},
{&Bar{1}, &Bar{10}, true},
{Baz{Bar{1}}, Baz{Bar{10}}, true},
{[...]string{}, [...]string{"1", "2", "3"}, false},
{[...]string{"1"}, [...]string{"1", "2", "3"}, false},
{[...]string{"1", "2", "3"}, [...]string{}, false},
{[...]string{"1", "2", "3"}, [...]string{"1", "2", "3"}, true},
{map[string]int{"foo": 1}, map[string]int{}, false},
{map[string]int{"foo": 1}, map[string]int{"foo": 2}, true},
{map[string]int{"foo": 2}, map[string]int{"foo": 1}, false},
{map[string]int{"foo": 1}, map[string]int{"foo": 2, "bar": 6}, false},
{map[string]int{"foo": 1, "bar": 6}, map[string]int{"foo": 2}, false},
{map[string]int{}, map[string]int(nil), true},
{[]string(nil), []string(nil), true},
{[]string{}, []string(nil), true},
{[]string(nil), []string{}, true},
{[]string{"1"}, []string(nil), false},
{[]string{}, []string{"1", "2", "3"}, false},
{[]string{"1"}, []string{"1", "2", "3"}, false},
{[]string{"1", "2", "3"}, []string{}, false},
}
for _, item := range table {
if e, a := item.equal, e.DeepEqual(item.a, item.b); e != a {
t.Errorf("Expected (%+v == %+v) == %v, but got %v", item.a, item.b, e, a)
}
}
}
func TestDerivates(t *testing.T) {
e := Equalities{}
type Bar struct {
X int
}
type Baz struct {
Y Bar
}
err := e.AddFuncs(
func(a, b int) bool {
return a+1 == b
},
func(a, b Bar) bool {
return a.X*10 == b.X
},
)
if err != nil {
t.Fatalf("Unexpected: %v", err)
}
type Foo struct {
X int
}
table := []struct {
a, b interface{}
equal bool
}{
{1, 2, true},
{2, 1, false},
{"foo", "fo", false},
{"foo", "foo", true},
{"foo", "foobar", false},
{Foo{1}, Foo{2}, true},
{Foo{2}, Foo{1}, false},
{Bar{1}, Bar{10}, true},
{&Bar{1}, &Bar{10}, true},
{Baz{Bar{1}}, Baz{Bar{10}}, true},
{[...]string{}, [...]string{"1", "2", "3"}, false},
{[...]string{"1"}, [...]string{"1", "2", "3"}, false},
{[...]string{"1", "2", "3"}, [...]string{}, false},
{[...]string{"1", "2", "3"}, [...]string{"1", "2", "3"}, true},
{map[string]int{"foo": 1}, map[string]int{}, false},
{map[string]int{"foo": 1}, map[string]int{"foo": 2}, true},
{map[string]int{"foo": 2}, map[string]int{"foo": 1}, false},
{map[string]int{"foo": 1}, map[string]int{"foo": 2, "bar": 6}, true},
{map[string]int{"foo": 1, "bar": 6}, map[string]int{"foo": 2}, false},
{map[string]int{}, map[string]int(nil), true},
{[]string(nil), []string(nil), true},
{[]string{}, []string(nil), true},
{[]string(nil), []string{}, true},
{[]string{"1"}, []string(nil), false},
{[]string{}, []string{"1", "2", "3"}, true},
{[]string{"1"}, []string{"1", "2", "3"}, true},
{[]string{"1", "2", "3"}, []string{}, false},
}
for _, item := range table {
if e, a := item.equal, e.DeepDerivative(item.a, item.b); e != a {
t.Errorf("Expected (%+v ~ %+v) == %v, but got %v", item.a, item.b, e, a)
}
}
}

View file

@ -0,0 +1,91 @@
//This package is copied from Go library reflect/type.go.
//The struct tag library provides no way to extract the list of struct tags, only
//a specific tag
package reflect
import (
"fmt"
"strconv"
"strings"
)
type StructTag struct {
Name string
Value string
}
func (t StructTag) String() string {
return fmt.Sprintf("%s:%q", t.Name, t.Value)
}
type StructTags []StructTag
func (tags StructTags) String() string {
s := make([]string, 0, len(tags))
for _, tag := range tags {
s = append(s, tag.String())
}
return "`" + strings.Join(s, " ") + "`"
}
func (tags StructTags) Has(name string) bool {
for i := range tags {
if tags[i].Name == name {
return true
}
}
return false
}
// ParseStructTags returns the full set of fields in a struct tag in the order they appear in
// the struct tag.
func ParseStructTags(tag string) (StructTags, error) {
tags := StructTags{}
for tag != "" {
// Skip leading space.
i := 0
for i < len(tag) && tag[i] == ' ' {
i++
}
tag = tag[i:]
if tag == "" {
break
}
// Scan to colon. A space, a quote or a control character is a syntax error.
// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
// as it is simpler to inspect the tag's bytes than the tag's runes.
i = 0
for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
i++
}
if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
break
}
name := string(tag[:i])
tag = tag[i+1:]
// Scan quoted string to find value.
i = 1
for i < len(tag) && tag[i] != '"' {
if tag[i] == '\\' {
i++
}
i++
}
if i >= len(tag) {
break
}
qvalue := string(tag[:i+1])
tag = tag[i+1:]
value, err := strconv.Unquote(qvalue)
if err != nil {
return nil, err
}
tags = append(tags, StructTag{Name: name, Value: value})
}
return tags, nil
}

View file

@ -0,0 +1,20 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = [
"exec.go",
"funcs.go",
],
tags = ["automanaged"],
)

View file

@ -0,0 +1,94 @@
//This package is copied from Go library text/template.
//The original private functions indirect and printableValue
//are exported as public functions.
package template
import (
"fmt"
"reflect"
)
var Indirect = indirect
var PrintableValue = printableValue
var (
errorType = reflect.TypeOf((*error)(nil)).Elem()
fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
)
// indirect returns the item at the end of indirection, and a bool to indicate if it's nil.
// We indirect through pointers and empty interfaces (only) because
// non-empty interfaces have methods we might need.
func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
if v.IsNil() {
return v, true
}
if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
break
}
}
return v, false
}
// printableValue returns the, possibly indirected, interface value inside v that
// is best for a call to formatted printer.
func printableValue(v reflect.Value) (interface{}, bool) {
if v.Kind() == reflect.Ptr {
v, _ = indirect(v) // fmt.Fprint handles nil.
}
if !v.IsValid() {
return "<no value>", true
}
if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) {
if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) {
v = v.Addr()
} else {
switch v.Kind() {
case reflect.Chan, reflect.Func:
return nil, false
}
}
}
return v.Interface(), true
}
// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
func canBeNil(typ reflect.Type) bool {
switch typ.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
return true
}
return false
}
// isTrue reports whether the value is 'true', in the sense of not the zero of its type,
// and whether the value has a meaningful truth value.
func isTrue(val reflect.Value) (truth, ok bool) {
if !val.IsValid() {
// Something like var x interface{}, never set. It's a form of nil.
return false, true
}
switch val.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
truth = val.Len() > 0
case reflect.Bool:
truth = val.Bool()
case reflect.Complex64, reflect.Complex128:
truth = val.Complex() != 0
case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
truth = !val.IsNil()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
truth = val.Int() != 0
case reflect.Float32, reflect.Float64:
truth = val.Float() != 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
truth = val.Uint() != 0
case reflect.Struct:
truth = true // Struct values are always true.
default:
return
}
return truth, true
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,172 @@
Shell2Junit License Information
Feb, 2010
shell2junit library and sample code is licensed under Apache License, v.2.0.
(c) 2009 Manolo Carrasco (Manuel Carrasco Moñino)
=====
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the
copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other
entities that control, are controlled by, or are under common control with
that entity. For the purposes of this definition, "control" means (i) the
power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty percent
(50%) or more of the outstanding shares, or (iii) beneficial ownership of
such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation source, and
configuration files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled
object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that is
included in or attached to the work (an example is provided in the Appendix
below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial
revisions, annotations, elaborations, or other modifications represent, as a
whole, an original work of authorship. For the purposes of this License,
Derivative Works shall not include works that remain separable from, or
merely link (or bind by name) to the interfaces of, the Work and Derivative
Works thereof.
"Contribution" shall mean any work of authorship, including the original
version of the Work and any modifications or additions to that Work or
Derivative Works thereof, that is intentionally submitted to Licensor for
inclusion in the Work by the copyright owner or by an individual or Legal
Entity authorized to submit on behalf of the copyright owner. For the
purposes of this definition, "submitted" means any form of electronic,
verbal, or written communication sent to the Licensor or its
representatives, including but not limited to communication on electronic
mailing lists, source code control systems, and issue tracking systems that
are managed by, or on behalf of, the Licensor for the purpose of discussing
and improving the Work, but excluding communication that is conspicuously
marked or otherwise designated in writing by the copyright owner as "Not a
Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on
behalf of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
reproduce, prepare Derivative Works of, publicly display, publicly perform,
sublicense, and distribute the Work and such Derivative Works in Source or
Object form.
3. Grant of Patent License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in
this section) patent license to make, have made, use, offer to sell, sell,
import, and otherwise transfer the Work, where such license applies only to
those patent claims licensable by such Contributor that are necessarily
infringed by their Contribution(s) alone or by combination of their
Contribution(s) with the Work to which such Contribution(s) was submitted.
If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this
License for that Work shall terminate as of the date such litigation is
filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
a. You must give any other recipients of the Work or Derivative Works a copy
of this License; and
b. You must cause any modified files to carry prominent notices stating that
You changed the files; and
c. You must retain, in the Source form of any Derivative Works that You
distribute, all copyright, patent, trademark, and attribution notices from
the Source form of the Work, excluding those notices that do not pertain to
any part of the Derivative Works; and
d. If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy
of the attribution notices contained within such NOTICE file, excluding
those notices that do not pertain to any part of the Derivative Works, in at
least one of the following places: within a NOTICE text file distributed as
part of the Derivative Works; within the Source form or documentation, if
provided along with the Derivative Works; or, within a display generated by
the Derivative Works, if and wherever such third-party notices normally
appear. The contents of the NOTICE file are for informational purposes only
and do not modify the License. You may add Your own attribution notices
within Derivative Works that You distribute, alongside or as an addendum to
the NOTICE text from the Work, provided that such additional attribution
notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may
provide additional or different license terms and conditions for use,
reproduction, or distribution of Your modifications, or for any such
Derivative Works as a whole, provided Your use, reproduction, and
distribution of the Work otherwise complies with the conditions stated in
this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to the
Licensor shall be under the terms and conditions of this License, without
any additional terms or conditions. Notwithstanding the above, nothing
herein shall supersede or modify the terms of any separate license agreement
you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor, except
as required for reasonable and customary use in describing the origin of the
Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any
warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or
FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining
the appropriateness of using or redistributing the Work and assume any risks
associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or inability
to use the Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all other
commercial damages or losses), even if such Contributor has been advised of
the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work
or Derivative Works thereof, You may choose to offer, and charge a fee for,
acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such
obligations, You may act only on Your own behalf and on Your sole
responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any
liability incurred by, or claims asserted against, such Contributor by
reason of your accepting any such warranty or additional liability.

View file

@ -0,0 +1,177 @@
#!/bin/bash
### Copyright 2010 Manuel Carrasco Moñino. (manolo at apache.org)
###
### Licensed under the Apache License, Version 2.0.
### You may obtain a copy of it at
### http://www.apache.org/licenses/LICENSE-2.0
###
### A library for shell scripts which creates reports in jUnit format.
### These reports can be used in Jenkins, or any other CI.
###
### Usage:
### - Include this file in your shell script
### - Use juLog to call your command any time you want to produce a new report
### Usage: juLog <options> command arguments
### options:
### -class="MyClass" : a class name which will be shown in the junit report
### -name="TestName" : the test name which will be shown in the junit report
### -error="RegExp" : a regexp which sets the test as failure when the output matches it
### -ierror="RegExp" : same as -error but case insensitive
### -output="Path" : path to output directory, defaults to "./results"
### - Junit reports are left in the folder 'result' under the directory where the script is executed.
### - Configure Jenkins to parse junit files from the generated folder
###
asserts=00; errors=0; total=0; content=""
date=`which gdate 2>/dev/null || which date`
# default output folder
juDIR=`pwd`/results
# The name of the suite is calculated based in your script name
suite=""
# A wrapper for the eval method witch allows catching seg-faults and use tee
errfile=/tmp/evErr.$$.log
function eVal() {
(eval "$1")
# stdout and stderr may currently be inverted (see below) so echo may write to stderr
echo $? 2>&1 | tr -d "\n" > $errfile
}
# Method to clean old tests
function juLogClean() {
echo "+++ Removing old junit reports from: $juDIR "
rm -f "$juDIR"/junit-*
}
# Execute a command and record its results
function juLog() {
suite="";
errfile=/tmp/evErr.$$.log
date=`which gdate || which date`
asserts=00; errors=0; total=0; content=""
# parse arguments
ya=""; icase=""
while [ -z "$ya" ]; do
case "$1" in
-name=*) name=`echo "$1" | sed -e 's/-name=//'`; shift;;
-class=*) class=`echo "$1" | sed -e 's/-class=//'`; shift;;
-ierror=*) ereg=`echo "$1" | sed -e 's/-ierror=//'`; icase="-i"; shift;;
-error=*) ereg=`echo "$1" | sed -e 's/-error=//'`; shift;;
-output=*) juDIR=`echo "$1" | sed -e 's/-output=//'`; shift;;
*) ya=1;;
esac
done
# create output directory
mkdir -p "$juDIR" || exit
# use first arg as name if it was not given
if [ -z "$name" ]; then
name="$asserts-$1"
shift
fi
if [[ "$class" = "" ]]; then
class="default"
fi
suite=$class
# calculate command to eval
[ -z "$1" ] && return
cmd="$1"; shift
while [ -n "$1" ]
do
cmd="$cmd \"$1\""
shift
done
# eval the command sending output to a file
outf=/var/tmp/ju$$.txt
errf=/var/tmp/ju$$-err.txt
>$outf
echo "" | tee -a $outf
echo "+++ Running case: $class.$name " | tee -a $outf
echo "+++ working dir: "`pwd` | tee -a $outf
echo "+++ command: $cmd" | tee -a $outf
ini=`$date +%s.%N`
# execute the command, temporarily swapping stderr and stdout so they can be tee'd to separate files,
# then swapping them back again so that the streams are written correctly for the invoking process
( (eVal "$cmd" | tee -a $outf) 3>&1 1>&2 2>&3 | tee $errf) 3>&1 1>&2 2>&3
evErr=`cat $errfile`
rm -f $errfile
end=`$date +%s.%N`
echo "+++ exit code: $evErr" | tee -a $outf
# set the appropriate error, based in the exit code and the regex
[ $evErr != 0 ] && err=1 || err=0
out=`cat $outf | sed -e 's/^\([^+]\)/| \1/g'`
if [ $err = 0 -a -n "$ereg" ]; then
H=`echo "$out" | egrep $icase "$ereg"`
[ -n "$H" ] && err=1
fi
[ $err != 0 ] && echo "+++ error: $err" | tee -a $outf
rm -f $outf
errMsg=`cat $errf`
rm -f $errf
# calculate vars
asserts=$(($asserts+1))
errors=$(($errors+$err))
time=`echo "$end - $ini" | bc -l`
total=`echo "$total + $time" | bc -l`
# write the junit xml report
## failure tag
[ $err = 0 ] && failure="" || failure="
<failure type=\"ScriptError\" message=\"Script Error\">
<![CDATA[
$errMsg
]]>
</failure>
"
## testcase tag
content="$content
<testcase assertions=\"1\" name=\"$name\" time=\"$time\" classname=\"$class\">
$failure
<system-out>
<![CDATA[
$out
]]>
</system-out>
<system-err>
<![CDATA[
$errMsg
]]>
</system-err>
</testcase>
"
## testsuite block
if [[ -e "$juDIR/junit-$suite.xml" ]]; then
# file exists. first update the failures count
failCount=`sed -n "s/.*testsuite.*failures=\"\([0-9]*\)\".*/\1/p" "$juDIR/junit-$suite.xml"`
errors=$(($failCount+$errors))
sed -i "0,/failures=\"$failCount\"/ s/failures=\"$failCount\"/failures=\"$errors\"/" "$juDIR/junit-$suite.xml"
sed -i "0,/errors=\"$failCount\"/ s/errors=\"$failCount\"/errors=\"$errors\"/" "$juDIR/junit-$suite.xml"
# file exists. Need to append to it. If we remove the testsuite end tag, we can just add it in after.
sed -i "s^</testsuite>^^g" $juDIR/junit-$suite.xml ## remove testSuite so we can add it later
cat <<EOF >> "$juDIR/junit-$suite.xml"
$content
</testsuite>
EOF
else
# no file exists. Adding a new file
cat <<EOF > "$juDIR/junit-$suite.xml"
<testsuite failures="$errors" assertions="$assertions" name="$suite" tests="1" errors="$errors" time="$total">
$content
</testsuite>
EOF
fi
}