<commit_before>// Copyright 2015 Peter Goetz
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pegomock

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/petergtz/pegomock/internal/verify"
)

var GlobalFailHandler FailHandler

func RegisterMockFailHandler(handler FailHandler) {
	GlobalFailHandler = handler
}
func RegisterMockTestingT(t *testing.T) {
	RegisterMockFailHandler(BuildTestingTGomegaFailHandler(t))
}

var lastInvocation *invocation
var globalArgMatchers Matchers

func RegisterMatcher(matcher Matcher) {
	globalArgMatchers.append(matcher)
}

type invocation struct {
	genericMock *GenericMock
	MethodName  string
	Params      []Param
	ReturnTypes []reflect.Type
}

type GenericMock struct {
	mockedMethods map[string]*mockedMethod
}

func (genericMock *GenericMock) Invoke(methodName string, params []Param, returnTypes []reflect.Type) ReturnValues {
	lastInvocation = &invocation{
		genericMock: genericMock,
		MethodName:  methodName,
		Params:      params,
		ReturnTypes: returnTypes,
	}
	return genericMock.getOrCreateMockedMethod(methodName).Invoke(params)
}

func (genericMock *GenericMock) stub(methodName string, paramMatchers []Matcher, returnValues ReturnValues) {
	genericMock.stubWithCallback(methodName, paramMatchers, func([]Param) ReturnValues { return returnValues })
}

func (genericMock *GenericMock) stubWithCallback(methodName string, paramMatchers []Matcher, callback func([]Param) ReturnValues) {
	genericMock.getOrCreateMockedMethod(methodName).stub(paramMatchers, callback)
}

func (genericMock *GenericMock) getOrCreateMockedMethod(methodName string) *mockedMethod {
	if _, ok := genericMock.mockedMethods[methodName]; !ok {
		genericMock.mockedMethods[methodName] = &mockedMethod{name: methodName}
	}
	return genericMock.mockedMethods[methodName]
}

func (genericMock *GenericMock) Reset(methodName string, paramMatchers []Matcher) {
	genericMock.getOrCreateMockedMethod(methodName).reset(paramMatchers)
}

func (genericMock *GenericMock) Verify(
	inOrderContext *InOrderContext,
	invocationCountMatcher Matcher,
	methodName string,
	params []Param) {
	if GlobalFailHandler == nil {
		panic("No GlobalFailHandler set. Please use either RegisterMockFailHandler or RegisterMockTestingT to set a fail handler.")
	}
	defer func() { globalArgMatchers = nil }() // We don't want a panic somewhere during verification screw our global argMatchers

	if len(globalArgMatchers) != 0 {
		verify.Argument(len(globalArgMatchers) == len(params),
			"If you use matchers, you must use matchers for all parameters. Example: TODO")
	}
	matchers := globalArgMatchers
	methodInvocations := genericMock.methodInvocations(methodName, params, matchers)
	if inOrderContext != nil {
		for _, methodInvocation := range methodInvocations {
			if methodInvocation.orderingInvocationNumber <= inOrderContext.invocationCounter {
				GlobalFailHandler("Wrong order. TODO: better message")
			}
			inOrderContext.invocationCounter = methodInvocation.orderingInvocationNumber
		}
	}
	if !invocationCountMatcher.Matches(len(methodInvocations)) {
		if len(matchers) == 0 {
			GlobalFailHandler(fmt.Sprintf(
				"Mock invocation count for method \"%s\" with params %v does not match expectation.\n\n\t%v",
				methodName, params, invocationCountMatcher.FailureMessage()))
		} else {
			GlobalFailHandler(fmt.Sprintf(
				"Mock invocation count for method \"%s\" with params %v does not match expectation.\n\n\t%v",
				methodName, matchers, invocationCountMatcher.FailureMessage()))
		}
	}
}

func (genericMock *GenericMock) GetInvocationParams(methodName string) [][]Param {
	if len(genericMock.mockedMethods[methodName].invocations) == 0 {
		return nil
	}
	result := make([][]Param, len(genericMock.mockedMethods[methodName].invocations[len(genericMock.mockedMethods[methodName].invocations)-1].params))
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		for u, param := range invocation.params {
			result[u] = append(result[u], param)
		}
	}
	return result
}

func (genericMock *GenericMock) methodInvocations(methodName string, params []Param, matchers []Matcher) []methodInvocation {
	if len(matchers) != 0 {
		return genericMock.methodInvocationsUsingMatchers(methodName, matchers)
	}

	invocations := make([]methodInvocation, 0)
	if _, exists := genericMock.mockedMethods[methodName]; exists {
		for _, invocation := range genericMock.mockedMethods[methodName].invocations {
			if reflect.DeepEqual(params, invocation.params) {
				invocations = append(invocations, invocation)
			}
		}
	}
	return invocations
}

func (genericMock *GenericMock) methodInvocationsUsingMatchers(methodName string, paramMatchers Matchers) []methodInvocation {
	invocations := make([]methodInvocation, 0)
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		if paramMatchers.Matches(invocation.params) {
			invocations = append(invocations, invocation)
		}
	}
	return invocations
}

type mockedMethod struct {
	name        string
	invocations []methodInvocation
	stubbings   Stubbings
}

func (method *mockedMethod) Invoke(params []Param) ReturnValues {
	method.invocations = append(method.invocations, methodInvocation{params, globalInvocationCounter.nextNumber()})
	stubbing := method.stubbings.find(params)
	if stubbing == nil {
		return ReturnValues{}
	}
	return stubbing.Invoke(params)
}

func (method *mockedMethod) stub(paramMatchers Matchers, callback func([]Param) ReturnValues) {
	stubbing := method.stubbings.findByMatchers(paramMatchers)
	if stubbing == nil {
		stubbing = &Stubbing{paramMatchers: paramMatchers}
		method.stubbings = append(method.stubbings, stubbing)
	}
	stubbing.callbackSequence = append(stubbing.callbackSequence, callback)
}

func (method *mockedMethod) removeLastInvocation() {
	method.invocations = method.invocations[:len(method.invocations)-1]
}

func (method *mockedMethod) reset(paramMatchers Matchers) {
	method.stubbings.removeByMatchers(paramMatchers)
}

type Counter struct {
	count int
}

func (counter *Counter) nextNumber() (nextNumber int) {
	nextNumber = counter.count
	counter.count++
	return
}

var globalInvocationCounter Counter

type methodInvocation struct {
	params                   []Param
	orderingInvocationNumber int
}

type Stubbings []*Stubbing

func (stubbings Stubbings) find(params []Param) *Stubbing {
	for i := len(stubbings) - 1; i >= 0; i-- {
		if stubbings[i].paramMatchers.Matches(params) {
			return stubbings[i]
		}
	}
	return nil
}

func (stubbings Stubbings) findByMatchers(paramMatchers Matchers) *Stubbing {
	for _, stubbing := range stubbings {
		if matchersEqual(stubbing.paramMatchers, paramMatchers) {
			return stubbing
		}
	}
	return nil
}

func (stubbings *Stubbings) removeByMatchers(paramMatchers Matchers) {
	for i, stubbing := range *stubbings {
		if matchersEqual(stubbing.paramMatchers, paramMatchers) {
			*stubbings = append((*stubbings)[:i], (*stubbings)[i+1:]...)
		}
	}
}

func matchersEqual(a, b Matchers) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if !a[i].Equals(b[i]) {
			return false
		}
	}
	return true
}

type Stubbing struct {
	paramMatchers    Matchers
	callbackSequence []func([]Param) ReturnValues
	sequencePointer  int
}

func (stubbing *Stubbing) Invoke(params []Param) ReturnValues {
	defer func() {
		if stubbing.sequencePointer < len(stubbing.callbackSequence)-1 {
			stubbing.sequencePointer++
		}
	}()
	return stubbing.callbackSequence[stubbing.sequencePointer](params)
}

type Matchers []Matcher

func (matchers Matchers) Matches(params []Param) bool {
	verify.Argument(len(matchers) == len(params),
		"Number of params and matchers different: params: %v, matchers: %v",
		params, matchers)
	for i := range params {
		if !matchers[i].Matches(params[i]) {
			return false
		}
	}
	return true
}

func (matchers *Matchers) append(matcher Matcher) {
	*matchers = append(*matchers, matcher)
}

type ongoingStubbing struct {
	genericMock   *GenericMock
	MethodName    string
	ParamMatchers []Matcher
	returnTypes   []reflect.Type
}

func When(invocation ...interface{}) *ongoingStubbing {
	verify.NotNil(lastInvocation,
		"when() requires an argument which has to be 'a method call on a mock'.")
	defer func() {
		lastInvocation = nil
		globalArgMatchers = nil
	}()
	lastInvocation.genericMock.mockedMethods[lastInvocation.MethodName].removeLastInvocation()

	paramMatchers := paramMatchersFromArgMatchersOrParams(globalArgMatchers, lastInvocation.Params)
	lastInvocation.genericMock.Reset(lastInvocation.MethodName, paramMatchers)
	return &ongoingStubbing{
		genericMock:   lastInvocation.genericMock,
		MethodName:    lastInvocation.MethodName,
		ParamMatchers: paramMatchers,
		returnTypes:   lastInvocation.ReturnTypes,
	}
}

func paramMatchersFromArgMatchersOrParams(argMatchers []Matcher, params []Param) []Matcher {
	if len(argMatchers) == 0 {
		return transformParamsIntoEqMatchers(params)
	} else {
		verify.Argument(len(argMatchers) == len(lastInvocation.Params),
			"Invalid use of matchers!\n\n %v matchers expected, %v recorded.\n\n"+
				"This error may occur if matchers are combined with raw values:\n"+
				"    //incorrect:\n"+
				"    someFunc(AnyInt(), \"raw String\")\n"+
				"When using matchers, all arguments have to be provided by matchers.\n"+
				"For example:\n"+
				"    //correct:\n"+
				"    someFunc(AnyInt(), EqString(\"String by matcher\"))",
			len(lastInvocation.Params), len(argMatchers),
		)
		return argMatchers
	}
}

func transformParamsIntoEqMatchers(params []Param) []Matcher {
	paramMatchers := make([]Matcher, len(params))
	for i, param := range params {
		paramMatchers[i] = &EqMatcher{Value: param}
	}
	return paramMatchers
}

var genericMocks = make(map[Mock]*GenericMock)

func GetGenericMockFrom(mock Mock) *GenericMock {
	if genericMocks[mock] == nil {
		genericMocks[mock] = &GenericMock{mockedMethods: make(map[string]*mockedMethod)}
	}
	return genericMocks[mock]
}

func (stubbing *ongoingStubbing) ThenReturn(values ...ReturnValue) *ongoingStubbing {
	checkAssignabilityOf(values, stubbing.returnTypes)
	stubbing.genericMock.stub(stubbing.MethodName, stubbing.ParamMatchers, values)
	return stubbing
}

func checkAssignabilityOf(stubbedReturnValues []ReturnValue, expectedReturnTypes []reflect.Type) {
	verify.Argument(len(stubbedReturnValues) == len(expectedReturnTypes),
		"Different number of return values")
	for i := range stubbedReturnValues {
		if stubbedReturnValues[i] == nil {
			switch expectedReturnTypes[i].Kind() {
			case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,
				reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32,
				reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Array, reflect.String,
				reflect.Struct:
				panic("Return value 'nil' not assignable to return type " + expectedReturnTypes[i].Kind().String())
			}
		} else {
			verify.Argument(reflect.TypeOf(stubbedReturnValues[i]).AssignableTo(expectedReturnTypes[i]),
				"Return value of type %T not assignable to return type %v", stubbedReturnValues[i], expectedReturnTypes[i])
		}
	}
}

func (stubbing *ongoingStubbing) ThenPanic(v interface{}) *ongoingStubbing {
	stubbing.genericMock.stubWithCallback(
		stubbing.MethodName,
		stubbing.ParamMatchers,
		func([]Param) ReturnValues { panic(v) })
	return stubbing
}

func (stubbing *ongoingStubbing) Then(callback func([]Param) ReturnValues) *ongoingStubbing {
	stubbing.genericMock.stubWithCallback(
		stubbing.MethodName,
		stubbing.ParamMatchers,
		callback)
	return stubbing
}

type InOrderContext struct {
	invocationCounter int
}

type Stubber struct {
	returnValue interface{}
}

func DoPanic(value interface{}) *Stubber {
	return &Stubber{returnValue: value}
}

func (stubber *Stubber) When(mock interface{}) {

}

// Matcher ... it is guaranteed that FailureMessage will always be called after Matches
// so an implementation can save state
type Matcher interface {
	Matches(param Param) bool
	FailureMessage() string
	Equals(interface{}) bool
	fmt.Stringer
}
<commit_msg>Minor cleanup<commit_after>// Copyright 2015 Peter Goetz
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pegomock

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/petergtz/pegomock/internal/verify"
)

var GlobalFailHandler FailHandler

func RegisterMockFailHandler(handler FailHandler) {
	GlobalFailHandler = handler
}
func RegisterMockTestingT(t *testing.T) {
	RegisterMockFailHandler(BuildTestingTGomegaFailHandler(t))
}

var lastInvocation *invocation
var globalArgMatchers Matchers

func RegisterMatcher(matcher Matcher) {
	globalArgMatchers.append(matcher)
}

type invocation struct {
	genericMock *GenericMock
	MethodName  string
	Params      []Param
	ReturnTypes []reflect.Type
}

type GenericMock struct {
	mockedMethods map[string]*mockedMethod
}

func (genericMock *GenericMock) Invoke(methodName string, params []Param, returnTypes []reflect.Type) ReturnValues {
	lastInvocation = &invocation{
		genericMock: genericMock,
		MethodName:  methodName,
		Params:      params,
		ReturnTypes: returnTypes,
	}
	return genericMock.getOrCreateMockedMethod(methodName).Invoke(params)
}

func (genericMock *GenericMock) stub(methodName string, paramMatchers []Matcher, returnValues ReturnValues) {
	genericMock.stubWithCallback(methodName, paramMatchers, func([]Param) ReturnValues { return returnValues })
}

func (genericMock *GenericMock) stubWithCallback(methodName string, paramMatchers []Matcher, callback func([]Param) ReturnValues) {
	genericMock.getOrCreateMockedMethod(methodName).stub(paramMatchers, callback)
}

func (genericMock *GenericMock) getOrCreateMockedMethod(methodName string) *mockedMethod {
	if _, ok := genericMock.mockedMethods[methodName]; !ok {
		genericMock.mockedMethods[methodName] = &mockedMethod{name: methodName}
	}
	return genericMock.mockedMethods[methodName]
}

func (genericMock *GenericMock) Reset(methodName string, paramMatchers []Matcher) {
	genericMock.getOrCreateMockedMethod(methodName).reset(paramMatchers)
}

func (genericMock *GenericMock) Verify(
	inOrderContext *InOrderContext,
	invocationCountMatcher Matcher,
	methodName string,
	params []Param) {
	if GlobalFailHandler == nil {
		panic("No GlobalFailHandler set. Please use either RegisterMockFailHandler or RegisterMockTestingT to set a fail handler.")
	}
	defer func() { globalArgMatchers = nil }() // We don't want a panic somewhere during verification screw our global argMatchers

	if len(globalArgMatchers) != 0 {
		verify.Argument(len(globalArgMatchers) == len(params),
			"If you use matchers, you must use matchers for all parameters. Example: TODO")
	}

	methodInvocations := genericMock.methodInvocations(methodName, params, globalArgMatchers)
	if inOrderContext != nil {
		for _, methodInvocation := range methodInvocations {
			if methodInvocation.orderingInvocationNumber <= inOrderContext.invocationCounter {
				GlobalFailHandler("Wrong order. TODO: better message")
			}
			inOrderContext.invocationCounter = methodInvocation.orderingInvocationNumber
		}
	}
	if !invocationCountMatcher.Matches(len(methodInvocations)) {
		if len(globalArgMatchers) == 0 {
			GlobalFailHandler(fmt.Sprintf(
				"Mock invocation count for method \"%s\" with params %v does not match expectation.\n\n\t%v",
				methodName, params, invocationCountMatcher.FailureMessage()))
		} else {
			GlobalFailHandler(fmt.Sprintf(
				"Mock invocation count for method \"%s\" with params %v does not match expectation.\n\n\t%v",
				methodName, globalArgMatchers, invocationCountMatcher.FailureMessage()))
		}
	}
}

func (genericMock *GenericMock) GetInvocationParams(methodName string) [][]Param {
	if len(genericMock.mockedMethods[methodName].invocations) == 0 {
		return nil
	}
	result := make([][]Param, len(genericMock.mockedMethods[methodName].invocations[len(genericMock.mockedMethods[methodName].invocations)-1].params))
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		for u, param := range invocation.params {
			result[u] = append(result[u], param)
		}
	}
	return result
}

func (genericMock *GenericMock) methodInvocations(methodName string, params []Param, matchers []Matcher) []methodInvocation {
	if len(matchers) != 0 {
		return genericMock.methodInvocationsUsingMatchers(methodName, matchers)
	}

	invocations := make([]methodInvocation, 0)
	if _, exists := genericMock.mockedMethods[methodName]; exists {
		for _, invocation := range genericMock.mockedMethods[methodName].invocations {
			if reflect.DeepEqual(params, invocation.params) {
				invocations = append(invocations, invocation)
			}
		}
	}
	return invocations
}

func (genericMock *GenericMock) methodInvocationsUsingMatchers(methodName string, paramMatchers Matchers) []methodInvocation {
	invocations := make([]methodInvocation, 0)
	for _, invocation := range genericMock.mockedMethods[methodName].invocations {
		if paramMatchers.Matches(invocation.params) {
			invocations = append(invocations, invocation)
		}
	}
	return invocations
}

type mockedMethod struct {
	name        string
	invocations []methodInvocation
	stubbings   Stubbings
}

func (method *mockedMethod) Invoke(params []Param) ReturnValues {
	method.invocations = append(method.invocations, methodInvocation{params, globalInvocationCounter.nextNumber()})
	stubbing := method.stubbings.find(params)
	if stubbing == nil {
		return ReturnValues{}
	}
	return stubbing.Invoke(params)
}

func (method *mockedMethod) stub(paramMatchers Matchers, callback func([]Param) ReturnValues) {
	stubbing := method.stubbings.findByMatchers(paramMatchers)
	if stubbing == nil {
		stubbing = &Stubbing{paramMatchers: paramMatchers}
		method.stubbings = append(method.stubbings, stubbing)
	}
	stubbing.callbackSequence = append(stubbing.callbackSequence, callback)
}

func (method *mockedMethod) removeLastInvocation() {
	method.invocations = method.invocations[:len(method.invocations)-1]
}

func (method *mockedMethod) reset(paramMatchers Matchers) {
	method.stubbings.removeByMatchers(paramMatchers)
}

type Counter struct {
	count int
}

func (counter *Counter) nextNumber() (nextNumber int) {
	nextNumber = counter.count
	counter.count++
	return
}

var globalInvocationCounter Counter

type methodInvocation struct {
	params                   []Param
	orderingInvocationNumber int
}

type Stubbings []*Stubbing

func (stubbings Stubbings) find(params []Param) *Stubbing {
	for i := len(stubbings) - 1; i >= 0; i-- {
		if stubbings[i].paramMatchers.Matches(params) {
			return stubbings[i]
		}
	}
	return nil
}

func (stubbings Stubbings) findByMatchers(paramMatchers Matchers) *Stubbing {
	for _, stubbing := range stubbings {
		if matchersEqual(stubbing.paramMatchers, paramMatchers) {
			return stubbing
		}
	}
	return nil
}

func (stubbings *Stubbings) removeByMatchers(paramMatchers Matchers) {
	for i, stubbing := range *stubbings {
		if matchersEqual(stubbing.paramMatchers, paramMatchers) {
			*stubbings = append((*stubbings)[:i], (*stubbings)[i+1:]...)
		}
	}
}

func matchersEqual(a, b Matchers) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if !a[i].Equals(b[i]) {
			return false
		}
	}
	return true
}

type Stubbing struct {
	paramMatchers    Matchers
	callbackSequence []func([]Param) ReturnValues
	sequencePointer  int
}

func (stubbing *Stubbing) Invoke(params []Param) ReturnValues {
	defer func() {
		if stubbing.sequencePointer < len(stubbing.callbackSequence)-1 {
			stubbing.sequencePointer++
		}
	}()
	return stubbing.callbackSequence[stubbing.sequencePointer](params)
}

type Matchers []Matcher

func (matchers Matchers) Matches(params []Param) bool {
	verify.Argument(len(matchers) == len(params),
		"Number of params and matchers different: params: %v, matchers: %v",
		params, matchers)
	for i := range params {
		if !matchers[i].Matches(params[i]) {
			return false
		}
	}
	return true
}

func (matchers *Matchers) append(matcher Matcher) {
	*matchers = append(*matchers, matcher)
}

type ongoingStubbing struct {
	genericMock   *GenericMock
	MethodName    string
	ParamMatchers []Matcher
	returnTypes   []reflect.Type
}

func When(invocation ...interface{}) *ongoingStubbing {
	verify.NotNil(lastInvocation,
		"when() requires an argument which has to be 'a method call on a mock'.")
	defer func() {
		lastInvocation = nil
		globalArgMatchers = nil
	}()
	lastInvocation.genericMock.mockedMethods[lastInvocation.MethodName].removeLastInvocation()

	paramMatchers := paramMatchersFromArgMatchersOrParams(globalArgMatchers, lastInvocation.Params)
	lastInvocation.genericMock.Reset(lastInvocation.MethodName, paramMatchers)
	return &ongoingStubbing{
		genericMock:   lastInvocation.genericMock,
		MethodName:    lastInvocation.MethodName,
		ParamMatchers: paramMatchers,
		returnTypes:   lastInvocation.ReturnTypes,
	}
}

func paramMatchersFromArgMatchersOrParams(argMatchers []Matcher, params []Param) []Matcher {
	if len(argMatchers) == 0 {
		return transformParamsIntoEqMatchers(params)
	} else {
		verify.Argument(len(argMatchers) == len(lastInvocation.Params),
			"Invalid use of matchers!\n\n %v matchers expected, %v recorded.\n\n"+
				"This error may occur if matchers are combined with raw values:\n"+
				"    //incorrect:\n"+
				"    someFunc(AnyInt(), \"raw String\")\n"+
				"When using matchers, all arguments have to be provided by matchers.\n"+
				"For example:\n"+
				"    //correct:\n"+
				"    someFunc(AnyInt(), EqString(\"String by matcher\"))",
			len(lastInvocation.Params), len(argMatchers),
		)
		return argMatchers
	}
}

func transformParamsIntoEqMatchers(params []Param) []Matcher {
	paramMatchers := make([]Matcher, len(params))
	for i, param := range params {
		paramMatchers[i] = &EqMatcher{Value: param}
	}
	return paramMatchers
}

var genericMocks = make(map[Mock]*GenericMock)

func GetGenericMockFrom(mock Mock) *GenericMock {
	if genericMocks[mock] == nil {
		genericMocks[mock] = &GenericMock{mockedMethods: make(map[string]*mockedMethod)}
	}
	return genericMocks[mock]
}

func (stubbing *ongoingStubbing) ThenReturn(values ...ReturnValue) *ongoingStubbing {
	checkAssignabilityOf(values, stubbing.returnTypes)
	stubbing.genericMock.stub(stubbing.MethodName, stubbing.ParamMatchers, values)
	return stubbing
}

func checkAssignabilityOf(stubbedReturnValues []ReturnValue, expectedReturnTypes []reflect.Type) {
	verify.Argument(len(stubbedReturnValues) == len(expectedReturnTypes),
		"Different number of return values")
	for i := range stubbedReturnValues {
		if stubbedReturnValues[i] == nil {
			switch expectedReturnTypes[i].Kind() {
			case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,
				reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32,
				reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Array, reflect.String,
				reflect.Struct:
				panic("Return value 'nil' not assignable to return type " + expectedReturnTypes[i].Kind().String())
			}
		} else {
			verify.Argument(reflect.TypeOf(stubbedReturnValues[i]).AssignableTo(expectedReturnTypes[i]),
				"Return value of type %T not assignable to return type %v", stubbedReturnValues[i], expectedReturnTypes[i])
		}
	}
}

func (stubbing *ongoingStubbing) ThenPanic(v interface{}) *ongoingStubbing {
	stubbing.genericMock.stubWithCallback(
		stubbing.MethodName,
		stubbing.ParamMatchers,
		func([]Param) ReturnValues { panic(v) })
	return stubbing
}

func (stubbing *ongoingStubbing) Then(callback func([]Param) ReturnValues) *ongoingStubbing {
	stubbing.genericMock.stubWithCallback(
		stubbing.MethodName,
		stubbing.ParamMatchers,
		callback)
	return stubbing
}

type InOrderContext struct {
	invocationCounter int
}

type Stubber struct {
	returnValue interface{}
}

func DoPanic(value interface{}) *Stubber {
	return &Stubber{returnValue: value}
}

func (stubber *Stubber) When(mock interface{}) {

}

// Matcher ... it is guaranteed that FailureMessage will always be called after Matches
// so an implementation can save state
type Matcher interface {
	Matches(param Param) bool
	FailureMessage() string
	Equals(interface{}) bool
	fmt.Stringer
}
<|endoftext|>


<commit_before>package venom

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

func parseEnvLine(line string) (string, string, error) {
	pair := strings.SplitN(line, "=", 2)
	if len(pair) != 2 {
		return "", "", fmt.Errorf("Invalid format, must be kv-pair separated with '=': %s", line)
	}
	return pair[0], pair[1], nil
}

func readEnvFile(p string) (map[string]string, error) {
	f, err := os.Open(p)
	if err != nil {
		return nil, err
	}

	s := bufio.NewScanner(f)
	envMap := make(map[string]string)
	for s.Scan() {
		line := s.Text()
		line = strings.TrimSpace(line)
		if len(line) == 0 {
			continue // skip empty lines
		}

		k, v, err := parseEnvLine(line)
		if err != nil {
			return nil, err
		}
		envMap[k] = v
	}
	return envMap, nil
}

type envConfig struct {
	Envs      []string `mapstructure:"env"`
	EnvFiles  []string `mapstructure:"env-file"`
	EnvPrefix string   `mapstructure:"env-prefix"`
}

func initEnvFlags(flags *pflag.FlagSet, envprefix string) error {
	flags.String("env-prefix", envprefix, "Set environment variables prefix")
	flags.StringSliceP("env", "e", nil, "Set environment variables")
	flags.StringSlice("env-file", nil, "Read in a file of environment variables")
	return nil
}

func readEnv(v *viper.Viper) error {
	var cfg envConfig
	err := Unmarshal(&cfg, v)
	if err != nil {
		return err
	}

	envMap := make(map[string]string)

	// read --env-prefix
	if cfg.EnvPrefix != "" {
		v.SetEnvPrefix(cfg.EnvPrefix)
	}

	// read --env-file
	for _, f := range cfg.EnvFiles {
		env, err := readEnvFile(f)
		if err != nil {
			return err
		}
		for k, v := range env {
			envMap[k] = v
		}
	}

	// read --env
	for _, kv := range cfg.Envs {
		k, v, err := parseEnvLine(kv)
		if err != nil {
			return err
		}
		envMap[k] = v
	}

	// apply env
	for k, v := range envMap {
		err = os.Setenv(k, v)
		if err != nil {
			return err
		}
	}
	return nil
}

func lookupEnvPrefix(flags *pflag.FlagSet) (string, bool) {
	envprefix := ""
	flags.VisitAll(func(f *pflag.Flag) {
		if f.Name == "env-prefix" {
			envprefix = f.Value.String()
		}
	})
	return envprefix, envprefix != ""
}
<commit_msg>Update help<commit_after>package venom

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

func parseEnvLine(line string) (string, string, error) {
	pair := strings.SplitN(line, "=", 2)
	if len(pair) != 2 {
		return "", "", fmt.Errorf("Invalid format, must be kv-pair separated with '=': %s", line)
	}
	return pair[0], pair[1], nil
}

func readEnvFile(p string) (map[string]string, error) {
	f, err := os.Open(p)
	if err != nil {
		return nil, err
	}

	s := bufio.NewScanner(f)
	envMap := make(map[string]string)
	for s.Scan() {
		line := s.Text()
		line = strings.TrimSpace(line)
		if len(line) == 0 {
			continue // skip empty lines
		}

		k, v, err := parseEnvLine(line)
		if err != nil {
			return nil, err
		}
		envMap[k] = v
	}
	return envMap, nil
}

type envConfig struct {
	Envs      []string `mapstructure:"env"`
	EnvFiles  []string `mapstructure:"env-file"`
	EnvPrefix string   `mapstructure:"env-prefix"`
}

func initEnvFlags(flags *pflag.FlagSet, envprefix string) error {
	flags.String("env-prefix", envprefix, "Set environment variables prefix")
	flags.StringSliceP("env", "e", nil, "Set environment variables")
	flags.StringSlice("env-file", nil, "Read environment variables from a text file")
	return nil
}

func readEnv(v *viper.Viper) error {
	var cfg envConfig
	err := Unmarshal(&cfg, v)
	if err != nil {
		return err
	}

	envMap := make(map[string]string)

	// read --env-prefix
	if cfg.EnvPrefix != "" {
		v.SetEnvPrefix(cfg.EnvPrefix)
	}

	// read --env-file
	for _, f := range cfg.EnvFiles {
		env, err := readEnvFile(f)
		if err != nil {
			return err
		}
		for k, v := range env {
			envMap[k] = v
		}
	}

	// read --env
	for _, kv := range cfg.Envs {
		k, v, err := parseEnvLine(kv)
		if err != nil {
			return err
		}
		envMap[k] = v
	}

	// apply env
	for k, v := range envMap {
		err = os.Setenv(k, v)
		if err != nil {
			return err
		}
	}
	return nil
}

func lookupEnvPrefix(flags *pflag.FlagSet) (string, bool) {
	envprefix := ""
	flags.VisitAll(func(f *pflag.Flag) {
		if f.Name == "env-prefix" {
			envprefix = f.Value.String()
		}
	})
	return envprefix, envprefix != ""
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/flynn/flynn-controller/client"
	ct "github.com/flynn/flynn-controller/types"
)

var cmdEnv = &Command{
	Run:   runEnv,
	Usage: "env [-t <proc>]",
	Short: "list env vars",
	Long:  "Command env shows all env vars.",
}

var envProc string

func init() {
	cmdEnv.Flag.StringVarP(&envProc, "process-type", "t", "", "include env from process type")
}

func runEnv(cmd *Command, args []string, client *controller.Client) error {
	if len(args) != 0 {
		cmd.printUsage(true)
	}

	release, err := client.GetAppRelease(mustApp())
	if err == controller.ErrNotFound {
		return nil
	}
	if err != nil {
		return err
	}

	if envProc != "" {
		if release.Env == nil {
			release.Env = make(map[string]string)
		}
		for k, v := range release.Processes[envProc].Env {
			release.Env[k] = v
		}
	}

	vars := make([]string, 0, len(release.Env))
	for k, v := range release.Env {
		vars = append(vars, k+"="+v)
	}
	sort.Strings(vars)

	for _, v := range vars {
		fmt.Println(v)
	}
	return nil
}

var cmdEnvSet = &Command{
	Run:   runEnvSet,
	Usage: "env-set [-t <proc>] <name>=<value>...",
	Short: "set env vars",
	Long:  "Command set sets the value of one or more env vars.",
}

func init() {
	cmdEnvSet.Flag.StringVarP(&envProc, "process-type", "t", "", "set env for process type")
}

func runEnvSet(cmd *Command, args []string, client *controller.Client) error {
	if len(args) == 0 {
		cmd.printUsage(true)
	}

	env := make(map[string]*string, len(args))
	for _, s := range args {
		v := strings.SplitN(s, "=", 2)
		if len(v) != 2 {
			return fmt.Errorf("invalid var format: %q", s)
		}
		env[v[0]] = &v[1]
	}
	id, err := setEnv(client, envProc, env)
	if err != nil {
		return err
	}
	log.Printf("Created release %s.", id)
	return nil
}

var cmdEnvUnset = &Command{
	Run:   runEnvUnset,
	Usage: "env-unset [-t <proc>] <name>...",
	Short: "unset env vars",
	Long:  "Command unset deletes one or more env vars.",
}

func init() {
	cmdEnvUnset.Flag.StringVarP(&envProc, "process-type", "t", "", "unset env var for process type")
}

func runEnvUnset(cmd *Command, args []string, client *controller.Client) error {
	if len(args) == 0 {
		cmd.printUsage(true)
	}

	env := make(map[string]*string, len(args))
	for _, s := range args {
		env[s] = nil
	}
	id, err := setEnv(client, envProc, env)
	if err != nil {
		return err
	}
	log.Printf("Created release %s.", id)
	return nil
}

var cmdEnvGet = &Command{
	Run:   runEnvGet,
	Usage: "env-get [-t <proc>] <name>",
	Short: "get env var",
	Long:  "Get the value of an env var.",
}

func init() {
	cmdEnvGet.Flag.StringVarP(&envProc, "process-type", "t", "", "unset env var for process type")
}

func runEnvGet(cmd *Command, args []string, client *controller.Client) error {
	if len(args) != 1 {
		cmd.printUsage(true)
	}

	release, err := client.GetAppRelease(mustApp())
	if err == controller.ErrNotFound {
		return errors.New("no app release found")
	}

	if _, ok := release.Processes[envProc]; envProc != "" && !ok {
		return fmt.Errorf("process type %q not found in release %s", envProc, release.ID)
	}

	if v, ok := release.Env[args[0]]; ok {
		fmt.Println(v)
		return nil
	}
	if v, ok := release.Processes[envProc].Env[args[0]]; ok {
		fmt.Println(v)
		return nil
	}

	return fmt.Errorf("var %q not found in release %q", args[0], release.ID)
}

func setEnv(client *controller.Client, proc string, env map[string]*string) (string, error) {
	release, err := client.GetAppRelease(mustApp())
	if err == controller.ErrNotFound {
		artifact := &ct.Artifact{}
		if err := client.CreateArtifact(artifact); err != nil {
			return "", err
		}
		release = &ct.Release{ArtifactID: artifact.ID}
		if proc != "" {
			release.Processes = make(map[string]ct.ProcessType)
			release.Processes[proc] = ct.ProcessType{}
		}
	} else if err != nil {
		return "", err
	}

	var dest map[string]string
	if proc != "" {
		if _, ok := release.Processes[proc]; !ok {
			return "", fmt.Errorf("process %q in release %s not found", proc, release.ID)
		}
		if release.Processes[proc].Env == nil {
			p := release.Processes[proc]
			p.Env = make(map[string]string, len(env))
			release.Processes[proc] = p
		}
		dest = release.Processes[proc].Env
	} else {
		if release.Env == nil {
			release.Env = make(map[string]string, len(env))
		}
		dest = release.Env
	}
	for k, v := range env {
		if v == nil {
			delete(dest, k)
		} else {
			dest[k] = *v
		}
	}

	release.ID = ""
	if err := client.CreateRelease(release); err != nil {
		return "", err
	}
	return release.ID, client.SetAppRelease(mustApp(), release.ID)
}
<commit_msg>Fix typo<commit_after>package main

import (
	"errors"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/flynn/flynn-controller/client"
	ct "github.com/flynn/flynn-controller/types"
)

var cmdEnv = &Command{
	Run:   runEnv,
	Usage: "env [-t <proc>]",
	Short: "list env vars",
	Long:  "Command env shows all env vars.",
}

var envProc string

func init() {
	cmdEnv.Flag.StringVarP(&envProc, "process-type", "t", "", "include env from process type")
}

func runEnv(cmd *Command, args []string, client *controller.Client) error {
	if len(args) != 0 {
		cmd.printUsage(true)
	}

	release, err := client.GetAppRelease(mustApp())
	if err == controller.ErrNotFound {
		return nil
	}
	if err != nil {
		return err
	}

	if envProc != "" {
		if release.Env == nil {
			release.Env = make(map[string]string)
		}
		for k, v := range release.Processes[envProc].Env {
			release.Env[k] = v
		}
	}

	vars := make([]string, 0, len(release.Env))
	for k, v := range release.Env {
		vars = append(vars, k+"="+v)
	}
	sort.Strings(vars)

	for _, v := range vars {
		fmt.Println(v)
	}
	return nil
}

var cmdEnvSet = &Command{
	Run:   runEnvSet,
	Usage: "env-set [-t <proc>] <name>=<value>...",
	Short: "set env vars",
	Long:  "Command set sets the value of one or more env vars.",
}

func init() {
	cmdEnvSet.Flag.StringVarP(&envProc, "process-type", "t", "", "set env for process type")
}

func runEnvSet(cmd *Command, args []string, client *controller.Client) error {
	if len(args) == 0 {
		cmd.printUsage(true)
	}

	env := make(map[string]*string, len(args))
	for _, s := range args {
		v := strings.SplitN(s, "=", 2)
		if len(v) != 2 {
			return fmt.Errorf("invalid var format: %q", s)
		}
		env[v[0]] = &v[1]
	}
	id, err := setEnv(client, envProc, env)
	if err != nil {
		return err
	}
	log.Printf("Created release %s.", id)
	return nil
}

var cmdEnvUnset = &Command{
	Run:   runEnvUnset,
	Usage: "env-unset [-t <proc>] <name>...",
	Short: "unset env vars",
	Long:  "Command unset deletes one or more env vars.",
}

func init() {
	cmdEnvUnset.Flag.StringVarP(&envProc, "process-type", "t", "", "unset env var for process type")
}

func runEnvUnset(cmd *Command, args []string, client *controller.Client) error {
	if len(args) == 0 {
		cmd.printUsage(true)
	}

	env := make(map[string]*string, len(args))
	for _, s := range args {
		env[s] = nil
	}
	id, err := setEnv(client, envProc, env)
	if err != nil {
		return err
	}
	log.Printf("Created release %s.", id)
	return nil
}

var cmdEnvGet = &Command{
	Run:   runEnvGet,
	Usage: "env-get [-t <proc>] <name>",
	Short: "get env var",
	Long:  "Get the value of an env var.",
}

func init() {
	cmdEnvGet.Flag.StringVarP(&envProc, "process-type", "t", "", "get env var for process type")
}

func runEnvGet(cmd *Command, args []string, client *controller.Client) error {
	if len(args) != 1 {
		cmd.printUsage(true)
	}

	release, err := client.GetAppRelease(mustApp())
	if err == controller.ErrNotFound {
		return errors.New("no app release found")
	}

	if _, ok := release.Processes[envProc]; envProc != "" && !ok {
		return fmt.Errorf("process type %q not found in release %s", envProc, release.ID)
	}

	if v, ok := release.Env[args[0]]; ok {
		fmt.Println(v)
		return nil
	}
	if v, ok := release.Processes[envProc].Env[args[0]]; ok {
		fmt.Println(v)
		return nil
	}

	return fmt.Errorf("var %q not found in release %q", args[0], release.ID)
}

func setEnv(client *controller.Client, proc string, env map[string]*string) (string, error) {
	release, err := client.GetAppRelease(mustApp())
	if err == controller.ErrNotFound {
		artifact := &ct.Artifact{}
		if err := client.CreateArtifact(artifact); err != nil {
			return "", err
		}
		release = &ct.Release{ArtifactID: artifact.ID}
		if proc != "" {
			release.Processes = make(map[string]ct.ProcessType)
			release.Processes[proc] = ct.ProcessType{}
		}
	} else if err != nil {
		return "", err
	}

	var dest map[string]string
	if proc != "" {
		if _, ok := release.Processes[proc]; !ok {
			return "", fmt.Errorf("process %q in release %s not found", proc, release.ID)
		}
		if release.Processes[proc].Env == nil {
			p := release.Processes[proc]
			p.Env = make(map[string]string, len(env))
			release.Processes[proc] = p
		}
		dest = release.Processes[proc].Env
	} else {
		if release.Env == nil {
			release.Env = make(map[string]string, len(env))
		}
		dest = release.Env
	}
	for k, v := range env {
		if v == nil {
			delete(dest, k)
		} else {
			dest[k] = *v
		}
	}

	release.ID = ""
	if err := client.CreateRelease(release); err != nil {
		return "", err
	}
	return release.ID, client.SetAppRelease(mustApp(), release.ID)
}
<|endoftext|>


<commit_before>package hut

import (
	"os"
	"strconv"
	"strings"
)

type Env interface {
	Get(string) (interface{}, error)
	GetString(string) (string, error)
	GetUint(string) (uint64, error)
	GetInt(string) (int64, error)
	InProd() bool
}

// Reads the environment from the OS environment
type OsEnv struct{}

func (e *OsEnv) Get(key string) (interface{}, error) {
	return e.GetString(key)
}

func (*OsEnv) GetString(key string) (string, error) {
	return os.Getenv(key), nil
}

func (*OsEnv) GetUint(key string) (uint64, error) {
	return strconv.ParseUint(os.Getenv(key), 10, 64)
}

func (*OsEnv) GetInt(key string) (int64, error) {
	return strconv.ParseInt(os.Getenv(key), 10, 64)
}

func (e *OsEnv) InProd() bool {
	return strings.ToLower(os.Getenv("ENV")) != "prod"
}

func NewOsEnv() *OsEnv {
	return &OsEnv{}
}
<commit_msg>Env fixes<commit_after>package hut

import (
	"os"
	"strconv"
	"strings"
)

type Env interface {
	Get(string) (interface{}, error)
	GetString(string) (string, error)
	GetUint(string) (uint64, error)
	GetInt(string) (int64, error)
	InProd() bool
}

// Reads the environment from the OS environment
type OsEnv struct{}

func getenv(key string) string {
	return os.Getenv(strings.ToUpper(key))
}

func (e *OsEnv) Get(key string) (interface{}, error) {
	return e.GetString(key)
}

func (*OsEnv) GetString(key string) (string, error) {
	return getenv(key), nil
}

func (*OsEnv) GetUint(key string) (uint64, error) {
	return strconv.ParseUint(getenv(key), 10, 64)
}

func (*OsEnv) GetInt(key string) (int64, error) {
	return strconv.ParseInt(getenv(key), 10, 64)
}

func (e *OsEnv) InProd() bool {
	return strings.ToLower(os.Getenv("ENV")) == "prod"
}

func NewOsEnv() *OsEnv {
	return &OsEnv{}
}
<|endoftext|>


<commit_before>// Package envexpvar exposes process environmental variables
// via expvar
package envexpvar

import (
	"expvar"
	"strings"
	"syscall"
)

func Env() map[string]string {
	vals := syscall.Environ()
	e := make(map[string]string, len(vals))
	for _, i := range vals {
		// this is not particularly speedy. Good enough for a first try
		parts := strings.SplitN(i, "=", 2)
		k := parts[0]
		// There can be multiple values for an environment variable (see stdlib syscall source)
		// so just call Getenv on each.  We could optimize and do the "magic" here, but
		// there is little performance gane to be had for potentially buggy code.
		if v, ok := syscall.Getenv(k); ok {
			e[k] = v
		}
	}
	return e
}

// helper to "cast" for expvar
func env() interface{} {
	return interface{}(Env())
}

func init() {
	expvar.Publish("environment", expvar.Func(env))
}
<commit_msg>Add doc<commit_after>// Package envexpvar exposes process environmental variables
// via expvar
package envexpvar

import (
	"expvar"
	"strings"
	"syscall"
)

// Env returns the current OS environment for this running process.
func Env() map[string]string {
	vals := syscall.Environ()
	e := make(map[string]string, len(vals))
	for _, i := range vals {
		// this is not particularly speedy. Good enough for a first try
		parts := strings.SplitN(i, "=", 2)
		k := parts[0]
		// There can be multiple values for an environment variable (see stdlib syscall source)
		// so just call Getenv on each.  We could optimize and do the "magic" here, but
		// there is little performance gane to be had for potentially buggy code.
		if v, ok := syscall.Getenv(k); ok {
			e[k] = v
		}
	}
	return e
}

// helper to "cast" for expvar
func env() interface{} {
	return interface{}(Env())
}

func init() {
	expvar.Publish("environment", expvar.Func(env))
}
<|endoftext|>


<commit_before>/*
	Copyright 2017, Google, Inc.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

// Command logpipe is a service that will let you pipe logs directly to Stackdriver Logging.
package main

import (
	"bufio"
	"fmt"
	"log"
	"os"

	flags "github.com/jessevdk/go-flags"

	"cloud.google.com/go/logging"
	"golang.org/x/net/context"
)

func main() {
	ctx := context.Background()

	var opts struct {
		ProjectID string `short:"p" long:"project" description:"Google Cloud Platform Project ID" required:"true"`
		LogName   string `short:"l" long:"logname" description:"The name of the log to write to" default:"default"`
	}

	flags.Parse(&opts)

	projectID := &opts.ProjectID
	logName := &opts.LogName

	if *projectID == "" {
		fmt.Printf("Please specify a project ID\n")
		return
	}

	// Check if Standard In is coming from a pipe
	fi, err := os.Stdin.Stat()
	if err != nil {
		panic(err)
	}
	if fi.Mode()&os.ModeNamedPipe == 0 {
		fmt.Printf("Nothing is piped in so there is nothing to log!\n")
		return
	}

	// Creates a client.
	client, err := logging.NewClient(ctx, *projectID)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	// Selects the log to write to.
	logger := client.Logger(*logName)

	// Read from Stdin and log it to Stdout and Stackdriver
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		text := scanner.Text()
		fmt.Println(text)
		logger.Log(logging.Entry{Payload: text})
	}
	if err := scanner.Err(); err != nil {
		log.Fatalf("Failed to scan input: %v", err)
	}

	// Closes the client and flushes the buffer to the Stackdriver Logging
	// service.
	if err := client.Close(); err != nil {
		log.Fatalf("Failed to close client: %v", err)
	}

	fmt.Printf("Finished logging\n")
}
<commit_msg>handle all errors the same way<commit_after>/*
	Copyright 2017, Google, Inc.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

// Command logpipe is a service that will let you pipe logs directly to Stackdriver Logging.
package main

import (
	"bufio"
	"fmt"
	"os"

	flags "github.com/jessevdk/go-flags"

	"cloud.google.com/go/logging"
	"golang.org/x/net/context"
)

func main() {
	ctx := context.Background()

	var opts struct {
		ProjectID string `short:"p" long:"project" description:"Google Cloud Platform Project ID" required:"true"`
		LogName   string `short:"l" long:"logname" description:"The name of the log to write to" default:"default"`
	}

	flags.Parse(&opts)

	projectID := &opts.ProjectID
	logName := &opts.LogName

	if *projectID == "" {
		errorf("Please specify a project ID\n")
	}

	// Check if Standard In is coming from a pipe
	fi, err := os.Stdin.Stat()
	if err != nil {
		errorf("Could not stat standard input: %v\n", err)
	}
	if fi.Mode()&os.ModeNamedPipe == 0 {
		errorf("Nothing is piped in so there is nothing to log!\n")
	}

	// Creates a client.
	client, err := logging.NewClient(ctx, *projectID)
	if err != nil {
		errorf("Failed to create client: %v", err)
	}

	// Selects the log to write to.
	logger := client.Logger(*logName)

	// Read from Stdin and log it to Stdout and Stackdriver
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		text := scanner.Text()
		fmt.Println(text)
		logger.Log(logging.Entry{Payload: text})
	}
	if err := scanner.Err(); err != nil {
		errorf("Failed to scan input: %v", err)
	}

	// Closes the client and flushes the buffer to the Stackdriver Logging
	// service.
	if err := client.Close(); err != nil {
		errorf("Failed to close client: %v", err)
	}
}

func errorf(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	os.Exit(2)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"syscall"
	"unsafe"
)

const (
	ansiEraseDisplay = "\033[2J"
	ansiResetCursor  = "\033[H"
	carriageReturn   = "\015"
)

var originalSttyState bytes.Buffer
var winRows uint16
var winCols uint16

type winsize struct {
	rows, cols, xpixel, ypixel uint16
}

func getWinsize() winsize {
	ws := winsize{}
	syscall.Syscall(syscall.SYS_IOCTL,
		uintptr(0), uintptr(syscall.TIOCGWINSZ),
		uintptr(unsafe.Pointer(&ws)))
	return ws
}

func getSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", "-g")
	cmd.Stdin = os.Stdin
	cmd.Stdout = state
	return cmd.Run()
}

func setSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", state.String())
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func NewTTY() (t *TTY, err error) {
	fh, err := os.OpenFile("/dev/tty", os.O_RDWR, 0666)
	if err != nil {
		return
	}
	t = &TTY{fh, ">> "}
	return
}

type TTY struct {
	*os.File
	prompt string
}

// Clears the screen and sets the cursor to first row, first column
func (t *TTY) resetScreen() {
	fmt.Fprint(t.File, ansiEraseDisplay+ansiResetCursor)
}

// Print prompt with `in`
func (t *TTY) printPrompt(in []byte) {
	fmt.Fprintf(t.File, t.prompt+"%s", in)
}

// Positions the cursor after the prompt and `inlen` colums to the right
func (t *TTY) cursorAfterPrompt(inlen int) {
	t.setCursorPos(0, len(t.prompt)+inlen)
}

// Sets the cursor to `line` and `col`
func (t *TTY) setCursorPos(line int, col int) {
	fmt.Fprintf(t.File, "\033[%d;%dH", line+1, col+1)
}

func init() {
	ws := getWinsize()
	winRows = ws.rows
	winCols = ws.cols
}

func main() {
	err := getSttyState(&originalSttyState)
	if err != nil {
		log.Fatal(err)
	}
	// TODO: this needs to be run when the process is interrupted
	defer setSttyState(&originalSttyState)

	setSttyState(bytes.NewBufferString("cbreak"))
	setSttyState(bytes.NewBufferString("-echo"))

	tty, err := NewTTY()
	if err != nil {
		log.Fatal(err)
	}

	// TODO: Clean this up. This is a mess.
	var input []byte = make([]byte, 0)
	var b []byte = make([]byte, 1)
	var out []byte

	for {
		tty.resetScreen()
		tty.printPrompt(input[:len(input)])

		var quit chan bool = make(chan bool)
		if len(input) > 0 {
			go func() {
				var ch chan string = make(chan string)

				arg := fmt.Sprintf("%s", input[:len(input)])
				cmd := exec.Command("ag", arg)
				cmdstdout, err := cmd.StdoutPipe()
				if err != nil {
					log.Fatal(err)
				}
				cmdreader := bufio.NewReader(cmdstdout)

				err = cmd.Start()
				if err != nil {
					log.Fatal(err)
				}

				go func() {
					for {
						line, err := cmdreader.ReadBytes('\n')
						if err != nil || err == io.EOF {
							break
						}
						ch <- string(line)
					}
					close(ch)
				}()

				fmt.Fprintf(tty, "\n")

				printed := 0
				for {
					select {
					case str, ok := <-ch:
						if !ok {
							tty.cursorAfterPrompt(len(input))
							return
						}

						printed++
						if len(str) > int(winCols) {
							fmt.Fprintf(tty, "%s", str[:int(winCols)])
						} else {
							fmt.Fprintf(tty, "%s", str)
						}

						if printed > int(winRows)-3 {
							tty.cursorAfterPrompt(len(input))
							return
						}
					case <-quit:
						cmd.Process.Kill()
						tty.cursorAfterPrompt(len(input))
						return
					}
				}
			}()
		}

		os.Stdin.Read(b)
		switch b[0] {
		case 127:
			// Backspace
			if len(input) > 0 {
				input = input[:len(input)-1]
			}
		case 4, 10, 13:
			// Ctrl-D, line feed, carriage return
			// TODO: this is probably wrong, since we need to wait for the cmd
			// in the bg to finish
			fmt.Fprint(os.Stdout, string(out))
			return
		default:
			// TODO: Default is wrong here. Only append printable characters to
			// input
			input = append(input, b...)
		}

		// Non-blocking sent to quit channel.
		if len(input) > 0 {
			select {
			case quit <- true:
			default:
			}
		}
	}
}
<commit_msg>Remove unused code<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"syscall"
	"unsafe"
)

const (
	ansiEraseDisplay = "\033[2J"
	ansiResetCursor  = "\033[H"
	carriageReturn   = "\015"
)

var originalSttyState bytes.Buffer
var winRows uint16
var winCols uint16

type winsize struct {
	rows, cols, xpixel, ypixel uint16
}

func getWinsize() winsize {
	ws := winsize{}
	syscall.Syscall(syscall.SYS_IOCTL,
		uintptr(0), uintptr(syscall.TIOCGWINSZ),
		uintptr(unsafe.Pointer(&ws)))
	return ws
}

func getSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", "-g")
	cmd.Stdin = os.Stdin
	cmd.Stdout = state
	return cmd.Run()
}

func setSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", state.String())
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func NewTTY() (t *TTY, err error) {
	fh, err := os.OpenFile("/dev/tty", os.O_RDWR, 0666)
	if err != nil {
		return
	}
	t = &TTY{fh, ">> "}
	return
}

type TTY struct {
	*os.File
	prompt string
}

// Clears the screen and sets the cursor to first row, first column
func (t *TTY) resetScreen() {
	fmt.Fprint(t.File, ansiEraseDisplay+ansiResetCursor)
}

// Print prompt with `in`
func (t *TTY) printPrompt(in []byte) {
	fmt.Fprintf(t.File, t.prompt+"%s", in)
}

// Positions the cursor after the prompt and `inlen` colums to the right
func (t *TTY) cursorAfterPrompt(inlen int) {
	t.setCursorPos(0, len(t.prompt)+inlen)
}

// Sets the cursor to `line` and `col`
func (t *TTY) setCursorPos(line int, col int) {
	fmt.Fprintf(t.File, "\033[%d;%dH", line+1, col+1)
}

func init() {
	ws := getWinsize()
	winRows = ws.rows
	winCols = ws.cols
}

func main() {
	err := getSttyState(&originalSttyState)
	if err != nil {
		log.Fatal(err)
	}
	// TODO: this needs to be run when the process is interrupted
	defer setSttyState(&originalSttyState)

	setSttyState(bytes.NewBufferString("cbreak"))
	setSttyState(bytes.NewBufferString("-echo"))

	tty, err := NewTTY()
	if err != nil {
		log.Fatal(err)
	}

	// TODO: Clean this up. This is a mess.
	var input []byte = make([]byte, 0)
	var b []byte = make([]byte, 1)

	for {
		tty.resetScreen()
		tty.printPrompt(input[:len(input)])

		var quit chan bool = make(chan bool)
		if len(input) > 0 {
			go func() {
				var ch chan string = make(chan string)

				arg := fmt.Sprintf("%s", input[:len(input)])
				cmd := exec.Command("ag", arg)
				cmdstdout, err := cmd.StdoutPipe()
				if err != nil {
					log.Fatal(err)
				}
				cmdreader := bufio.NewReader(cmdstdout)

				err = cmd.Start()
				if err != nil {
					log.Fatal(err)
				}

				go func() {
					for {
						line, err := cmdreader.ReadBytes('\n')
						if err != nil || err == io.EOF {
							break
						}
						ch <- string(line)
					}
					close(ch)
				}()

				fmt.Fprintf(tty, "\n")

				printed := 0
				for {
					select {
					case str, ok := <-ch:
						if !ok {
							tty.cursorAfterPrompt(len(input))
							return
						}

						printed++
						if len(str) > int(winCols) {
							fmt.Fprintf(tty, "%s", str[:int(winCols)])
						} else {
							fmt.Fprintf(tty, "%s", str)
						}

						if printed > int(winRows)-3 {
							tty.cursorAfterPrompt(len(input))
							return
						}
					case <-quit:
						cmd.Process.Kill()
						tty.cursorAfterPrompt(len(input))
						return
					}
				}
			}()
		}

		os.Stdin.Read(b)
		switch b[0] {
		case 127:
			// Backspace
			if len(input) > 0 {
				input = input[:len(input)-1]
			}
		case 4, 10, 13:
			// Ctrl-D, line feed, carriage return
			// TODO: write the last output generated by the cmd to os.Stdout
			return
		default:
			// TODO: Default is wrong here. Only append printable characters to
			// input
			input = append(input, b...)
		}

		// Non-blocking sent to quit channel.
		if len(input) > 0 {
			select {
			case quit <- true:
			default:
			}
		}
	}
}
<|endoftext|>


<commit_before>package gcp

import (
	"errors"

	log "github.com/Sirupsen/logrus"
)

type Gcp struct {
	Receivers map[string]Receiver
	Senders   map[string]Sender
	logEntry  *log.Entry
}

func InitGcp(logger *log.Entry) (*Gcp, error) {
	ret := Gcp{}
	ret.Receivers = map[string]Receiver{}
	ret.Senders = map[string]Sender{}
	ret.logEntry = logger
	return &ret, nil
}

func (gcp *Gcp) Start() {
	gcp.startAllReceiver()
}

func (gcp *Gcp) AddReceiver(receiverName string, receiver Receiver) error {
	if _, ok := gcp.Receivers[receiverName]; ok {
		return errors.New("Receiver Name has already exists.")
	}
	gcp.Receivers[receiverName] = receiver
	return nil
}

func (gcp *Gcp) AddSender(senderName string, sender Sender) error {
	if _, ok := gcp.Senders[senderName]; ok {
		return errors.New("Sender Name has already exists.")
	}
	gcp.Senders[senderName] = sender
	return nil
}

func (gcp *Gcp) startAllReceiver() {
	for key := range gcp.Receivers {
		gcp.logEntry.Info("Start Receiver:" + key)
		err := gcp.Receivers[key].Start()
		if err != nil {
			gcp.logEntry.Errorf("Start Recevier %s %s. %s", key, " Fail", err)
			continue
		}
	}
}
<commit_msg>Fix compile error.<commit_after>package gcp

import (
	"errors"

	log "github.com/Sirupsen/logrus"
)

type Gcp struct {
	Receivers map[string]Receiver
	Senders   map[string]Sender
	Logger    *log.Entry
}

func InitGcp(logger *log.Entry) (*Gcp, error) {
	ret := Gcp{}
	ret.Receivers = map[string]Receiver{}
	ret.Senders = map[string]Sender{}
	ret.Logger = logger
	return &ret, nil
}

func (gcp *Gcp) Start() {
	gcp.startAllReceiver()
}

func (gcp *Gcp) AddReceiver(receiverName string, receiver Receiver) error {
	if _, ok := gcp.Receivers[receiverName]; ok {
		return errors.New("Receiver Name has already exists.")
	}
	gcp.Receivers[receiverName] = receiver
	return nil
}

func (gcp *Gcp) AddSender(senderName string, sender Sender) error {
	if _, ok := gcp.Senders[senderName]; ok {
		return errors.New("Sender Name has already exists.")
	}
	gcp.Senders[senderName] = sender
	return nil
}

func (gcp *Gcp) startAllReceiver() {
	for key := range gcp.Receivers {
		gcp.Logger.Info("Start Receiver:" + key)
		err := gcp.Receivers[key].Start()
		if err != nil {
			gcp.Logger.Errorf("Start Recevier %s %s. %s", key, " Fail", err)
			continue
		}
	}
}
<|endoftext|>


<commit_before>package gopter

import (
	"fmt"
	"reflect"
)

// Gen generator of arbitrary values.
// Usually properties are checked by verifing a condition holds true for
// arbitrary input parameters generated by a Gen.
//
// IMPORTANT: Even though a generator is supposed to generate random values, it
// should do this in a reproducable way. Therefore a generator has to create the
// same result for the same GenParameters, i.e. ensure that you just use the
// RNG provided by GenParameters and no external one.
// If you just plug generators together you do not have to worry about this.
type Gen func(*GenParameters) *GenResult

var (
	// DefaultGenParams can be used as default für *GenParameters
	DefaultGenParams = DefaultGenParameters()
)

// Sample generate a sample value.
// Depending on the state of the RNG the generate might fail to provide a sample
func (g Gen) Sample() (interface{}, bool) {
	return g(DefaultGenParameters()).Retrieve()
}

// WithLabel adds a label to a generated value.
// Labels are usually used for reporting for the arguments of a property check.
func (g Gen) WithLabel(label string) Gen {
	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		result.Labels = append(result.Labels, label)
		return result
	}
}

// SuchThat creates a derived generator by adding a sieve.
// f: has to be a function with one parameter (matching the generated value) returning a bool.
// All generated values are expected to satisfy
//  f(value) == true.
// Use this care, if the sieve to to fine the generator will have many misses which results
// in an undecided property.
func (g Gen) SuchThat(f interface{}) Gen {
	checkVal := reflect.ValueOf(f)
	checkType := checkVal.Type()

	if checkVal.Kind() != reflect.Func {
		panic(fmt.Sprintf("Param of SuchThat has to be a func, but is %v", checkType.Kind()))
	}
	if checkType.NumIn() != 1 {
		panic(fmt.Sprintf("Param of SuchThat has to be a func with one param, but is %v", checkType.NumIn()))
	} else {
		genResultType := g(DefaultGenParams).ResultType
		if !genResultType.AssignableTo(checkType.In(0)) {
			panic(fmt.Sprintf("Param of SuchThat has to be a func with one param assignable to %v, but is %v", genResultType, checkType.In(0)))
		}
	}
	if checkType.NumOut() != 1 {
		panic(fmt.Sprintf("Param of SuchThat has to be a func with one return value, but is %v", checkType.NumOut()))
	} else if checkType.Out(0).Kind() != reflect.Bool {
		panic(fmt.Sprintf("Param of SuchThat has to be a func with one return value of bool, but is %v", checkType.Out(0).Kind()))
	}
	sieve := func(v interface{}) bool {
		return checkVal.Call([]reflect.Value{reflect.ValueOf(v)})[0].Bool()
	}

	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		prevSieve := result.Sieve
		if prevSieve == nil {
			result.Sieve = sieve
		} else {
			result.Sieve = func(value interface{}) bool {
				return prevSieve(value) && sieve(value)
			}
		}
		return result
	}
}

// WithShrinker creates a derived generator with a specific shrinker
func (g Gen) WithShrinker(shrinker Shrinker) Gen {
	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		if shrinker == nil {
			result.Shrinker = NoShrinker
		} else {
			result.Shrinker = shrinker
		}
		return result
	}
}

// Map creates a derived generators by mapping all generatored values with a given function.
// f: has to be a function with one parameter (matching the generated value) and a single return.
// Note: The derived generator will not have a sieve or shrinker.
// Note: The mapping function may have a second parameter "*GenParameters"
// Note: The first parameter of the mapping function and its return may be a *GenResult (this makes MapResult obsolete)
func (g Gen) Map(f interface{}) Gen {
	mapperVal := reflect.ValueOf(f)
	mapperType := mapperVal.Type()
	needsGenParameters := false
	genResultInput := false
	genResultOutput := false

	if mapperVal.Kind() != reflect.Func {
		panic(fmt.Sprintf("Param of Map has to be a func, but is %v", mapperType.Kind()))
	}
	if mapperType.NumIn() != 1 && mapperType.NumIn() != 2 {
		panic(fmt.Sprintf("Param of Map has to be a func with one or two params, but is %v", mapperType.NumIn()))
	} else {
		if mapperType.NumIn() == 2 {
			if !reflect.TypeOf(&GenParameters{}).AssignableTo(mapperType.In(1)) {
				panic("Second parameter of mapper function has to be a *GenParameters")
			}
			needsGenParameters = true
		}
		genResultType := g(DefaultGenParams).ResultType
		if reflect.TypeOf(&GenResult{}).AssignableTo(mapperType.In(0)) {
			genResultInput = true
		} else if !genResultType.AssignableTo(mapperType.In(0)) {
			panic(fmt.Sprintf("Param of Map has to be a func with one param assignable to %v, but is %v", genResultType, mapperType.In(0)))
		}
	}
	if mapperType.NumOut() != 1 {
		panic(fmt.Sprintf("Param of Map has to be a func with one return value, but is %v", mapperType.NumOut()))
	} else if reflect.TypeOf(&GenResult{}).AssignableTo(mapperType.Out(0)) {
		genResultOutput = true
	}

	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		if genResultInput {
			var mapped reflect.Value
			if needsGenParameters {
				mapped = mapperVal.Call([]reflect.Value{reflect.ValueOf(result), reflect.ValueOf(genParams)})[0]
			} else {
				mapped = mapperVal.Call([]reflect.Value{reflect.ValueOf(result)})[0]
			}
			if genResultOutput {
				return mapped.Interface().(*GenResult)
			}
			return &GenResult{
				Shrinker:   NoShrinker,
				Result:     mapped.Interface(),
				Labels:     result.Labels,
				ResultType: mapperType.Out(0),
			}
		}
		value, ok := result.RetrieveAsValue()
		if ok {
			var mapped reflect.Value
			if needsGenParameters {
				mapped = mapperVal.Call([]reflect.Value{value, reflect.ValueOf(genParams)})[0]
			} else {
				mapped = mapperVal.Call([]reflect.Value{value})[0]
			}
			if genResultOutput {
				return mapped.Interface().(*GenResult)
			}
			return &GenResult{
				Shrinker:   NoShrinker,
				Result:     mapped.Interface(),
				Labels:     result.Labels,
				ResultType: mapperType.Out(0),
			}
		}
		return &GenResult{
			Shrinker:   NoShrinker,
			Result:     nil,
			Labels:     result.Labels,
			ResultType: mapperType.Out(0),
		}
	}
}

// FlatMap creates a derived generator by passing a generated value to a function which itself
// creates a generator.
func (g Gen) FlatMap(f func(interface{}) Gen, resultType reflect.Type) Gen {
	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		value, ok := result.Retrieve()
		if ok {
			return f(value)(genParams)
		}
		return &GenResult{
			Shrinker:   NoShrinker,
			Result:     nil,
			Labels:     result.Labels,
			ResultType: resultType,
		}
	}
}

// MapResult creates a derived generator by mapping the GenResult directly.
// Contrary to `Map` and `FlatMap` this also allow the conversion of
// shrinkers and sieves, but implementation is more cumbersome.
// Deprecation note: Map now has the same functionality
func (g Gen) MapResult(f func(*GenResult) *GenResult) Gen {
	return func(genParams *GenParameters) *GenResult {
		return f(g(genParams))
	}
}

// CombineGens creates a generators from a list of generators.
// The result type will be a []interface{} containing the generated values of each generators in
// the list.
// Note: The combined generator will not have a sieve or shrinker.
func CombineGens(gens ...Gen) Gen {
	return func(genParams *GenParameters) *GenResult {
		labels := []string{}
		values := make([]interface{}, len(gens))
		shrinkers := make([]Shrinker, len(gens))
		sieves := make([]func(v interface{}) bool, len(gens))

		var ok bool
		for i, gen := range gens {
			result := gen(genParams)
			labels = append(labels, result.Labels...)
			shrinkers[i] = result.Shrinker
			sieves[i] = result.Sieve
			values[i], ok = result.Retrieve()
			if !ok {
				return &GenResult{
					Shrinker:   NoShrinker,
					Result:     nil,
					Labels:     result.Labels,
					ResultType: reflect.TypeOf(values),
				}
			}
		}
		return &GenResult{
			Shrinker:   CombineShrinker(shrinkers...),
			Result:     values,
			Labels:     labels,
			ResultType: reflect.TypeOf(values),
			Sieve: func(v interface{}) bool {
				values := v.([]interface{})
				for i, value := range values {
					if sieves[i] != nil && !sieves[i](value) {
						return false
					}
				}
				return true
			},
		}
	}
}
<commit_msg>Fix edge case in Sieve()<commit_after>package gopter

import (
	"fmt"
	"reflect"
)

// Gen generator of arbitrary values.
// Usually properties are checked by verifing a condition holds true for
// arbitrary input parameters generated by a Gen.
//
// IMPORTANT: Even though a generator is supposed to generate random values, it
// should do this in a reproducable way. Therefore a generator has to create the
// same result for the same GenParameters, i.e. ensure that you just use the
// RNG provided by GenParameters and no external one.
// If you just plug generators together you do not have to worry about this.
type Gen func(*GenParameters) *GenResult

var (
	// DefaultGenParams can be used as default für *GenParameters
	DefaultGenParams = DefaultGenParameters()
)

// Sample generate a sample value.
// Depending on the state of the RNG the generate might fail to provide a sample
func (g Gen) Sample() (interface{}, bool) {
	return g(DefaultGenParameters()).Retrieve()
}

// WithLabel adds a label to a generated value.
// Labels are usually used for reporting for the arguments of a property check.
func (g Gen) WithLabel(label string) Gen {
	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		result.Labels = append(result.Labels, label)
		return result
	}
}

// SuchThat creates a derived generator by adding a sieve.
// f: has to be a function with one parameter (matching the generated value) returning a bool.
// All generated values are expected to satisfy
//  f(value) == true.
// Use this care, if the sieve to to fine the generator will have many misses which results
// in an undecided property.
func (g Gen) SuchThat(f interface{}) Gen {
	checkVal := reflect.ValueOf(f)
	checkType := checkVal.Type()

	if checkVal.Kind() != reflect.Func {
		panic(fmt.Sprintf("Param of SuchThat has to be a func, but is %v", checkType.Kind()))
	}
	if checkType.NumIn() != 1 {
		panic(fmt.Sprintf("Param of SuchThat has to be a func with one param, but is %v", checkType.NumIn()))
	} else {
		genResultType := g(DefaultGenParams).ResultType
		if !genResultType.AssignableTo(checkType.In(0)) {
			panic(fmt.Sprintf("Param of SuchThat has to be a func with one param assignable to %v, but is %v", genResultType, checkType.In(0)))
		}
	}
	if checkType.NumOut() != 1 {
		panic(fmt.Sprintf("Param of SuchThat has to be a func with one return value, but is %v", checkType.NumOut()))
	} else if checkType.Out(0).Kind() != reflect.Bool {
		panic(fmt.Sprintf("Param of SuchThat has to be a func with one return value of bool, but is %v", checkType.Out(0).Kind()))
	}
	sieve := func(v interface{}) bool {
		valueOf := reflect.ValueOf(v)
		if !valueOf.IsValid() {
			return false
		}
		return checkVal.Call([]reflect.Value{valueOf})[0].Bool()
	}

	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		prevSieve := result.Sieve
		if prevSieve == nil {
			result.Sieve = sieve
		} else {
			result.Sieve = func(value interface{}) bool {
				return prevSieve(value) && sieve(value)
			}
		}
		return result
	}
}

// WithShrinker creates a derived generator with a specific shrinker
func (g Gen) WithShrinker(shrinker Shrinker) Gen {
	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		if shrinker == nil {
			result.Shrinker = NoShrinker
		} else {
			result.Shrinker = shrinker
		}
		return result
	}
}

// Map creates a derived generators by mapping all generatored values with a given function.
// f: has to be a function with one parameter (matching the generated value) and a single return.
// Note: The derived generator will not have a sieve or shrinker.
// Note: The mapping function may have a second parameter "*GenParameters"
// Note: The first parameter of the mapping function and its return may be a *GenResult (this makes MapResult obsolete)
func (g Gen) Map(f interface{}) Gen {
	mapperVal := reflect.ValueOf(f)
	mapperType := mapperVal.Type()
	needsGenParameters := false
	genResultInput := false
	genResultOutput := false

	if mapperVal.Kind() != reflect.Func {
		panic(fmt.Sprintf("Param of Map has to be a func, but is %v", mapperType.Kind()))
	}
	if mapperType.NumIn() != 1 && mapperType.NumIn() != 2 {
		panic(fmt.Sprintf("Param of Map has to be a func with one or two params, but is %v", mapperType.NumIn()))
	} else {
		if mapperType.NumIn() == 2 {
			if !reflect.TypeOf(&GenParameters{}).AssignableTo(mapperType.In(1)) {
				panic("Second parameter of mapper function has to be a *GenParameters")
			}
			needsGenParameters = true
		}
		genResultType := g(DefaultGenParams).ResultType
		if reflect.TypeOf(&GenResult{}).AssignableTo(mapperType.In(0)) {
			genResultInput = true
		} else if !genResultType.AssignableTo(mapperType.In(0)) {
			panic(fmt.Sprintf("Param of Map has to be a func with one param assignable to %v, but is %v", genResultType, mapperType.In(0)))
		}
	}
	if mapperType.NumOut() != 1 {
		panic(fmt.Sprintf("Param of Map has to be a func with one return value, but is %v", mapperType.NumOut()))
	} else if reflect.TypeOf(&GenResult{}).AssignableTo(mapperType.Out(0)) {
		genResultOutput = true
	}

	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		if genResultInput {
			var mapped reflect.Value
			if needsGenParameters {
				mapped = mapperVal.Call([]reflect.Value{reflect.ValueOf(result), reflect.ValueOf(genParams)})[0]
			} else {
				mapped = mapperVal.Call([]reflect.Value{reflect.ValueOf(result)})[0]
			}
			if genResultOutput {
				return mapped.Interface().(*GenResult)
			}
			return &GenResult{
				Shrinker:   NoShrinker,
				Result:     mapped.Interface(),
				Labels:     result.Labels,
				ResultType: mapperType.Out(0),
			}
		}
		value, ok := result.RetrieveAsValue()
		if ok {
			var mapped reflect.Value
			if needsGenParameters {
				mapped = mapperVal.Call([]reflect.Value{value, reflect.ValueOf(genParams)})[0]
			} else {
				mapped = mapperVal.Call([]reflect.Value{value})[0]
			}
			if genResultOutput {
				return mapped.Interface().(*GenResult)
			}
			return &GenResult{
				Shrinker:   NoShrinker,
				Result:     mapped.Interface(),
				Labels:     result.Labels,
				ResultType: mapperType.Out(0),
			}
		}
		return &GenResult{
			Shrinker:   NoShrinker,
			Result:     nil,
			Labels:     result.Labels,
			ResultType: mapperType.Out(0),
		}
	}
}

// FlatMap creates a derived generator by passing a generated value to a function which itself
// creates a generator.
func (g Gen) FlatMap(f func(interface{}) Gen, resultType reflect.Type) Gen {
	return func(genParams *GenParameters) *GenResult {
		result := g(genParams)
		value, ok := result.Retrieve()
		if ok {
			return f(value)(genParams)
		}
		return &GenResult{
			Shrinker:   NoShrinker,
			Result:     nil,
			Labels:     result.Labels,
			ResultType: resultType,
		}
	}
}

// MapResult creates a derived generator by mapping the GenResult directly.
// Contrary to `Map` and `FlatMap` this also allow the conversion of
// shrinkers and sieves, but implementation is more cumbersome.
// Deprecation note: Map now has the same functionality
func (g Gen) MapResult(f func(*GenResult) *GenResult) Gen {
	return func(genParams *GenParameters) *GenResult {
		return f(g(genParams))
	}
}

// CombineGens creates a generators from a list of generators.
// The result type will be a []interface{} containing the generated values of each generators in
// the list.
// Note: The combined generator will not have a sieve or shrinker.
func CombineGens(gens ...Gen) Gen {
	return func(genParams *GenParameters) *GenResult {
		labels := []string{}
		values := make([]interface{}, len(gens))
		shrinkers := make([]Shrinker, len(gens))
		sieves := make([]func(v interface{}) bool, len(gens))

		var ok bool
		for i, gen := range gens {
			result := gen(genParams)
			labels = append(labels, result.Labels...)
			shrinkers[i] = result.Shrinker
			sieves[i] = result.Sieve
			values[i], ok = result.Retrieve()
			if !ok {
				return &GenResult{
					Shrinker:   NoShrinker,
					Result:     nil,
					Labels:     result.Labels,
					ResultType: reflect.TypeOf(values),
				}
			}
		}
		return &GenResult{
			Shrinker:   CombineShrinker(shrinkers...),
			Result:     values,
			Labels:     labels,
			ResultType: reflect.TypeOf(values),
			Sieve: func(v interface{}) bool {
				values := v.([]interface{})
				for i, value := range values {
					if sieves[i] != nil && !sieves[i](value) {
						return false
					}
				}
				return true
			},
		}
	}
}
<|endoftext|>


<commit_before>package geo

import (
	"database/sql"
	"fmt"
	_ "github.com/bmizerany/pq"
	"math"
        "github.com/kylelemons/go-gypsy/yaml"
	"path"
	"os"
)

// TODO potentially package into file included with the package
var DefaultSQLConf = &SQLConf{driver: "postgres", openStr: "user=postgres password=*** dbname=points sslmode=disable", table: "points", latCol: "lat", lngCol: "lng"}

// Attempts to read config/geo.yml, and creates a {SQLConf} as described in the file
// Returns the DefaultSQLConf if no config/geo.yml is found.
// @return [*SQLConf].  The SQLConfiguration, as supplied with config/geo.yml
// @return [Error].  Any error that might occur while grabbing configuration
func GetSQLConf() (*SQLConf, error) {
	configPath := path.Join("config/geo.yml")
	_, err := os.Stat(configPath)
	if err != nil && os.IsNotExist(err) {
		return DefaultSQLConf, nil
	} else {
		config, readYamlErr := yaml.ReadFile(configPath)
		if readYamlErr == nil {

			// TODO Refactor this into a more generic method of retrieving info

			// Get driver
			driver, driveError := config.Get(fmt.Sprintf("%s.driver", "development"))
			if driveError != nil {
				return nil, driveError
			}

			// Get openStr
			openStr, openStrError := config.Get(fmt.Sprintf("%s.openStr", "development"))
			if openStrError != nil {
				return nil,openStrError
			}

			// Get table
			table, tableError := config.Get(fmt.Sprintf("%s.openStr", "development"))
			if tableError != nil {
				return nil, tableError
			}

			// Get latCol
			latCol, latColError := config.Get(fmt.Sprintf("%s.latCol", "development"))
			if latColError != nil {
				return nil, latColError
			}

			// Get lngCol
			lngCol, lngColError := config.Get(fmt.Sprintf("%s.lngCol", "development"))
			if lngColError != nil {
				return nil, lngColError
			}

			sqlConf := &SQLConf{driver: driver, openStr:openStr, table:table, latCol:latCol, lngCol:lngCol}
			return sqlConf, nil

		}

		return nil, readYamlErr
	}

	return nil, err
}

// Represents a Physical Point in geographic notation [lat, lng]
type Point struct {
	lat float64
	lng float64
}

// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
// @param [float64] dist.  The arc distance in which to transpose the origin point (in meters).
// @param [float64] bearing.  The compass bearing in which to transpose the origin point (in degrees).
// @return [*Point].  Returns a Point struct populated with the lat and lng coordinates
//                    of transposing the origin point a certain arc distance at a certain bearing.
func (p *Point) PointAtDistanceAndBearing(dist float64, bearing float64) *Point {
	// Earth's radius ~= 6,356.7523km
	// TODO Constantize
	dr := dist / 6356.7523

	bearing = (bearing * (math.Pi / 180.0))

	lat1 := (p.lat * (math.Pi / 180.0))
	lng1 := (p.lng * (math.Pi / 180.0))

	lat2_part1 := math.Sin(lat1) * math.Cos(dr)
	lat2_part2 := math.Cos(lat1) * math.Sin(dr) * math.Cos(bearing)

	lat2 := math.Asin(lat2_part1 + lat2_part2)

	lng2_part1 := math.Sin(bearing) * math.Sin(dr) * math.Cos(lat1)
	lng2_part2 := math.Cos(dr) - (math.Sin(lat1) * math.Sin(lat2))

	lng2 := lng1 + math.Atan2(lng2_part1, lng2_part2)
	lng2 = math.Mod((lng2+3*math.Pi), (2*math.Pi)) - math.Pi

	lat2 = lat2 * (180.0 / math.Pi)
	lng2 = lng2 * (180.0 / math.Pi)

	return &Point{lat: lat2, lng: lng2}
}

// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
// Calculates the Haversine distance between two points.
// @param [*Point].  The destination point.
// @return [float64].  The distance between the origin point and the destination point.
func (p * Point) Haversine(p2 * Point) (float64) {
	r := 6356.7523; // km
	dLat := (p2.lat-p.lat) * (math.Pi / 180.0)
	dLon := (p2.lng-p.lng) * (math.Pi / 180.0)

	lat1 := p.lat * (math.Pi / 180.0)
	lat2 := p2.lat * (math.Pi / 180.0)

	a1 := math.Sin(dLat/2) * math.Sin(dLat/2)
	a2 := math.Sin(dLon/2) * math.Sin(dLon/2) * math.Cos(lat1) * math.Cos(lat2);

	a := a1 + a2

	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a));

	return r * c;
}

// The Mapper interface
type Mapper interface {
	PointsWithinRadius(p *Point, radius int) bool
}

type SQLConf struct {
	driver  string
	openStr string
	table   string
	latCol  string
	lngCol  string
}

// A Mapper that uses Standard SQL Syntax
// to perform intersting geo-related mapping functions and queries
type SQLMapper struct {
	conf    *SQLConf
	sqlConn *sql.DB
}

// @return [*SQLMapper]. An instantiated SQLMapper struct with the DefaultSQLConf.
// @return [Error]. Any error that might have occured during instantiating the SQLMapper.
func HandleWithSQL() (*SQLMapper, error) {
	sqlConf, sqlConfErr := GetSQLConf()
	if sqlConfErr == nil {
		s := &SQLMapper{conf: sqlConf}

		db, err := sql.Open(s.conf.driver, s.conf.openStr)
		if err != nil {
			panic(err)
		}

		s.sqlConn = db
		return s, err
	}

	return nil, sqlConfErr
}

// Original implemenation from : http://www.movable-type.co.uk/scripts/latlong-db.html
// Uses SQL to retrieve all points within the radius of the origin point passed in.
// @param [*Point]. The origin point.
// @param [float64]. The radius (in meters) in which to search for points from the Origin.
// TODO Potentially fallback to PostgreSQL's earthdistance module: http://www.postgresql.org/docs/8.3/static/earthdistance.html
func (s *SQLMapper) PointsWithinRadius(p *Point, radius float64) (*sql.Rows, error) {
	select_str := fmt.Sprintf("SELECT * FROM %s a", s.conf.table)
	lat1 := fmt.Sprintf("sin(radians(%f)) * sin(radians(a.lat))", p.lat)
	lng1 := fmt.Sprintf("cos(radians(%f)) * cos(radians(a.lat)) * cos(radians(a.lng) - radians(%f))", p.lat, p.lng)
	where_str := fmt.Sprintf("WHERE acos(%s + %s) * %f <= %f", lat1, lng1, 6356.7523, radius)
	query := fmt.Sprintf("%s %s", select_str, where_str)

	res, err := s.sqlConn.Query(query)
	if err != nil {
		panic(err)
	}

	return res, err
}

/*
TODO Incoporate into README
func main() {
	s, err := HandleWithSQL()
	if err != nil {
		panic(err)
	}

	p := &Point{lat: 42.333, lng: 121.111}
	rows, err2 := s.Within(p, 15)
	if err2 != nil {
		panic(err)
	}

	for rows.Next() {
		var lat float32
		var lng float32
		err = rows.Scan(&lat, &lng)
		if err != nil {
			panic(err)
		}
		fmt.Printf("[%f, %f]", lat, lng)
	}
}
*/
<commit_msg>[src][derp] Fixing issue where table wasn't being applied to configured SQLConf from yaml parsing<commit_after>package geo

import (
	"database/sql"
	"fmt"
	_ "github.com/bmizerany/pq"
	"math"
        "github.com/kylelemons/go-gypsy/yaml"
	"path"
	"os"
)

// TODO potentially package into file included with the package
var DefaultSQLConf = &SQLConf{driver: "postgres", openStr: "user=postgres password=*** dbname=points sslmode=disable", table: "points", latCol: "lat", lngCol: "lng"}

// Attempts to read config/geo.yml, and creates a {SQLConf} as described in the file
// Returns the DefaultSQLConf if no config/geo.yml is found.
// @return [*SQLConf].  The SQLConfiguration, as supplied with config/geo.yml
// @return [Error].  Any error that might occur while grabbing configuration
func GetSQLConf() (*SQLConf, error) {
	configPath := path.Join("config/geo.yml")
	_, err := os.Stat(configPath)
	if err != nil && os.IsNotExist(err) {
		return DefaultSQLConf, nil
	} else {
		config, readYamlErr := yaml.ReadFile(configPath)
		if readYamlErr == nil {

			// TODO Refactor this into a more generic method of retrieving info

			// Get driver
			driver, driveError := config.Get(fmt.Sprintf("%s.driver", "development"))
			if driveError != nil {
				return nil, driveError
			}

			// Get openStr
			openStr, openStrError := config.Get(fmt.Sprintf("%s.openStr", "development"))
			if openStrError != nil {
				return nil,openStrError
			}

			// Get table
			table, tableError := config.Get(fmt.Sprintf("%s.table", "development"))
			if tableError != nil {
				return nil, tableError
			}

			// Get latCol
			latCol, latColError := config.Get(fmt.Sprintf("%s.latCol", "development"))
			if latColError != nil {
				return nil, latColError
			}

			// Get lngCol
			lngCol, lngColError := config.Get(fmt.Sprintf("%s.lngCol", "development"))
			if lngColError != nil {
				return nil, lngColError
			}

			sqlConf := &SQLConf{driver: driver, openStr:openStr, table:table, latCol:latCol, lngCol:lngCol}
			return sqlConf, nil

		}

		return nil, readYamlErr
	}

	return nil, err
}

// Represents a Physical Point in geographic notation [lat, lng]
type Point struct {
	lat float64
	lng float64
}

// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
// @param [float64] dist.  The arc distance in which to transpose the origin point (in meters).
// @param [float64] bearing.  The compass bearing in which to transpose the origin point (in degrees).
// @return [*Point].  Returns a Point struct populated with the lat and lng coordinates
//                    of transposing the origin point a certain arc distance at a certain bearing.
func (p *Point) PointAtDistanceAndBearing(dist float64, bearing float64) *Point {
	// Earth's radius ~= 6,356.7523km
	// TODO Constantize
	dr := dist / 6356.7523

	bearing = (bearing * (math.Pi / 180.0))

	lat1 := (p.lat * (math.Pi / 180.0))
	lng1 := (p.lng * (math.Pi / 180.0))

	lat2_part1 := math.Sin(lat1) * math.Cos(dr)
	lat2_part2 := math.Cos(lat1) * math.Sin(dr) * math.Cos(bearing)

	lat2 := math.Asin(lat2_part1 + lat2_part2)

	lng2_part1 := math.Sin(bearing) * math.Sin(dr) * math.Cos(lat1)
	lng2_part2 := math.Cos(dr) - (math.Sin(lat1) * math.Sin(lat2))

	lng2 := lng1 + math.Atan2(lng2_part1, lng2_part2)
	lng2 = math.Mod((lng2+3*math.Pi), (2*math.Pi)) - math.Pi

	lat2 = lat2 * (180.0 / math.Pi)
	lng2 = lng2 * (180.0 / math.Pi)

	return &Point{lat: lat2, lng: lng2}
}

// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
// Calculates the Haversine distance between two points.
// @param [*Point].  The destination point.
// @return [float64].  The distance between the origin point and the destination point.
func (p * Point) Haversine(p2 * Point) (float64) {
	r := 6356.7523; // km
	dLat := (p2.lat-p.lat) * (math.Pi / 180.0)
	dLon := (p2.lng-p.lng) * (math.Pi / 180.0)

	lat1 := p.lat * (math.Pi / 180.0)
	lat2 := p2.lat * (math.Pi / 180.0)

	a1 := math.Sin(dLat/2) * math.Sin(dLat/2)
	a2 := math.Sin(dLon/2) * math.Sin(dLon/2) * math.Cos(lat1) * math.Cos(lat2);

	a := a1 + a2

	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a));

	return r * c;
}

// The Mapper interface
type Mapper interface {
	PointsWithinRadius(p *Point, radius int) bool
}

type SQLConf struct {
	driver  string
	openStr string
	table   string
	latCol  string
	lngCol  string
}

// A Mapper that uses Standard SQL Syntax
// to perform intersting geo-related mapping functions and queries
type SQLMapper struct {
	conf    *SQLConf
	sqlConn *sql.DB
}

// @return [*SQLMapper]. An instantiated SQLMapper struct with the DefaultSQLConf.
// @return [Error]. Any error that might have occured during instantiating the SQLMapper.
func HandleWithSQL() (*SQLMapper, error) {
	sqlConf, sqlConfErr := GetSQLConf()
	if sqlConfErr == nil {
		s := &SQLMapper{conf: sqlConf}

		db, err := sql.Open(s.conf.driver, s.conf.openStr)
		if err != nil {
			panic(err)
		}

		s.sqlConn = db
		return s, err
	}

	return nil, sqlConfErr
}

// Original implemenation from : http://www.movable-type.co.uk/scripts/latlong-db.html
// Uses SQL to retrieve all points within the radius of the origin point passed in.
// @param [*Point]. The origin point.
// @param [float64]. The radius (in meters) in which to search for points from the Origin.
// TODO Potentially fallback to PostgreSQL's earthdistance module: http://www.postgresql.org/docs/8.3/static/earthdistance.html
func (s *SQLMapper) PointsWithinRadius(p *Point, radius float64) (*sql.Rows, error) {
	select_str := fmt.Sprintf("SELECT * FROM %s a", s.conf.table)
	lat1 := fmt.Sprintf("sin(radians(%f)) * sin(radians(a.lat))", p.lat)
	lng1 := fmt.Sprintf("cos(radians(%f)) * cos(radians(a.lat)) * cos(radians(a.lng) - radians(%f))", p.lat, p.lng)
	where_str := fmt.Sprintf("WHERE acos(%s + %s) * %f <= %f", lat1, lng1, 6356.7523, radius)
	query := fmt.Sprintf("%s %s", select_str, where_str)

	res, err := s.sqlConn.Query(query)
	if err != nil {
		panic(err)
	}

	return res, err
}

/*
TODO Incoporate into README
func main() {
	s, err := HandleWithSQL()
	if err != nil {
		panic(err)
	}

	p := &Point{lat: 42.333, lng: 121.111}
	rows, err2 := s.Within(p, 15)
	if err2 != nil {
		panic(err)
	}

	for rows.Next() {
		var lat float32
		var lng float32
		err = rows.Scan(&lat, &lng)
		if err != nil {
			panic(err)
		}
		fmt.Printf("[%f, %f]", lat, lng)
	}
}
*/
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "strings"
    "os/exec"
    "io/ioutil"
    "regexp"

    "code.google.com/p/go.text/encoding/japanese"
    "code.google.com/p/go.text/transform"
    "gopkg.in/fatih/set.v0"
)

func getPackageNamesOfCommitMessage() ([]string, error) {
    msg, err := getLastCommitMessage()

    if err != nil {
        return nil, err
    }

    if pattern, err := regexp.Compile(`\[([A-Za-z<>_\.-]+)\]`); err != nil {
        return nil, err
    } else {
        matches := pattern.FindAllStringSubmatch(msg, -1)
        names := []string{}

        for _, pair := range(matches) {
            names = append(names, pair[1])
        }

        return names, nil
    }
}

func getLastCommitMessage() (string, error) {
    cmd := exec.Command("git", "log", "-1", "--pretty=format:%s")
    msg, err := getCommandStdout(cmd)

    if err != nil {
        return "", err
    }

    return msg, nil
}

func getChangedRootDirs(depth int) ([]string, error) {
    paths, err := getChangedFilePaths(depth)

    if err != nil {
        return nil, err
    }

    pattern, err := regexp.Compile("([^/]*)/")

    if err != nil {
        return nil, err
    }

    dirs := set.New()

    for _, path := range(paths) {
        matches := pattern.FindStringSubmatch(path)

        if len(matches) >= 2 {
            dirs.Add(matches[1])
        }
    }

    return set.StringSlice(dirs), nil
}

func getChangedFilePaths(depth int) ([]string, error) {
    if changes, err := getChanges(depth); err != nil {
        return nil, err
    } else {
        lines := strings.Split(changes, "\n")
        return lines, nil
    }
}

func getChanges(depth int) (string, error) {
    rev := fmt.Sprintf("HEAD~%d", depth)
    cmd := exec.Command("git", "diff", "--name-only", rev)

    return getCommandStdout(cmd)
}

func getCommandStdout(cmd *exec.Cmd) (string, error) {
    stdoutpipe, err := cmd.StdoutPipe()
    if err != nil {
        return "", err
    }

    defer stdoutpipe.Close()

    if err = cmd.Start(); err != nil {
        return "", err
    }

    stdout, err := ioutil.ReadAll(
        transform.NewReader(stdoutpipe, japanese.ShiftJIS.NewDecoder()))
    if err != nil {
        return "", err
    }

    if err = cmd.Wait(); err != nil {
        return "", err
    }

    return string(stdout), nil
}
<commit_msg>Fix bug<commit_after>package main

import (
    "fmt"
    "strings"
    "os/exec"
    "io/ioutil"
    "regexp"

    "code.google.com/p/go.text/encoding/japanese"
    "code.google.com/p/go.text/transform"
    "gopkg.in/fatih/set.v0"
)

func getPackageNamesOfCommitMessage() ([]string, error) {
    msg, err := getLastCommitMessage()

    if err != nil {
        return nil, err
    }

    if pattern, err := regexp.Compile(`\[([A-Za-z0-9<>_\.-]+)\]`); err != nil {
        return nil, err
    } else {
        matches := pattern.FindAllStringSubmatch(msg, -1)
        names := []string{}

        for _, pair := range(matches) {
            names = append(names, pair[1])
        }

        return names, nil
    }
}

func getLastCommitMessage() (string, error) {
    cmd := exec.Command("git", "log", "-1", "--pretty=format:%s")
    msg, err := getCommandStdout(cmd)

    if err != nil {
        return "", err
    }

    return msg, nil
}

func getChangedRootDirs(depth int) ([]string, error) {
    paths, err := getChangedFilePaths(depth)

    if err != nil {
        return nil, err
    }

    pattern, err := regexp.Compile("([^/]*)/")

    if err != nil {
        return nil, err
    }

    dirs := set.New()

    for _, path := range(paths) {
        matches := pattern.FindStringSubmatch(path)

        if len(matches) >= 2 {
            dirs.Add(matches[1])
        }
    }

    return set.StringSlice(dirs), nil
}

func getChangedFilePaths(depth int) ([]string, error) {
    if changes, err := getChanges(depth); err != nil {
        return nil, err
    } else {
        lines := strings.Split(changes, "\n")
        return lines, nil
    }
}

func getChanges(depth int) (string, error) {
    rev := fmt.Sprintf("HEAD~%d", depth)
    cmd := exec.Command("git", "diff", "--name-only", rev)

    return getCommandStdout(cmd)
}

func getCommandStdout(cmd *exec.Cmd) (string, error) {
    stdoutpipe, err := cmd.StdoutPipe()
    if err != nil {
        return "", err
    }

    defer stdoutpipe.Close()

    if err = cmd.Start(); err != nil {
        return "", err
    }

    stdout, err := ioutil.ReadAll(
        transform.NewReader(stdoutpipe, japanese.ShiftJIS.NewDecoder()))
    if err != nil {
        return "", err
    }

    if err = cmd.Wait(); err != nil {
        return "", err
    }

    return string(stdout), nil
}
<|endoftext|>


<commit_before>package git

import (
	"bytes"
	"fmt"
	"os/exec"
	pathlib "path"
	"strings"

	"github.com/buckhx/pathutil"
)

var NOF = []string{}

type Repository struct {
	Path string
}

func (repo *Repository) Op(cmd string, flags []string, args ...string) (out string, err error) {
	flags = append(flags, "-C", repo.Path)
	return Operation(cmd, flags, args...)
}

func (repo *Repository) Init() (err error) {
	_, err = repo.Op("init", NOF)
	return
}

func (repo *Repository) Add(paths []string) (err error) {
	_, err = repo.Op("add", NOF, paths...)
	return
}

func (repo *Repository) Commit(msg string) (err error) {
	_, err = repo.Op("commit", NOF, "-am", msg)
	return

}

func (repo *Repository) Push() (err error) {
	_, err = repo.Op("push", NOF)
	return
}

func Operation(command string, flags []string, args ...string) (string, error) {
	var stderr, stdout bytes.Buffer
	args = append([]string{command}, args...)
	args = append(flags, args...)
	cmd := exec.Command("git", args...)
	cmd.Stderr = &stderr
	cmd.Stdout = &stdout
	err := cmd.Run()
	if err != nil {
		err = fmt.Errorf("%s\n%s\n", stderr.String(), strings.Join(append([]string{"git"}, args...), " "))
	}
	return stdout.String(), err
}

func IsRepository(path string) bool {
	return pathutil.Exists(pathlib.Join(path, ".git"))
}

func NewRepository(path string) (repo *Repository, err error) {
	if !pathutil.Exists(path) {
		err = fmt.Errorf("Cannot instantiate Repository because path doesn't exist at %q", path)
	} else {
		repo = &Repository{}
		repo.Path = path
	}
	return
}
<commit_msg>added Exclude<commit_after>package git

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	pathlib "path"
	"strings"

	"github.com/buckhx/pathutil"
)

var NOF = []string{}

type Repository struct {
	Path string
}

func (repo *Repository) Op(cmd string, flags []string, args ...string) (out string, err error) {
	flags = append(flags, "-C", repo.Path)
	return Operation(cmd, flags, args...)
}

func (repo *Repository) Init() (err error) {
	_, err = repo.Op("init", NOF)
	return
}

func (repo *Repository) Add(paths []string) (err error) {
	_, err = repo.Op("add", NOF, paths...)
	return
}

func (repo *Repository) Commit(msg string) (err error) {
	_, err = repo.Op("commit", NOF, "-am", msg)
	return
}

// Append these patterns to .git/info/exclude
func (repo *Repository) Exclude(patterns ...string) (err error) {
	excludef, err := os.OpenFile(pathlib.Join(repo.Path, ".git/info/exclude"), os.O_APPEND|os.O_WRONLY, 0600)
	defer excludef.Close()
	if err != nil {
		return
	}
	for _, pattern := range patterns {
		_, err = excludef.WriteString(pattern+"\n")
	}
	return
}

func (repo *Repository) Push() (err error) {
	_, err = repo.Op("push", NOF)
	return
}

func Operation(command string, flags []string, args ...string) (string, error) {
	var stderr, stdout bytes.Buffer
	args = append([]string{command}, args...)
	args = append(flags, args...)
	cmd := exec.Command("git", args...)
	cmd.Stderr = &stderr
	cmd.Stdout = &stdout
	err := cmd.Run()
	if err != nil {
		err = fmt.Errorf("%s\n%s\n", stderr.String(), strings.Join(append([]string{"git"}, args...), " "))
	}
	return stdout.String(), err
}

func IsRepository(path string) bool {
	return pathutil.Exists(pathlib.Join(path, ".git"))
}

func NewRepository(path string) (repo *Repository, err error) {
	if !pathutil.Exists(path) {
		err = fmt.Errorf("Cannot instantiate Repository because path doesn't exist at %q", path)
	} else {
		repo = &Repository{}
		repo.Path = path
	}
	return
}
<|endoftext|>


<commit_before>package glu

// #cgo pkg-config: glu
//
// #include <GL/glu.h>
//
import "C"
import "github.com/banthar/gl"
import "unsafe"

func Build2DMipmaps(target gl.GLenum, internalFormat int, width, height int, format gl.GLenum, data interface{}) int {
	t, p := gl.GetGLenumType(data)
	return int(C.gluBuild2DMipmaps(
		C.GLenum(target),
		C.GLint(internalFormat),
		C.GLsizei(width),
		C.GLsizei(height),
		C.GLenum(format),
		C.GLenum(t),
		p,
	))
}

func Perspective(fovy, aspect, zNear, zFar float64) {
	C.gluPerspective(
		C.GLdouble(fovy),
		C.GLdouble(aspect),
		C.GLdouble(zNear),
		C.GLdouble(zFar),
	)
}

func LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ float64) {
	C.gluLookAt(
		C.GLdouble(eyeX),
		C.GLdouble(eyeY),
		C.GLdouble(eyeZ),
		C.GLdouble(centerX),
		C.GLdouble(centerY),
		C.GLdouble(centerZ),
		C.GLdouble(upX),
		C.GLdouble(upY),
		C.GLdouble(upZ),
	)
}

func UnProject(winX, winY, winZ float64, model, proj, view unsafe.Pointer) (float64, float64, float64) {
	var ox, oy, oz C.GLdouble

	m := (*C.GLdouble)(model)
	p := (*C.GLdouble)(proj)
	v := (*C.GLint)(view)

	C.gluUnProject(
		C.GLdouble(winX),
		C.GLdouble(winY),
		C.GLdouble(winZ),
		m,
		p,
		v,
		&ox,
		&oy,
		&oz,
	)

	return float64(ox), float64(oy), float64(oz)
}

func NewQuadric() unsafe.Pointer {
	return unsafe.Pointer(C.gluNewQuadric())
}

func Sphere(q unsafe.Pointer, radius float32, slices, stacks int) {
	C.gluSphere((*[0]byte)(q), C.GLdouble(radius), C.GLint(slices), C.GLint(stacks))
}<commit_msg>removed unsafe.Pointer as parameters<commit_after>package glu

// #cgo pkg-config: glu
//
// #include <GL/glu.h>
//
import "C"
import "github.com/banthar/gl"
import "unsafe"

func Build2DMipmaps(target gl.GLenum, internalFormat int, width, height int, format gl.GLenum, data interface{}) int {
	t, p := gl.GetGLenumType(data)
	return int(C.gluBuild2DMipmaps(
		C.GLenum(target),
		C.GLint(internalFormat),
		C.GLsizei(width),
		C.GLsizei(height),
		C.GLenum(format),
		C.GLenum(t),
		p,
	))
}

func Perspective(fovy, aspect, zNear, zFar float64) {
	C.gluPerspective(
		C.GLdouble(fovy),
		C.GLdouble(aspect),
		C.GLdouble(zNear),
		C.GLdouble(zFar),
	)
}

func LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ float64) {
	C.gluLookAt(
		C.GLdouble(eyeX),
		C.GLdouble(eyeY),
		C.GLdouble(eyeZ),
		C.GLdouble(centerX),
		C.GLdouble(centerY),
		C.GLdouble(centerZ),
		C.GLdouble(upX),
		C.GLdouble(upY),
		C.GLdouble(upZ),
	)
}

func UnProject(winX, winY, winZ float64, model, proj *[16]float64, view *[4]int32) (float64, float64, float64) {
	var ox, oy, oz C.GLdouble

	m := (*C.GLdouble)(unsafe.Pointer(model))
	p := (*C.GLdouble)(unsafe.Pointer(proj))
	v := (*C.GLint)(unsafe.Pointer(view))

	C.gluUnProject(
		C.GLdouble(winX),
		C.GLdouble(winY),
		C.GLdouble(winZ),
		m,
		p,
		v,
		&ox,
		&oy,
		&oz,
	)

	return float64(ox), float64(oy), float64(oz)
}

func NewQuadric() unsafe.Pointer {
	return unsafe.Pointer(C.gluNewQuadric())
}

func Sphere(q unsafe.Pointer, radius float32, slices, stacks int) {
	C.gluSphere((*[0]byte)(q), C.GLdouble(radius), C.GLint(slices), C.GLint(stacks))
}<|endoftext|>