<commit_before>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Gauge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Gauge.  If not, see <http://www.gnu.org/licenses/>.

/*
   Execution can be of two types
	- Simple execution
	- Paralell execution

   Execution Flow :
   	- Checks for updates
    	- Validation
    	- Init Registry
    	- Saving Execution result

   Strategy
    	- Lazy : Lazy is a parallelization strategy for execution. In this case tests assignment will be dynamic during execution, i.e. assign the next spec in line to the stream that has completed it’s previous execution and is waiting for more work.
    	- Eager : Eager is a parallelization strategy for execution. In this case tests are distributed before execution, thus making them an equal number based distribution.
*/
package execution

import (
	"strconv"
	"time"

	"github.com/getgauge/gauge/skel"

	"fmt"

	"strings"

	"os"

	"sync"

	"runtime/debug"

	"encoding/json"
	"io/ioutil"
	"path/filepath"

	"github.com/getgauge/common"
	"github.com/getgauge/gauge/config"
	"github.com/getgauge/gauge/env"
	"github.com/getgauge/gauge/execution/event"
	"github.com/getgauge/gauge/execution/rerun"
	"github.com/getgauge/gauge/execution/result"
	"github.com/getgauge/gauge/gauge"
	"github.com/getgauge/gauge/logger"
	"github.com/getgauge/gauge/manifest"
	"github.com/getgauge/gauge/plugin"
	"github.com/getgauge/gauge/plugin/install"
	"github.com/getgauge/gauge/reporter"
	"github.com/getgauge/gauge/runner"
	"github.com/getgauge/gauge/util"
	"github.com/getgauge/gauge/validation"
)

const (
	executionStatusFile = "executionStatus.json"
)

// NumberOfExecutionStreams shows the number of execution streams, in parallel execution.
var NumberOfExecutionStreams int

// InParallel if true executes the specs in parallel else in serial.
var InParallel bool

type suiteExecutor interface {
	run() *result.SuiteResult
}

type executor interface {
	execute(i gauge.Item, r result.Result)
}

type executionInfo struct {
	manifest        *manifest.Manifest
	specs           *gauge.SpecCollection
	runner          runner.Runner
	pluginHandler   plugin.Handler
	errMaps         *gauge.BuildErrors
	inParallel      bool
	numberOfStreams int
	stream          int
}

func newExecutionInfo(s *gauge.SpecCollection, r runner.Runner, ph plugin.Handler, e *gauge.BuildErrors, p bool, stream int) *executionInfo {
	m, err := manifest.ProjectManifest()
	if err != nil {
		logger.Fatalf(err.Error())
	}
	return &executionInfo{
		manifest:        m,
		specs:           s,
		runner:          r,
		pluginHandler:   ph,
		errMaps:         e,
		inParallel:      p,
		numberOfStreams: NumberOfExecutionStreams,
		stream:          stream,
	}
}

// ExecuteSpecs : Check for updates, validates the specs (by invoking the respective language runners), initiates the registry which is needed for console reporting, execution API and Rerunning of specs
// and finally saves the execution result as binary in .gauge folder.
func ExecuteSpecs(specDirs []string) int {
	err := validateFlags()
	if err != nil {
		logger.Fatalf(err.Error())
	}
	if config.CheckUpdates() {
		i := &install.UpdateFacade{}
		i.BufferUpdateDetails()
		defer i.PrintUpdateBuffer()
	}
	skel.SetupPlugins()
	res := validation.ValidateSpecs(specDirs, false)
	if len(res.Errs) > 0 {
		return 1
	}
	if res.SpecCollection.Size() < 1 {
		logger.Infof("No specifications found in %s.", strings.Join(specDirs, ", "))
		res.Runner.Kill()
		if res.ParseOk {
			return 0
		}
		return 1
	}
	event.InitRegistry()
	wg := &sync.WaitGroup{}
	reporter.ListenExecutionEvents(wg)
	rerun.ListenFailedScenarios(wg, specDirs)
	if util.ConvertToBool(os.Getenv(env.SaveExecutionResult), env.SaveExecutionResult, false) {
		ListenSuiteEndAndSaveResult(wg)
	}
	defer wg.Wait()
	defer recoverPanic()
	ei := newExecutionInfo(res.SpecCollection, res.Runner, nil, res.ErrMap, InParallel, 0)
	e := newExecution(ei)
	return printExecutionStatus(e.run(), res.ParseOk)
}

func recoverPanic() {
	if r := recover(); r != nil {
		logger.Infof("%v\n%s", r, string(debug.Stack()))
		os.Exit(1)
	}
}

func newExecution(executionInfo *executionInfo) suiteExecutor {
	if executionInfo.inParallel {
		return newParallelExecution(executionInfo)
	}
	return newSimpleExecution(executionInfo, true)
}

type executionStatus struct {
	SpecsExecuted int `json:"specsExecuted"`
	SpecsPassed   int `json:"specsPassesd"`
	SpecsFailed   int `json:"specsFailed"`
	SpecsSkipped  int `json:"specsSkipped"`
	SceExecuted   int `json:"sceExecuted"`
	ScePassed     int `json:"scePassed"`
	SceFailed     int `json:"sceFailed"`
	SceSkipped    int `json:"sceSkipped"`
}

func (status *executionStatus) getJSON() (string, error) {
	j, err := json.MarshalIndent(status, "", "\t")
	if err != nil {
		return "", err
	}
	return string(j), nil
}

func writeExecutionStatus(executedSpecs, passedSpecs, failedSpecs, skippedSpecs, executedScenarios, passedScenarios, failedScenarios, skippedScenarios int) {
	executionStatus := &executionStatus{}
	executionStatus.SpecsExecuted = executedSpecs
	executionStatus.SpecsPassed = passedSpecs
	executionStatus.SpecsFailed = failedSpecs
	executionStatus.SpecsSkipped = skippedSpecs
	executionStatus.SceExecuted = executedScenarios
	executionStatus.ScePassed = passedScenarios
	executionStatus.SceFailed = failedScenarios
	executionStatus.SceSkipped = skippedScenarios
	contents, err := executionStatus.getJSON()
	if err != nil {
		logger.Fatalf("Unable to parse execution status information : %v", err.Error())
	}
	executionStatusFile := filepath.Join(config.ProjectRoot, common.DotGauge, executionStatusFile)
	dotGaugeDir := filepath.Join(config.ProjectRoot, common.DotGauge)
	if err = os.MkdirAll(dotGaugeDir, common.NewDirectoryPermissions); err != nil {
		logger.Fatalf("Failed to create directory in %s. Reason: %s", dotGaugeDir, err.Error())
	}
	err = ioutil.WriteFile(executionStatusFile, []byte(contents), common.NewFilePermissions)
	if err != nil {
		logger.Fatalf("Failed to write to %s. Reason: %s", executionStatusFile, err.Error())
	}
}

func ReadExecutionStatus() (interface{}, error) {
	contents, err := common.ReadFileContents(filepath.Join(config.ProjectRoot, common.DotGauge, executionStatusFile))
	if err != nil {
		logger.Fatalf("Failed to read execution status information. Reason: %s", err.Error())
	}
	meta := &executionStatus{}
	if err = json.Unmarshal([]byte(contents), meta); err != nil {
		logger.Fatalf("Invalid execution status information. Reason: %s", err.Error())
		return meta, err
	}
	return meta, nil
}

func printExecutionStatus(suiteResult *result.SuiteResult, isParsingOk bool) int {
	nSkippedSpecs := suiteResult.SpecsSkippedCount
	var nExecutedSpecs int
	if len(suiteResult.SpecResults) != 0 {
		nExecutedSpecs = len(suiteResult.SpecResults) - nSkippedSpecs
	}
	nFailedSpecs := suiteResult.SpecsFailedCount
	nPassedSpecs := nExecutedSpecs - nFailedSpecs

	nExecutedScenarios := 0
	nFailedScenarios := 0
	nPassedScenarios := 0
	nSkippedScenarios := 0
	for _, specResult := range suiteResult.SpecResults {
		nExecutedScenarios += specResult.ScenarioCount
		nFailedScenarios += specResult.ScenarioFailedCount
		nSkippedScenarios += specResult.ScenarioSkippedCount
	}
	nExecutedScenarios -= nSkippedScenarios
	nPassedScenarios = nExecutedScenarios - nFailedScenarios
	if nExecutedScenarios < 0 {
		nExecutedScenarios = 0
	}

	if nPassedScenarios < 0 {
		nPassedScenarios = 0
	}

	logger.Infof("Specifications:\t%d executed\t%d passed\t%d failed\t%d skipped", nExecutedSpecs, nPassedSpecs, nFailedSpecs, nSkippedSpecs)
	logger.Infof("Scenarios:\t%d executed\t%d passed\t%d failed\t%d skipped", nExecutedScenarios, nPassedScenarios, nFailedScenarios, nSkippedScenarios)
	logger.Infof("\nTotal time taken: %s", time.Millisecond*time.Duration(suiteResult.ExecutionTime))

	writeExecutionStatus(nExecutedSpecs, nPassedSpecs, nFailedSpecs, nSkippedSpecs, nExecutedScenarios, nPassedScenarios, nFailedScenarios, nSkippedScenarios)

	if suiteResult.IsFailed || !isParsingOk {
		return 1
	}
	return 0
}

func validateFlags() error {
	if !InParallel {
		return nil
	}
	if NumberOfExecutionStreams < 1 {
		return fmt.Errorf("Invalid input(%s) to --n flag.", strconv.Itoa(NumberOfExecutionStreams))
	}
	if !isValidStrategy(Strategy) {
		return fmt.Errorf("Invalid input(%s) to --strategy flag.", Strategy)
	}
	return nil
}
<commit_msg>Fixing the typo<commit_after>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Gauge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Gauge.  If not, see <http://www.gnu.org/licenses/>.

/*
   Execution can be of two types
	- Simple execution
	- Paralell execution

   Execution Flow :
   	- Checks for updates
    	- Validation
    	- Init Registry
    	- Saving Execution result

   Strategy
    	- Lazy : Lazy is a parallelization strategy for execution. In this case tests assignment will be dynamic during execution, i.e. assign the next spec in line to the stream that has completed it’s previous execution and is waiting for more work.
    	- Eager : Eager is a parallelization strategy for execution. In this case tests are distributed before execution, thus making them an equal number based distribution.
*/
package execution

import (
	"strconv"
	"time"

	"github.com/getgauge/gauge/skel"

	"fmt"

	"strings"

	"os"

	"sync"

	"runtime/debug"

	"encoding/json"
	"io/ioutil"
	"path/filepath"

	"github.com/getgauge/common"
	"github.com/getgauge/gauge/config"
	"github.com/getgauge/gauge/env"
	"github.com/getgauge/gauge/execution/event"
	"github.com/getgauge/gauge/execution/rerun"
	"github.com/getgauge/gauge/execution/result"
	"github.com/getgauge/gauge/gauge"
	"github.com/getgauge/gauge/logger"
	"github.com/getgauge/gauge/manifest"
	"github.com/getgauge/gauge/plugin"
	"github.com/getgauge/gauge/plugin/install"
	"github.com/getgauge/gauge/reporter"
	"github.com/getgauge/gauge/runner"
	"github.com/getgauge/gauge/util"
	"github.com/getgauge/gauge/validation"
)

const (
	executionStatusFile = "executionStatus.json"
)

// NumberOfExecutionStreams shows the number of execution streams, in parallel execution.
var NumberOfExecutionStreams int

// InParallel if true executes the specs in parallel else in serial.
var InParallel bool

type suiteExecutor interface {
	run() *result.SuiteResult
}

type executor interface {
	execute(i gauge.Item, r result.Result)
}

type executionInfo struct {
	manifest        *manifest.Manifest
	specs           *gauge.SpecCollection
	runner          runner.Runner
	pluginHandler   plugin.Handler
	errMaps         *gauge.BuildErrors
	inParallel      bool
	numberOfStreams int
	stream          int
}

func newExecutionInfo(s *gauge.SpecCollection, r runner.Runner, ph plugin.Handler, e *gauge.BuildErrors, p bool, stream int) *executionInfo {
	m, err := manifest.ProjectManifest()
	if err != nil {
		logger.Fatalf(err.Error())
	}
	return &executionInfo{
		manifest:        m,
		specs:           s,
		runner:          r,
		pluginHandler:   ph,
		errMaps:         e,
		inParallel:      p,
		numberOfStreams: NumberOfExecutionStreams,
		stream:          stream,
	}
}

// ExecuteSpecs : Check for updates, validates the specs (by invoking the respective language runners), initiates the registry which is needed for console reporting, execution API and Rerunning of specs
// and finally saves the execution result as binary in .gauge folder.
func ExecuteSpecs(specDirs []string) int {
	err := validateFlags()
	if err != nil {
		logger.Fatalf(err.Error())
	}
	if config.CheckUpdates() {
		i := &install.UpdateFacade{}
		i.BufferUpdateDetails()
		defer i.PrintUpdateBuffer()
	}
	skel.SetupPlugins()
	res := validation.ValidateSpecs(specDirs, false)
	if len(res.Errs) > 0 {
		return 1
	}
	if res.SpecCollection.Size() < 1 {
		logger.Infof("No specifications found in %s.", strings.Join(specDirs, ", "))
		res.Runner.Kill()
		if res.ParseOk {
			return 0
		}
		return 1
	}
	event.InitRegistry()
	wg := &sync.WaitGroup{}
	reporter.ListenExecutionEvents(wg)
	rerun.ListenFailedScenarios(wg, specDirs)
	if util.ConvertToBool(os.Getenv(env.SaveExecutionResult), env.SaveExecutionResult, false) {
		ListenSuiteEndAndSaveResult(wg)
	}
	defer wg.Wait()
	defer recoverPanic()
	ei := newExecutionInfo(res.SpecCollection, res.Runner, nil, res.ErrMap, InParallel, 0)
	e := newExecution(ei)
	return printExecutionStatus(e.run(), res.ParseOk)
}

func recoverPanic() {
	if r := recover(); r != nil {
		logger.Infof("%v\n%s", r, string(debug.Stack()))
		os.Exit(1)
	}
}

func newExecution(executionInfo *executionInfo) suiteExecutor {
	if executionInfo.inParallel {
		return newParallelExecution(executionInfo)
	}
	return newSimpleExecution(executionInfo, true)
}

type executionStatus struct {
	SpecsExecuted int `json:"specsExecuted"`
	SpecsPassed   int `json:"specsPassed"`
	SpecsFailed   int `json:"specsFailed"`
	SpecsSkipped  int `json:"specsSkipped"`
	SceExecuted   int `json:"sceExecuted"`
	ScePassed     int `json:"scePassed"`
	SceFailed     int `json:"sceFailed"`
	SceSkipped    int `json:"sceSkipped"`
}

func (status *executionStatus) getJSON() (string, error) {
	j, err := json.MarshalIndent(status, "", "\t")
	if err != nil {
		return "", err
	}
	return string(j), nil
}

func writeExecutionStatus(executedSpecs, passedSpecs, failedSpecs, skippedSpecs, executedScenarios, passedScenarios, failedScenarios, skippedScenarios int) {
	executionStatus := &executionStatus{}
	executionStatus.SpecsExecuted = executedSpecs
	executionStatus.SpecsPassed = passedSpecs
	executionStatus.SpecsFailed = failedSpecs
	executionStatus.SpecsSkipped = skippedSpecs
	executionStatus.SceExecuted = executedScenarios
	executionStatus.ScePassed = passedScenarios
	executionStatus.SceFailed = failedScenarios
	executionStatus.SceSkipped = skippedScenarios
	contents, err := executionStatus.getJSON()
	if err != nil {
		logger.Fatalf("Unable to parse execution status information : %v", err.Error())
	}
	executionStatusFile := filepath.Join(config.ProjectRoot, common.DotGauge, executionStatusFile)
	dotGaugeDir := filepath.Join(config.ProjectRoot, common.DotGauge)
	if err = os.MkdirAll(dotGaugeDir, common.NewDirectoryPermissions); err != nil {
		logger.Fatalf("Failed to create directory in %s. Reason: %s", dotGaugeDir, err.Error())
	}
	err = ioutil.WriteFile(executionStatusFile, []byte(contents), common.NewFilePermissions)
	if err != nil {
		logger.Fatalf("Failed to write to %s. Reason: %s", executionStatusFile, err.Error())
	}
}

func ReadExecutionStatus() (interface{}, error) {
	contents, err := common.ReadFileContents(filepath.Join(config.ProjectRoot, common.DotGauge, executionStatusFile))
	if err != nil {
		logger.Fatalf("Failed to read execution status information. Reason: %s", err.Error())
	}
	meta := &executionStatus{}
	if err = json.Unmarshal([]byte(contents), meta); err != nil {
		logger.Fatalf("Invalid execution status information. Reason: %s", err.Error())
		return meta, err
	}
	return meta, nil
}

func printExecutionStatus(suiteResult *result.SuiteResult, isParsingOk bool) int {
	nSkippedSpecs := suiteResult.SpecsSkippedCount
	var nExecutedSpecs int
	if len(suiteResult.SpecResults) != 0 {
		nExecutedSpecs = len(suiteResult.SpecResults) - nSkippedSpecs
	}
	nFailedSpecs := suiteResult.SpecsFailedCount
	nPassedSpecs := nExecutedSpecs - nFailedSpecs

	nExecutedScenarios := 0
	nFailedScenarios := 0
	nPassedScenarios := 0
	nSkippedScenarios := 0
	for _, specResult := range suiteResult.SpecResults {
		nExecutedScenarios += specResult.ScenarioCount
		nFailedScenarios += specResult.ScenarioFailedCount
		nSkippedScenarios += specResult.ScenarioSkippedCount
	}
	nExecutedScenarios -= nSkippedScenarios
	nPassedScenarios = nExecutedScenarios - nFailedScenarios
	if nExecutedScenarios < 0 {
		nExecutedScenarios = 0
	}

	if nPassedScenarios < 0 {
		nPassedScenarios = 0
	}

	logger.Infof("Specifications:\t%d executed\t%d passed\t%d failed\t%d skipped", nExecutedSpecs, nPassedSpecs, nFailedSpecs, nSkippedSpecs)
	logger.Infof("Scenarios:\t%d executed\t%d passed\t%d failed\t%d skipped", nExecutedScenarios, nPassedScenarios, nFailedScenarios, nSkippedScenarios)
	logger.Infof("\nTotal time taken: %s", time.Millisecond*time.Duration(suiteResult.ExecutionTime))

	writeExecutionStatus(nExecutedSpecs, nPassedSpecs, nFailedSpecs, nSkippedSpecs, nExecutedScenarios, nPassedScenarios, nFailedScenarios, nSkippedScenarios)

	if suiteResult.IsFailed || !isParsingOk {
		return 1
	}
	return 0
}

func validateFlags() error {
	if !InParallel {
		return nil
	}
	if NumberOfExecutionStreams < 1 {
		return fmt.Errorf("Invalid input(%s) to --n flag.", strconv.Itoa(NumberOfExecutionStreams))
	}
	if !isValidStrategy(Strategy) {
		return fmt.Errorf("Invalid input(%s) to --strategy flag.", Strategy)
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 The etcd Authors
//
// 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 tcpproxy

import (
	"io"
	"net"
	"sync"
	"time"

	"github.com/coreos/pkg/capnslog"
)

var (
	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "proxy/tcpproxy")
)

type remote struct {
	mu       sync.Mutex
	addr     string
	inactive bool
}

func (r *remote) inactivate() {
	r.mu.Lock()
	defer r.mu.Unlock()
	r.inactive = true
}

func (r *remote) tryReactivate() error {
	conn, err := net.Dial("tcp", r.addr)
	if err != nil {
		return err
	}
	conn.Close()
	r.mu.Lock()
	defer r.mu.Unlock()
	r.inactive = false
	return nil
}

func (r *remote) isActive() bool {
	r.mu.Lock()
	defer r.mu.Unlock()
	return !r.inactive
}

type TCPProxy struct {
	Listener        net.Listener
	Endpoints       []string
	MonitorInterval time.Duration

	donec chan struct{}

	mu         sync.Mutex // guards the following fields
	remotes    []*remote
	nextRemote int
}

func (tp *TCPProxy) Run() error {
	tp.donec = make(chan struct{})
	if tp.MonitorInterval == 0 {
		tp.MonitorInterval = 5 * time.Minute
	}
	for _, ep := range tp.Endpoints {
		tp.remotes = append(tp.remotes, &remote{addr: ep})
	}

	plog.Printf("ready to proxy client requests to %v", tp.Endpoints)
	go tp.runMonitor()
	for {
		in, err := tp.Listener.Accept()
		if err != nil {
			return err
		}

		go tp.serve(in)
	}
}

func (tp *TCPProxy) numRemotes() int {
	tp.mu.Lock()
	defer tp.mu.Unlock()
	return len(tp.remotes)
}

func (tp *TCPProxy) serve(in net.Conn) {
	var (
		err error
		out net.Conn
	)

	for i := 0; i < tp.numRemotes(); i++ {
		remote := tp.pick()
		if !remote.isActive() {
			continue
		}
		// TODO: add timeout
		out, err = net.Dial("tcp", remote.addr)
		if err == nil {
			break
		}
		remote.inactivate()
		plog.Warningf("deactivated endpoint [%s] due to %v for %v", remote.addr, err, tp.MonitorInterval)
	}

	if out == nil {
		in.Close()
		return
	}

	go func() {
		io.Copy(in, out)
		in.Close()
		out.Close()
	}()

	io.Copy(out, in)
	out.Close()
	in.Close()
}

// pick picks a remote in round-robin fashion
func (tp *TCPProxy) pick() *remote {
	tp.mu.Lock()
	defer tp.mu.Unlock()

	picked := tp.remotes[tp.nextRemote]
	tp.nextRemote = (tp.nextRemote + 1) % len(tp.remotes)
	return picked
}

func (tp *TCPProxy) runMonitor() {
	for {
		select {
		case <-time.After(tp.MonitorInterval):
			tp.mu.Lock()
			for _, r := range tp.remotes {
				if !r.isActive() {
					go func() {
						if err := r.tryReactivate(); err != nil {
							plog.Warningf("failed to activate endpoint [%s] due to %v (stay inactive for another %v)", r.addr, err, tp.MonitorInterval)
						} else {
							plog.Printf("activated %s", r.addr)
						}
					}()
				}
			}
			tp.mu.Unlock()
		case <-tp.donec:
			return
		}
	}
}

func (tp *TCPProxy) Stop() {
	// graceful shutdown?
	// shutdown current connections?
	tp.Listener.Close()
	close(tp.donec)
}
<commit_msg>tcpproxy: don't use range variable in reactivate goroutine<commit_after>// Copyright 2016 The etcd Authors
//
// 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 tcpproxy

import (
	"io"
	"net"
	"sync"
	"time"

	"github.com/coreos/pkg/capnslog"
)

var (
	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "proxy/tcpproxy")
)

type remote struct {
	mu       sync.Mutex
	addr     string
	inactive bool
}

func (r *remote) inactivate() {
	r.mu.Lock()
	defer r.mu.Unlock()
	r.inactive = true
}

func (r *remote) tryReactivate() error {
	conn, err := net.Dial("tcp", r.addr)
	if err != nil {
		return err
	}
	conn.Close()
	r.mu.Lock()
	defer r.mu.Unlock()
	r.inactive = false
	return nil
}

func (r *remote) isActive() bool {
	r.mu.Lock()
	defer r.mu.Unlock()
	return !r.inactive
}

type TCPProxy struct {
	Listener        net.Listener
	Endpoints       []string
	MonitorInterval time.Duration

	donec chan struct{}

	mu         sync.Mutex // guards the following fields
	remotes    []*remote
	nextRemote int
}

func (tp *TCPProxy) Run() error {
	tp.donec = make(chan struct{})
	if tp.MonitorInterval == 0 {
		tp.MonitorInterval = 5 * time.Minute
	}
	for _, ep := range tp.Endpoints {
		tp.remotes = append(tp.remotes, &remote{addr: ep})
	}

	plog.Printf("ready to proxy client requests to %v", tp.Endpoints)
	go tp.runMonitor()
	for {
		in, err := tp.Listener.Accept()
		if err != nil {
			return err
		}

		go tp.serve(in)
	}
}

func (tp *TCPProxy) numRemotes() int {
	tp.mu.Lock()
	defer tp.mu.Unlock()
	return len(tp.remotes)
}

func (tp *TCPProxy) serve(in net.Conn) {
	var (
		err error
		out net.Conn
	)

	for i := 0; i < tp.numRemotes(); i++ {
		remote := tp.pick()
		if !remote.isActive() {
			continue
		}
		// TODO: add timeout
		out, err = net.Dial("tcp", remote.addr)
		if err == nil {
			break
		}
		remote.inactivate()
		plog.Warningf("deactivated endpoint [%s] due to %v for %v", remote.addr, err, tp.MonitorInterval)
	}

	if out == nil {
		in.Close()
		return
	}

	go func() {
		io.Copy(in, out)
		in.Close()
		out.Close()
	}()

	io.Copy(out, in)
	out.Close()
	in.Close()
}

// pick picks a remote in round-robin fashion
func (tp *TCPProxy) pick() *remote {
	tp.mu.Lock()
	defer tp.mu.Unlock()

	picked := tp.remotes[tp.nextRemote]
	tp.nextRemote = (tp.nextRemote + 1) % len(tp.remotes)
	return picked
}

func (tp *TCPProxy) runMonitor() {
	for {
		select {
		case <-time.After(tp.MonitorInterval):
			tp.mu.Lock()
			for _, rem := range tp.remotes {
				if rem.isActive() {
					continue
				}
				go func(r *remote) {
					if err := r.tryReactivate(); err != nil {
						plog.Warningf("failed to activate endpoint [%s] due to %v (stay inactive for another %v)", r.addr, err, tp.MonitorInterval)
					} else {
						plog.Printf("activated %s", r.addr)
					}
				}(rem)
			}
			tp.mu.Unlock()
		case <-tp.donec:
			return
		}
	}
}

func (tp *TCPProxy) Stop() {
	// graceful shutdown?
	// shutdown current connections?
	tp.Listener.Close()
	close(tp.donec)
}
<|endoftext|>


<commit_before>package blocks

import (
	"log"
)

var (
	Library     BlockLibrary
	libraryBlob string
)

// A block library is a collection of possible block templates
type BlockLibrary map[string]*BlockTemplate

func BuildLibrary() {
	log.Println("building block library")
	Library = make(map[string]*BlockTemplate)

	templates := []*BlockTemplate{
		&BlockTemplate{
			BlockType:  "ticker",
			RouteNames: []string{"set_rule", "get_rule"},
			Routine:    Ticker,
		},
		&BlockTemplate{
			BlockType:  "connection",
			RouteNames: []string{"last_seen"},
			Routine:    Connection,
		},
		&BlockTemplate{
			BlockType:  "tolog",
			RouteNames: []string{},
			Routine:    ToLog,
		},
		&BlockTemplate{
			BlockType:  "random",
			RouteNames: []string{"set_rule"},
			Routine:    Random,
		},
		&BlockTemplate{
			BlockType:  "count",
			RouteNames: []string{"set_rule", "count"},
			Routine:    Count,
		},
		&BlockTemplate{
			BlockType:  "bunch",
			RouteNames: []string{"set_rule"},
			Routine:    Bunch,
		},
		&BlockTemplate{
			BlockType:  "post",
			RouteNames: []string{"set_rule"},
			Routine:    Post,
		},
	}

	for _, t := range templates {
		Library[t.BlockType] = t
	}
}
<commit_msg>forgot library entry<commit_after>package blocks

import (
	"log"
)

var (
	Library     BlockLibrary
	libraryBlob string
)

// A block library is a collection of possible block templates
type BlockLibrary map[string]*BlockTemplate

func BuildLibrary() {
	log.Println("building block library")
	Library = make(map[string]*BlockTemplate)

	templates := []*BlockTemplate{
		&BlockTemplate{
			BlockType:  "ticker",
			RouteNames: []string{"set_rule", "get_rule"},
			Routine:    Ticker,
		},
		&BlockTemplate{
			BlockType:  "connection",
			RouteNames: []string{"last_seen"},
			Routine:    Connection,
		},
		&BlockTemplate{
			BlockType:  "tolog",
			RouteNames: []string{},
			Routine:    ToLog,
		},
		&BlockTemplate{
			BlockType:  "random",
			RouteNames: []string{"set_rule"},
			Routine:    Random,
		},
		&BlockTemplate{
			BlockType:  "count",
			RouteNames: []string{"set_rule", "count"},
			Routine:    Count,
		},
		&BlockTemplate{
			BlockType:  "bunch",
			RouteNames: []string{"set_rule"},
			Routine:    Bunch,
		},
		&BlockTemplate{
			BlockType:  "post",
			RouteNames: []string{"set_rule"},
			Routine:    Post,
		},
		&BlockTemplate{
			BlockType:  "date",
			RouteNames: []string{"set_rule"},
			Routine:    Date,
		},
	}

	for _, t := range templates {
		Library[t.BlockType] = t
	}
}
<|endoftext|>


<commit_before>package slack

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/nlopes/slack"

	"github.com/keel-hq/keel/bot"
	"github.com/keel-hq/keel/constants"
	"github.com/keel-hq/keel/version"

	log "github.com/sirupsen/logrus"
)

// SlackImplementer - implementes slack HTTP functionality, used to
// send messages with attachments
type SlackImplementer interface {
	PostMessage(channelID string, options ...slack.MsgOption) (string, string, error)
}

// Bot - main slack bot container
type Bot struct {
	id   string // bot id
	name string // bot name

	users map[string]string

	msgPrefix string

	slackClient *slack.Client
	slackRTM    *slack.RTM

	slackHTTPClient SlackImplementer

	approvalsChannel string // slack approvals channel name

	ctx                context.Context
	botMessagesChannel chan *bot.BotMessage
	approvalsRespCh    chan *bot.ApprovalResponse
}

func init() {
	bot.RegisterBot("slack", &Bot{})
}

func (b *Bot) Configure(approvalsRespCh chan *bot.ApprovalResponse, botMessagesChannel chan *bot.BotMessage) bool {
	if os.Getenv(constants.EnvSlackToken) != "" {

		b.name = "keel"
		if bootName := os.Getenv(constants.EnvSlackBotName); bootName != "" {
			b.name = bootName
		}

		token := os.Getenv(constants.EnvSlackToken)
		client := slack.New(token)

		b.approvalsChannel = "general"
		if channel := os.Getenv(constants.EnvSlackApprovalsChannel); channel != "" {
			b.approvalsChannel = strings.TrimPrefix(channel, "#")
		}

		b.slackClient = client
		b.slackHTTPClient = client
		b.approvalsRespCh = approvalsRespCh
		b.botMessagesChannel = botMessagesChannel

		return true
	}
	log.Info("bot.slack.Configure(): Slack approval bot is not configured")
	return false
}

// Start - start bot
func (b *Bot) Start(ctx context.Context) error {
	// setting root context
	b.ctx = ctx

	users, err := b.slackClient.GetUsers()
	if err != nil {
		return err
	}

	b.users = map[string]string{}

	for _, user := range users {
		switch user.Name {
		case b.name:
			if user.IsBot {
				b.id = user.ID
			}
		default:
			continue
		}
	}
	if b.id == "" {
		return errors.New("could not find bot in the list of names, check if the bot is called \"" + b.name + "\" ")
	}

	b.msgPrefix = strings.ToLower("<@" + b.id + ">")

	go b.startInternal()

	return nil
}

func (b *Bot) startInternal() error {
	b.slackRTM = b.slackClient.NewRTM()

	go b.slackRTM.ManageConnection()
	for {
		select {
		case <-b.ctx.Done():
			return nil

		case msg := <-b.slackRTM.IncomingEvents:
			switch ev := msg.Data.(type) {
			case *slack.HelloEvent:
				// Ignore hello

			case *slack.ConnectedEvent:
				// fmt.Println("Infos:", ev.Info)
				// fmt.Println("Connection counter:", ev.ConnectionCount)
				// Replace #general with your Channel ID
				// b.slackRTM.SendMessage(b.slackRTM.NewOutgoingMessage("Hello world", "#general"))

			case *slack.MessageEvent:
				b.handleMessage(ev)
			case *slack.PresenceChangeEvent:
				// fmt.Printf("Presence Change: %v\n", ev)

			// case *slack.LatencyReport:
			// 	fmt.Printf("Current latency: %v\n", ev.Value)

			case *slack.RTMError:
				fmt.Printf("Error: %s\n", ev.Error())

			case *slack.InvalidAuthEvent:
				fmt.Printf("Invalid credentials")
				return fmt.Errorf("invalid credentials")

			default:

				// Ignore other events..
				// fmt.Printf("Unexpected: %v\n", msg.Data)
			}
		}
	}
}

func (b *Bot) postMessage(title, message, color string, fields []slack.AttachmentField) error {
	params := slack.NewPostMessageParameters()
	params.Username = b.name

	attachements := []slack.Attachment{
		slack.Attachment{
			Fallback: message,
			Color:    color,
			Fields:   fields,
			Footer:   fmt.Sprintf("https://keel.sh %s", version.GetKeelVersion().Version),
			Ts:       json.Number(strconv.Itoa(int(time.Now().Unix()))),
		},
	}

	var mgsOpts []slack.MsgOption

	mgsOpts = append(mgsOpts, slack.MsgOptionPostMessageParameters(params))
	mgsOpts = append(mgsOpts, slack.MsgOptionAttachments(attachements...))

	_, _, err := b.slackHTTPClient.PostMessage(b.approvalsChannel, mgsOpts...)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("bot.postMessage: failed to send message")
	}
	return err
}

// checking if message was received in approvals channel
func (b *Bot) isApprovalsChannel(event *slack.MessageEvent) bool {

	channel, err := b.slackClient.GetChannelInfo(event.Channel)
	if err != nil {
		log.WithError(err).Errorf("channel with ID %s could not be retrieved", event.Channel)
		return false
	}

	log.Debugf("checking if approvals channel: %s==%s", channel.Name, b.approvalsChannel)
	if channel.Name == b.approvalsChannel {
		return true
	}

	log.Debugf("message was received not on approvals channel (%s)", channel.Name)

	return false
}

func (b *Bot) handleMessage(event *slack.MessageEvent) {
	if event.BotID != "" || event.User == "" || event.SubType == "bot_message" {
		log.WithFields(log.Fields{
			"event_bot_ID":  event.BotID,
			"event_user":    event.User,
			"msg":           event.Text,
			"event_subtype": event.SubType,
		}).Debug("handleMessage: ignoring message")
		return
	}

	eventText := strings.Trim(strings.ToLower(event.Text), " \n\r")

	if !b.isBotMessage(event, eventText) {
		return
	}

	eventText = b.trimBot(eventText)

	approval, ok := bot.IsApproval(event.User, eventText)
	// only accepting approvals from approvals channel
	if ok && b.isApprovalsChannel(event) {
		b.approvalsRespCh <- approval
		return
	} else if ok {
		log.WithFields(log.Fields{
			"received_on":    event.Channel,
			"approvals_chan": b.approvalsChannel,
		}).Warnf("message was received not in approvals channel: %s", event.Channel)
		b.Respond(fmt.Sprintf("please use approvals channel '%s'", b.approvalsChannel), event.Channel)
		return
	}

	b.botMessagesChannel <- &bot.BotMessage{
		Message: eventText,
		User:    event.User,
		Channel: event.Channel,
		Name:    "slack",
	}
}

func (b *Bot) Respond(text string, channel string) {

	// if message is short, replying directly via slack RTM
	if len(text) < 3000 {
		b.slackRTM.SendMessage(b.slackRTM.NewOutgoingMessage(formatAsSnippet(text), channel))
		return
	}

	// longer messages are getting uploaded as files

	f := slack.FileUploadParameters{
		Filename: "keel response",
		Content:  text,
		Filetype: "text",
		Channels: []string{channel},
	}

	_, err := b.slackClient.UploadFile(f)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("Respond: failed to send message")
	}
}

func (b *Bot) isBotMessage(event *slack.MessageEvent, eventText string) bool {
	prefixes := []string{
		b.msgPrefix,
		b.name,
		// "kel",
	}

	for _, p := range prefixes {
		if strings.HasPrefix(eventText, p) {
			return true
		}
	}

	// Direct message channels always starts with 'D'
	return strings.HasPrefix(event.Channel, "D")
}

func (b *Bot) trimBot(msg string) string {
	msg = strings.Replace(msg, strings.ToLower(b.msgPrefix), "", 1)
	msg = strings.TrimPrefix(msg, b.name)
	msg = strings.Trim(msg, " :\n")

	return msg
}

func formatAsSnippet(response string) string {
	return "```" + response + "```"
}
<commit_msg>cleanup<commit_after>package slack

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/nlopes/slack"

	"github.com/keel-hq/keel/bot"
	"github.com/keel-hq/keel/constants"
	"github.com/keel-hq/keel/version"

	log "github.com/sirupsen/logrus"
)

// SlackImplementer - implementes slack HTTP functionality, used to
// send messages with attachments
type SlackImplementer interface {
	PostMessage(channelID string, options ...slack.MsgOption) (string, string, error)
}

// Bot - main slack bot container
type Bot struct {
	id   string // bot id
	name string // bot name

	users map[string]string

	msgPrefix string

	slackClient *slack.Client
	slackRTM    *slack.RTM

	slackHTTPClient SlackImplementer

	approvalsChannel string // slack approvals channel name

	ctx                context.Context
	botMessagesChannel chan *bot.BotMessage
	approvalsRespCh    chan *bot.ApprovalResponse
}

func init() {
	bot.RegisterBot("slack", &Bot{})
}

func (b *Bot) Configure(approvalsRespCh chan *bot.ApprovalResponse, botMessagesChannel chan *bot.BotMessage) bool {
	if os.Getenv(constants.EnvSlackToken) != "" {

		b.name = "keel"
		if bootName := os.Getenv(constants.EnvSlackBotName); bootName != "" {
			b.name = bootName
		}

		token := os.Getenv(constants.EnvSlackToken)
		client := slack.New(token)

		b.approvalsChannel = "general"
		if channel := os.Getenv(constants.EnvSlackApprovalsChannel); channel != "" {
			b.approvalsChannel = strings.TrimPrefix(channel, "#")
		}

		b.slackClient = client
		b.slackHTTPClient = client
		b.approvalsRespCh = approvalsRespCh
		b.botMessagesChannel = botMessagesChannel

		return true
	}
	log.Info("bot.slack.Configure(): Slack approval bot is not configured")
	return false
}

// Start - start bot
func (b *Bot) Start(ctx context.Context) error {
	// setting root context
	b.ctx = ctx

	users, err := b.slackClient.GetUsers()
	if err != nil {
		return err
	}

	b.users = map[string]string{}

	for _, user := range users {
		switch user.Name {
		case b.name:
			if user.IsBot {
				b.id = user.ID
			}
		default:
			continue
		}
	}
	if b.id == "" {
		return errors.New("could not find bot in the list of names, check if the bot is called \"" + b.name + "\" ")
	}

	b.msgPrefix = strings.ToLower("<@" + b.id + ">")

	go b.startInternal()

	return nil
}

func (b *Bot) startInternal() error {
	b.slackRTM = b.slackClient.NewRTM()

	go b.slackRTM.ManageConnection()
	for {
		select {
		case <-b.ctx.Done():
			return nil

		case msg := <-b.slackRTM.IncomingEvents:
			switch ev := msg.Data.(type) {
			case *slack.HelloEvent:
				// Ignore hello
			case *slack.ConnectedEvent:
				// nothing to do
			case *slack.MessageEvent:
				b.handleMessage(ev)
			case *slack.PresenceChangeEvent:
				// nothing to do
			case *slack.RTMError:
				log.Error("Error: %s", ev.Error())
			case *slack.InvalidAuthEvent:
				log.Error("Invalid credentials")
				return fmt.Errorf("invalid credentials")

			default:

				// Ignore other events..
				// fmt.Printf("Unexpected: %v\n", msg.Data)
			}
		}
	}
}

func (b *Bot) postMessage(title, message, color string, fields []slack.AttachmentField) error {
	params := slack.NewPostMessageParameters()
	params.Username = b.name

	attachements := []slack.Attachment{
		slack.Attachment{
			Fallback: message,
			Color:    color,
			Fields:   fields,
			Footer:   fmt.Sprintf("https://keel.sh %s", version.GetKeelVersion().Version),
			Ts:       json.Number(strconv.Itoa(int(time.Now().Unix()))),
		},
	}

	var mgsOpts []slack.MsgOption

	mgsOpts = append(mgsOpts, slack.MsgOptionPostMessageParameters(params))
	mgsOpts = append(mgsOpts, slack.MsgOptionAttachments(attachements...))

	_, _, err := b.slackHTTPClient.PostMessage(b.approvalsChannel, mgsOpts...)
	if err != nil {
		log.WithFields(log.Fields{
			"error":             err,
			"approvals_channel": b.approvalsChannel,
		}).Error("bot.postMessage: failed to send message")
	}
	return err
}

// checking if message was received in approvals channel
func (b *Bot) isApprovalsChannel(event *slack.MessageEvent) bool {

	channel, err := b.slackClient.GetChannelInfo(event.Channel)
	if err != nil {
		// looking for private channel
		conv, err := b.slackRTM.GetConversationInfo(event.Channel, true)
		if err != nil {
			log.Errorf("couldn't find amongst private conversations: %s", err)
		} else if conv.Name == b.approvalsChannel {
			return true
		}

		log.WithError(err).Errorf("channel with ID %s could not be retrieved", event.Channel)
		return false
	}

	log.Debugf("checking if approvals channel: %s==%s", channel.Name, b.approvalsChannel)
	if channel.Name == b.approvalsChannel {
		return true
	}

	log.Debugf("message was received not on approvals channel (%s)", channel.Name)

	return false
}

func (b *Bot) handleMessage(event *slack.MessageEvent) {
	if event.BotID != "" || event.User == "" || event.SubType == "bot_message" {
		log.WithFields(log.Fields{
			"event_bot_ID":  event.BotID,
			"event_user":    event.User,
			"msg":           event.Text,
			"event_subtype": event.SubType,
		}).Debug("handleMessage: ignoring message")
		return
	}

	eventText := strings.Trim(strings.ToLower(event.Text), " \n\r")

	if !b.isBotMessage(event, eventText) {
		return
	}

	eventText = b.trimBot(eventText)

	approval, ok := bot.IsApproval(event.User, eventText)
	// only accepting approvals from approvals channel
	if ok && b.isApprovalsChannel(event) {
		b.approvalsRespCh <- approval
		return
	} else if ok {
		log.WithFields(log.Fields{
			"received_on":    event.Channel,
			"approvals_chan": b.approvalsChannel,
		}).Warnf("message was received not in approvals channel: %s", event.Channel)
		b.Respond(fmt.Sprintf("please use approvals channel '%s'", b.approvalsChannel), event.Channel)
		return
	}

	b.botMessagesChannel <- &bot.BotMessage{
		Message: eventText,
		User:    event.User,
		Channel: event.Channel,
		Name:    "slack",
	}
}

func (b *Bot) Respond(text string, channel string) {

	// if message is short, replying directly via slack RTM
	if len(text) < 3000 {
		b.slackRTM.SendMessage(b.slackRTM.NewOutgoingMessage(formatAsSnippet(text), channel))
		return
	}

	// longer messages are getting uploaded as files

	f := slack.FileUploadParameters{
		Filename: "keel response",
		Content:  text,
		Filetype: "text",
		Channels: []string{channel},
	}

	_, err := b.slackClient.UploadFile(f)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("Respond: failed to send message")
	}
}

func (b *Bot) isBotMessage(event *slack.MessageEvent, eventText string) bool {
	prefixes := []string{
		b.msgPrefix,
		b.name,
		// "kel",
	}

	for _, p := range prefixes {
		if strings.HasPrefix(eventText, p) {
			return true
		}
	}

	// Direct message channels always starts with 'D'
	return strings.HasPrefix(event.Channel, "D")
}

func (b *Bot) trimBot(msg string) string {
	msg = strings.Replace(msg, strings.ToLower(b.msgPrefix), "", 1)
	msg = strings.TrimPrefix(msg, b.name)
	msg = strings.Trim(msg, " :\n")

	return msg
}

func formatAsSnippet(response string) string {
	return "```" + response + "```"
}
<|endoftext|>


<commit_before><commit_msg>Clip struct fields<commit_after><|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var cmdPushAura = &Command{
	Usage: "pushAura",
	Short: "force pushAura -resourcepath=<filepath>",
	Long: `
	force pushAura -resourcepath <fullFilePath>

	force pushAura -f=<fullFilePath>

	`,
}

func init() {
	cmdPushAura.Run = runPushAura
	cmdPushAura.Flag.Var(&resourcepath, "f", "fully qualified file name for entity")
	//	cmdPushAura.Flag.StringVar(&resourcepath, "f", "", "fully qualified file name for entity")
	cmdPushAura.Flag.StringVar(&metadataType, "t", "", "Type of entity or bundle to create")
	cmdPushAura.Flag.StringVar(&metadataType, "type", "", "Type of entity or bundle to create")
}

var (
//resourcepath = cmdPushAura.Flag.String("filepath", "", "fully qualified file name for entity")
//	isBundle   = cmdPushAura.Flag.Bool("isBundle", false, "Creating a bundle or not")
//createType = cmdPushAura.Flag.String("auraType", "", "Type of entity or bundle to create")
)

func runPushAura(cmd *Command, args []string) {
	absPath, _ := filepath.Abs(resourcepath[0])

	if _, err := os.Stat(absPath); os.IsNotExist(err) {
		fmt.Println(err.Error())
		ErrorAndExit("File does not exist\n" + absPath)
	}

	// Verify that the file is in an aura bundles folder
	if !InAuraBundlesFolder(absPath) {
		ErrorAndExit("File is not in an aura bundle folder (aura)")
	}

	// See if this is a directory
	info, _ := os.Stat(absPath)
	if info.IsDir() {
		// If this is a path, then it is expected be a direct child of "metatdata/aura".
		// If so, then we are going to push all the definitions in the bundle one at a time.
		filepath.Walk(absPath, func(path string, inf os.FileInfo, err error) error {
			info, err = os.Stat(filepath.Join(absPath, inf.Name()))
			if err != nil {
				fmt.Println(err.Error())
			} else {
				if info.IsDir() || inf.Name() == ".manifest" {
					fmt.Println("\nSkip")
				} else {
					pushAuraComponent(filepath.Join(absPath, inf.Name()))
				}
			}
			return nil
		})
	} else {
		pushAuraComponent(absPath)
	}
	return
}

func pushAuraComponent(fname string) {
	force, _ := ActiveForce()
	// Check for manifest file
	if _, err := os.Stat(filepath.Join(filepath.Dir(fname), ".manifest")); os.IsNotExist(err) {
		// No manifest, but is in aurabundle folder, assume creating a new bundle with this file
		// as the first artifact.
		createNewAuraBundleAndDefinition(*force, fname)
	} else {
		// Got the manifest, let's update the artifact
		fmt.Println("Updating")
		updateAuraDefinition(*force, fname)
		return
	}
}

func isValidAuraExtension(fname string) bool {
	var ext = strings.Trim(strings.ToLower(filepath.Ext(fname)), " ")
	if ext == ".app" || ext == ".cmp" || ext == ".evt" {
		return true
	} else {
		ErrorAndExit("You need to create an application (.app) or component (.cmp) or and event (.evt) as the first item in your bundle.")
	}
	return false
}

func createNewAuraBundleAndDefinition(force Force, fname string) {
	// 	Creating a new bundle. We need
	// 		the name of the bundle (parent folder of file)
	//		the type of artifact (based on naming convention)
	// 		the contents of the file
	if isValidAuraExtension(fname) {
		// Need the parent folder name to name the bundle
		var bundleName = filepath.Base(filepath.Dir(fname))
		// Create the manifext
		var manifest BundleManifest
		manifest.Name = bundleName

		_, _ = getFormatByresourcepath(fname)
		targetDirectory = SetTargetDirectory(fname)

		// Create a bundle defintion
		bundle, err, emessages := force.CreateAuraBundle(bundleName)
		if err != nil {
			if emessages[0].ErrorCode == "DUPLICATE_VALUE" {
				// Should look up the bundle and get it's id then update it.
				FetchManifest(bundleName)
				updateAuraDefinition(force, fname)
				return
			}
			ErrorAndExit(err.Error())
		} else {
			manifest.Id = bundle.Id
			component, err, emessages := createBundleEntity(manifest, force, fname)
			if err != nil {
				ErrorAndExit(err.Error(), emessages[0].ErrorCode)
			}
			createManifest(manifest, component, fname)
		}
	}
}

func SetTargetDirectory(fname string) string {
	// Need to get the parent of metadata
	return strings.Split(fname, "/metadata/aura")[0]
}

func createBundleEntity(manifest BundleManifest, force Force, fname string) (component ForceCreateRecordResult, err error, emessages []ForceError) {
	// create the bundle entity
	format, deftype := getFormatByresourcepath(fname)
	mbody, _ := readFile(fname)
	component, err, emessages = force.CreateAuraComponent(map[string]string{"AuraDefinitionBundleId": manifest.Id, "DefType": deftype, "Format": format, "Source": mbody})
	return
}

func createManifest(manifest BundleManifest, component ForceCreateRecordResult, fname string) {
	cfile := ComponentFile{}
	cfile.FileName = fname
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644)
	return
}

func updateManifest(manifest BundleManifest, component ForceCreateRecordResult, fname string) {
	cfile := ComponentFile{}
	cfile.FileName = fname
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644)
	return
}

func GetManifest(fname string) (manifest BundleManifest, err error) {
	manifestname := filepath.Join(filepath.Dir(fname), ".manifest")

	if _, err = os.Stat(manifestname); os.IsNotExist(err) {
		return
	}

	mbody, _ := readFile(filepath.Join(filepath.Dir(fname), ".manifest"))
	json.Unmarshal([]byte(mbody), &manifest)
	return
}

func updateAuraDefinition(force Force, fname string) {

	//Get the manifest
	manifest, err := GetManifest(fname)

	for i := range manifest.Files {
		component := manifest.Files[i]
		if filepath.Base(component.FileName) == filepath.Base(fname) {
			//Here is where we make the call to send the update
			mbody, _ := readFile(fname)
			err := force.UpdateAuraComponent(map[string]string{"source": mbody}, component.ComponentId)
			if err != nil {
				ErrorAndExit(err.Error())
			}
			fmt.Printf("Aura definition updated: %s\n", filepath.Base(fname))
			return
		}
	}
	component, err, emessages := createBundleEntity(manifest, force, fname)
	if err != nil {
		ErrorAndExit(err.Error(), emessages[0].ErrorCode)
	}
	updateManifest(manifest, component, fname)
	fmt.Println("New component in the bundle")
}

func getFormatByresourcepath(resourcepath string) (format string, defType string) {
	var fname = strings.ToLower(resourcepath)
	if strings.Contains(fname, "application.app") {
		format = "XML"
		defType = "APPLICATION"
	} else if strings.Contains(fname, "component.cmp") {
		format = "XML"
		defType = "COMPONENT"
	} else if strings.Contains(fname, "event.evt") {
		format = "XML"
		defType = "EVENT"
	} else if strings.Contains(fname, "controller.js") {
		format = "JS"
		defType = "CONTROLLER"
	} else if strings.Contains(fname, "model.js") {
		format = "JS"
		defType = "MODEL"
	} else if strings.Contains(fname, "helper.js") {
		format = "JS"
		defType = "HELPER"
	} else if strings.Contains(fname, "renderer.js") {
		format = "JS"
		defType = "RENDERER"
	} else if strings.Contains(fname, "style.css") {
		format = "CSS"
		defType = "STYLE"
	} else {
		if filepath.Ext(fname) == ".app" {
			format = "XML"
			defType = "APPLICATION"
		} else if filepath.Ext(fname) == ".cmp" {
			format = "XML"
			defType = "COMPONENT"
		} else if filepath.Ext(fname) == ".evt" {
			format = "XML"
			defType = "EVENT"
		} else if filepath.Ext(fname) == ".css" {
			format = "CSS"
			defType = "STYLE"
		} else if filepath.Ext(fname) == ".auradoc" {
			format = "XML"
			defType = "DOCUMENTATION"
		} else {
			ErrorAndExit("Could not determine aura definition type.", fname)
		}
	}
	return
}

func getDefinitionFormat(deftype string) (result string) {
	switch strings.ToUpper(deftype) {
	case "APPLICATION", "COMPONENT", "EVENT", "DOCUMENTATION":
		result = "XML"
	case "CONTROLLER", "MODEL", "HELPER", "RENDERER":
		result = "JS"
	case "STYLE":
		result = "CSS"
	}
	return
}

func InAuraBundlesFolder(fname string) bool {
	info, _ := os.Stat(fname)
	if info.IsDir() {
		return strings.HasSuffix(filepath.Dir(fname), "metadata/aura")
	} else {
		return strings.HasSuffix(filepath.Dir(filepath.Dir(fname)), "metadata/aura")
	}
}

func readFile(resourcepath string) (body string, err error) {
	data, err := ioutil.ReadFile(resourcepath)
	if err != nil {
		return
	}
	body = string(data)
	return
}
<commit_msg>Use filepath.FromSlash to path string.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var cmdPushAura = &Command{
	Usage: "pushAura",
	Short: "force pushAura -resourcepath=<filepath>",
	Long: `
	force pushAura -resourcepath <fullFilePath>

	force pushAura -f=<fullFilePath>

	`,
}

func init() {
	cmdPushAura.Run = runPushAura
	cmdPushAura.Flag.Var(&resourcepath, "f", "fully qualified file name for entity")
	//	cmdPushAura.Flag.StringVar(&resourcepath, "f", "", "fully qualified file name for entity")
	cmdPushAura.Flag.StringVar(&metadataType, "t", "", "Type of entity or bundle to create")
	cmdPushAura.Flag.StringVar(&metadataType, "type", "", "Type of entity or bundle to create")
}

var (
//resourcepath = cmdPushAura.Flag.String("filepath", "", "fully qualified file name for entity")
//	isBundle   = cmdPushAura.Flag.Bool("isBundle", false, "Creating a bundle or not")
//createType = cmdPushAura.Flag.String("auraType", "", "Type of entity or bundle to create")
)

func runPushAura(cmd *Command, args []string) {
	absPath, _ := filepath.Abs(resourcepath[0])

	if _, err := os.Stat(absPath); os.IsNotExist(err) {
		fmt.Println(err.Error())
		ErrorAndExit("File does not exist\n" + absPath)
	}

	// Verify that the file is in an aura bundles folder
	if !InAuraBundlesFolder(absPath) {
		ErrorAndExit("File is not in an aura bundle folder (aura)")
	}

	// See if this is a directory
	info, _ := os.Stat(absPath)
	if info.IsDir() {
		// If this is a path, then it is expected be a direct child of "metatdata/aura".
		// If so, then we are going to push all the definitions in the bundle one at a time.
		filepath.Walk(absPath, func(path string, inf os.FileInfo, err error) error {
			info, err = os.Stat(filepath.Join(absPath, inf.Name()))
			if err != nil {
				fmt.Println(err.Error())
			} else {
				if info.IsDir() || inf.Name() == ".manifest" {
					fmt.Println("\nSkip")
				} else {
					pushAuraComponent(filepath.Join(absPath, inf.Name()))
				}
			}
			return nil
		})
	} else {
		pushAuraComponent(absPath)
	}
	return
}

func pushAuraComponent(fname string) {
	force, _ := ActiveForce()
	// Check for manifest file
	if _, err := os.Stat(filepath.Join(filepath.Dir(fname), ".manifest")); os.IsNotExist(err) {
		// No manifest, but is in aurabundle folder, assume creating a new bundle with this file
		// as the first artifact.
		createNewAuraBundleAndDefinition(*force, fname)
	} else {
		// Got the manifest, let's update the artifact
		fmt.Println("Updating")
		updateAuraDefinition(*force, fname)
		return
	}
}

func isValidAuraExtension(fname string) bool {
	var ext = strings.Trim(strings.ToLower(filepath.Ext(fname)), " ")
	if ext == ".app" || ext == ".cmp" || ext == ".evt" {
		return true
	} else {
		ErrorAndExit("You need to create an application (.app) or component (.cmp) or and event (.evt) as the first item in your bundle.")
	}
	return false
}

func createNewAuraBundleAndDefinition(force Force, fname string) {
	// 	Creating a new bundle. We need
	// 		the name of the bundle (parent folder of file)
	//		the type of artifact (based on naming convention)
	// 		the contents of the file
	if isValidAuraExtension(fname) {
		// Need the parent folder name to name the bundle
		var bundleName = filepath.Base(filepath.Dir(fname))
		// Create the manifext
		var manifest BundleManifest
		manifest.Name = bundleName

		_, _ = getFormatByresourcepath(fname)
		targetDirectory = SetTargetDirectory(fname)

		// Create a bundle defintion
		bundle, err, emessages := force.CreateAuraBundle(bundleName)
		if err != nil {
			if emessages[0].ErrorCode == "DUPLICATE_VALUE" {
				// Should look up the bundle and get it's id then update it.
				FetchManifest(bundleName)
				updateAuraDefinition(force, fname)
				return
			}
			ErrorAndExit(err.Error())
		} else {
			manifest.Id = bundle.Id
			component, err, emessages := createBundleEntity(manifest, force, fname)
			if err != nil {
				ErrorAndExit(err.Error(), emessages[0].ErrorCode)
			}
			createManifest(manifest, component, fname)
		}
	}
}

func SetTargetDirectory(fname string) string {
	// Need to get the parent of metadata
	return strings.Split(fname, "/metadata/aura")[0]
}

func createBundleEntity(manifest BundleManifest, force Force, fname string) (component ForceCreateRecordResult, err error, emessages []ForceError) {
	// create the bundle entity
	format, deftype := getFormatByresourcepath(fname)
	mbody, _ := readFile(fname)
	component, err, emessages = force.CreateAuraComponent(map[string]string{"AuraDefinitionBundleId": manifest.Id, "DefType": deftype, "Format": format, "Source": mbody})
	return
}

func createManifest(manifest BundleManifest, component ForceCreateRecordResult, fname string) {
	cfile := ComponentFile{}
	cfile.FileName = fname
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644)
	return
}

func updateManifest(manifest BundleManifest, component ForceCreateRecordResult, fname string) {
	cfile := ComponentFile{}
	cfile.FileName = fname
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644)
	return
}

func GetManifest(fname string) (manifest BundleManifest, err error) {
	manifestname := filepath.Join(filepath.Dir(fname), ".manifest")

	if _, err = os.Stat(manifestname); os.IsNotExist(err) {
		return
	}

	mbody, _ := readFile(filepath.Join(filepath.Dir(fname), ".manifest"))
	json.Unmarshal([]byte(mbody), &manifest)
	return
}

func updateAuraDefinition(force Force, fname string) {

	//Get the manifest
	manifest, err := GetManifest(fname)

	for i := range manifest.Files {
		component := manifest.Files[i]
		if filepath.Base(component.FileName) == filepath.Base(fname) {
			//Here is where we make the call to send the update
			mbody, _ := readFile(fname)
			err := force.UpdateAuraComponent(map[string]string{"source": mbody}, component.ComponentId)
			if err != nil {
				ErrorAndExit(err.Error())
			}
			fmt.Printf("Aura definition updated: %s\n", filepath.Base(fname))
			return
		}
	}
	component, err, emessages := createBundleEntity(manifest, force, fname)
	if err != nil {
		ErrorAndExit(err.Error(), emessages[0].ErrorCode)
	}
	updateManifest(manifest, component, fname)
	fmt.Println("New component in the bundle")
}

func getFormatByresourcepath(resourcepath string) (format string, defType string) {
	var fname = strings.ToLower(resourcepath)
	if strings.Contains(fname, "application.app") {
		format = "XML"
		defType = "APPLICATION"
	} else if strings.Contains(fname, "component.cmp") {
		format = "XML"
		defType = "COMPONENT"
	} else if strings.Contains(fname, "event.evt") {
		format = "XML"
		defType = "EVENT"
	} else if strings.Contains(fname, "controller.js") {
		format = "JS"
		defType = "CONTROLLER"
	} else if strings.Contains(fname, "model.js") {
		format = "JS"
		defType = "MODEL"
	} else if strings.Contains(fname, "helper.js") {
		format = "JS"
		defType = "HELPER"
	} else if strings.Contains(fname, "renderer.js") {
		format = "JS"
		defType = "RENDERER"
	} else if strings.Contains(fname, "style.css") {
		format = "CSS"
		defType = "STYLE"
	} else {
		if filepath.Ext(fname) == ".app" {
			format = "XML"
			defType = "APPLICATION"
		} else if filepath.Ext(fname) == ".cmp" {
			format = "XML"
			defType = "COMPONENT"
		} else if filepath.Ext(fname) == ".evt" {
			format = "XML"
			defType = "EVENT"
		} else if filepath.Ext(fname) == ".css" {
			format = "CSS"
			defType = "STYLE"
		} else if filepath.Ext(fname) == ".auradoc" {
			format = "XML"
			defType = "DOCUMENTATION"
		} else {
			ErrorAndExit("Could not determine aura definition type.", fname)
		}
	}
	return
}

func getDefinitionFormat(deftype string) (result string) {
	switch strings.ToUpper(deftype) {
	case "APPLICATION", "COMPONENT", "EVENT", "DOCUMENTATION":
		result = "XML"
	case "CONTROLLER", "MODEL", "HELPER", "RENDERER":
		result = "JS"
	case "STYLE":
		result = "CSS"
	}
	return
}

func InAuraBundlesFolder(fname string) bool {
	info, _ := os.Stat(fname)
	if info.IsDir() {
		return strings.HasSuffix(filepath.Dir(fname), filepath.FromSlash("metadata/aura"))
	} else {
		return strings.HasSuffix(filepath.Dir(filepath.Dir(fname)), filepath.FromSlash("metadata/aura"))
	}
}

func readFile(resourcepath string) (body string, err error) {
	data, err := ioutil.ReadFile(resourcepath)
	if err != nil {
		return
	}
	body = string(data)
	return
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package raw

import (
	"errors"

	"github.com/uber/tchannel-go"
	"golang.org/x/net/context"
)

// ErrAppError is returned if the application sets an error response.
var ErrAppError = errors.New("application error")

// WriteArgs writes the given arguments to the call, and returns the response args.
func WriteArgs(call *tchannel.OutboundCall, arg2, arg3 []byte) ([]byte, []byte, *tchannel.OutboundCallResponse, error) {
	if err := tchannel.NewArgWriter(call.Arg2Writer()).Write(arg2); err != nil {
		return nil, nil, nil, err
	}

	if err := tchannel.NewArgWriter(call.Arg3Writer()).Write(arg3); err != nil {
		return nil, nil, nil, err
	}

	resp := call.Response()
	var respArg2 []byte
	if err := tchannel.NewArgReader(resp.Arg2Reader()).Read(&respArg2); err != nil {
		return nil, nil, nil, err
	}

	var respArg3 []byte
	if err := tchannel.NewArgReader(resp.Arg3Reader()).Read(&respArg3); err != nil {
		return nil, nil, nil, err
	}

	return respArg2, respArg3, resp, nil
}

// Call makes a call to the given hostPort with the given arguments and returns the response args.
func Call(ctx context.Context, ch *tchannel.Channel, hostPort string, serviceName, operation string,
	arg2, arg3 []byte) ([]byte, []byte, *tchannel.OutboundCallResponse, error) {

	call, err := ch.BeginCall(ctx, hostPort, serviceName, operation, nil)
	if err != nil {
		return nil, nil, nil, err
	}

	return WriteArgs(call, arg2, arg3)
}

// CallSC makes a call using the given subcahnnel
func CallSC(ctx context.Context, sc *tchannel.SubChannel, operation string, arg2, arg3 []byte) (
	[]byte, []byte, *tchannel.OutboundCallResponse, error) {

	call, err := sc.BeginCall(ctx, operation, nil)
	if err != nil {
		return nil, nil, nil, err
	}

	return WriteArgs(call, arg2, arg3)
}

// CArgs are the call arguments passed to CallV2.
type CArgs struct {
	Operation   string
	Arg2        []byte
	Arg3        []byte
	CallOptions *tchannel.CallOptions
}

// CRes is the result of making a call.
type CRes struct {
	Arg2     []byte
	Arg3     []byte
	AppError bool
}

// CallV2 makes a call and does not attempt any retries.
func CallV2(ctx context.Context, sc *tchannel.SubChannel, cArgs CArgs) (*CRes, error) {
	call, err := sc.BeginCall(ctx, cArgs.Operation, cArgs.CallOptions)
	if err != nil {
		return nil, err
	}

	arg2, arg3, res, err := WriteArgs(call, cArgs.Arg2, cArgs.Arg3)
	if err != nil {
		return nil, err
	}

	return &CRes{
		Arg2:     arg2,
		Arg3:     arg3,
		AppError: res.ApplicationError(),
	}, nil
}
<commit_msg>Add ReadArgsV2 to read from either a call or response<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package raw

import (
	"errors"
	"io"

	"github.com/uber/tchannel-go"
	"golang.org/x/net/context"
)

// ErrAppError is returned if the application sets an error response.
var ErrAppError = errors.New("application error")

// Readable is the interface for something that can be read.
type Readable interface {
	Arg2Reader() (io.ReadCloser, error)
	Arg3Reader() (io.ReadCloser, error)
}

// ReadArgsV2 reads arg2 and arg3 from a reader.
func ReadArgsV2(r Readable) ([]byte, []byte, error) {
	var arg2, arg3 []byte

	if err := tchannel.NewArgReader(r.Arg2Reader()).Read(&arg2); err != nil {
		return nil, nil, err
	}

	if err := tchannel.NewArgReader(r.Arg3Reader()).Read(&arg3); err != nil {
		return nil, nil, err
	}

	return arg2, arg3, nil
}

// WriteArgs writes the given arguments to the call, and returns the response args.
func WriteArgs(call *tchannel.OutboundCall, arg2, arg3 []byte) ([]byte, []byte, *tchannel.OutboundCallResponse, error) {
	if err := tchannel.NewArgWriter(call.Arg2Writer()).Write(arg2); err != nil {
		return nil, nil, nil, err
	}

	if err := tchannel.NewArgWriter(call.Arg3Writer()).Write(arg3); err != nil {
		return nil, nil, nil, err
	}

	resp := call.Response()
	var respArg2 []byte
	if err := tchannel.NewArgReader(resp.Arg2Reader()).Read(&respArg2); err != nil {
		return nil, nil, nil, err
	}

	var respArg3 []byte
	if err := tchannel.NewArgReader(resp.Arg3Reader()).Read(&respArg3); err != nil {
		return nil, nil, nil, err
	}

	return respArg2, respArg3, resp, nil
}

// Call makes a call to the given hostPort with the given arguments and returns the response args.
func Call(ctx context.Context, ch *tchannel.Channel, hostPort string, serviceName, operation string,
	arg2, arg3 []byte) ([]byte, []byte, *tchannel.OutboundCallResponse, error) {

	call, err := ch.BeginCall(ctx, hostPort, serviceName, operation, nil)
	if err != nil {
		return nil, nil, nil, err
	}

	return WriteArgs(call, arg2, arg3)
}

// CallSC makes a call using the given subcahnnel
func CallSC(ctx context.Context, sc *tchannel.SubChannel, operation string, arg2, arg3 []byte) (
	[]byte, []byte, *tchannel.OutboundCallResponse, error) {

	call, err := sc.BeginCall(ctx, operation, nil)
	if err != nil {
		return nil, nil, nil, err
	}

	return WriteArgs(call, arg2, arg3)
}

// CArgs are the call arguments passed to CallV2.
type CArgs struct {
	Operation   string
	Arg2        []byte
	Arg3        []byte
	CallOptions *tchannel.CallOptions
}

// CRes is the result of making a call.
type CRes struct {
	Arg2     []byte
	Arg3     []byte
	AppError bool
}

// CallV2 makes a call and does not attempt any retries.
func CallV2(ctx context.Context, sc *tchannel.SubChannel, cArgs CArgs) (*CRes, error) {
	call, err := sc.BeginCall(ctx, cArgs.Operation, cArgs.CallOptions)
	if err != nil {
		return nil, err
	}

	arg2, arg3, res, err := WriteArgs(call, cArgs.Arg2, cArgs.Arg3)
	if err != nil {
		return nil, err
	}

	return &CRes{
		Arg2:     arg2,
		Arg3:     arg3,
		AppError: res.ApplicationError(),
	}, nil
}
<|endoftext|>


<commit_before>package bot

import (
	"bytes"
	"testing"
)

const path = "../db/test"

func TestStore(t *testing.T) {
	store, err := NewStore(path)

	if err != nil {
		t.Error(err)
	}

	data := map[string][]byte{
		"one":   []byte("111"),
		"two":   []byte("222"),
		"three": []byte("333"),
		"four":  []byte("444"),
	}

	for k, v := range data {
		err = store.Put(k, v)
		if err != nil {
			t.Error(err)
		}

		exists, err := store.Exists(k)
		if err != nil {
			t.Error(err)
		}
		if !exists {
			t.Fail()
		}

		pair, err := store.Get(k)
		if err != nil {
			t.Error(err)
		}
		if bytes.Compare(pair.Value, v) != 0 {
			t.Error(pair.Value, "!=", v)
		}
	}
	exists, err := store.Exists("not exists")
	if err != nil {
		t.Error(err)
	}
	if exists {
		t.Fail()
	}

	pairs, err := store.List()
	if err != nil {
		t.Error(err)
	}
	for _, p := range pairs {
		if bytes.Compare(p.Value, data[p.Key]) != 0 {
			t.Fail()
		}
	}

	for k, _ := range data {
		err = store.Delete(k)
		if err != nil {
			t.Error(err)
		}

		exists, err := store.Exists(k)
		if err != nil {
			t.Error(err)
		}
		if exists {
			t.Error()
		}

		pair, err := store.Get(k)
		if err != ErrKeyNotFound {
			t.Error(err)
		}
		if pair != nil {
			t.Fail()
		}
	}
	store.Close()
}
<commit_msg>fix test, quit if failed to open store<commit_after>package bot

import (
	"bytes"
	"testing"
)

const path = "../data/test"

func TestStore(t *testing.T) {
	store, err := NewStore(path)

	if err != nil {
		t.Fatal(err)
	}

	data := map[string][]byte{
		"one":   []byte("111"),
		"two":   []byte("222"),
		"three": []byte("333"),
		"four":  []byte("444"),
	}

	for k, v := range data {
		err = store.Put(k, v)
		if err != nil {
			t.Error(err)
		}

		exists, err := store.Exists(k)
		if err != nil {
			t.Error(err)
		}
		if !exists {
			t.Fail()
		}

		pair, err := store.Get(k)
		if err != nil {
			t.Error(err)
		}
		if bytes.Compare(pair.Value, v) != 0 {
			t.Error(pair.Value, "!=", v)
		}
	}
	exists, err := store.Exists("not exists")
	if err != nil {
		t.Error(err)
	}
	if exists {
		t.Fail()
	}

	pairs, err := store.List()
	if err != nil {
		t.Error(err)
	}
	for _, p := range pairs {
		if bytes.Compare(p.Value, data[p.Key]) != 0 {
			t.Fail()
		}
	}

	for k, _ := range data {
		err = store.Delete(k)
		if err != nil {
			t.Error(err)
		}

		exists, err := store.Exists(k)
		if err != nil {
			t.Error(err)
		}
		if exists {
			t.Error()
		}

		pair, err := store.Get(k)
		if err != ErrKeyNotFound {
			t.Error(err)
		}
		if pair != nil {
			t.Fail()
		}
	}
	store.Close()
}
<|endoftext|>


<commit_before>package quadtree

import (
	"math"
)

var (
	Capacity = 8
	MaxDepth = 6
)

type AABB struct {
	center *Point
	half   *Point
}

type Point struct {
	x    float64
	y    float64
	data interface{}
}

type QuadTree struct {
	boundary *AABB
	depth    int
	points   []*Point
	parent   *QuadTree
	nodes    [4]*QuadTree
}

type filter func(*Point) bool

func deg2Rad(deg float64) float64 {
	return deg * (math.Pi / 180)
}

func rad2Deg(rad float64) float64 {
	return (180.0 * rad) / math.Pi
}

func boundaryPoint(x *Point, m float64) *Point {
	x2 := deg2Rad(x.x)
	y2 := deg2Rad(x.y)

	// Radius of Earth at given latitude
	radius := earthRadius(x2)
	// Radius of the parallel at given latitude
	pradius := radius * math.Cos(x2)

	xMax := x2 + m/radius
	yMax := y2 + m/pradius

	return &Point{rad2Deg(xMax), rad2Deg(yMax), nil}
}

// Earth radius at a given latitude, according to the WGS-84 ellipsoid [m]
func earthRadius(x float64) float64 {
	masm := 6378137.0 // Major semiaxis [m]
	mism := 6356752.3 // Minor semiaxis [m]

	an := masm * masm * math.Cos(x)
	bn := mism * mism * math.Sin(x)
	ad := masm * math.Cos(x)
	bd := mism * math.Sin(x)
	return math.Sqrt((an*an + bn*bn) / (ad*ad + bd*bd))
}

// New creates a new *QuadTree. It requires a boundary defining the center
// and half points, depth at which the QuadTree resides and parent node.
// Depth of 0 and parent as nil implies the root node.
func New(boundary *AABB, depth int, parent *QuadTree) *QuadTree {
	return &QuadTree{
		boundary: boundary,
		depth:    depth,
		parent:   parent,
	}
}

// NewAABB creates an axis aligned bounding box. It takes the center and half
// point.
func NewAABB(center, half *Point) *AABB {
	return &AABB{center, half}
}

// NewPoint generates a new *Point struct.
func NewPoint(x, y float64, data interface{}) *Point {
	return &Point{x, y, data}
}

// ContainsPoint checks whether the point provided resides within the axis
// aligned bounding box.
func (a *AABB) ContainsPoint(p *Point) bool {
	if p.x < a.center.x-a.half.x {
		return false
	}
	if p.y < a.center.y-a.half.y {
		return false
	}
	if p.x > a.center.x+a.half.x {
		return false
	}
	if p.y > a.center.y+a.half.y {
		return false
	}

	return true
}

// Intersect checks whether two axis aligned bounding boxes overlap.
func (a *AABB) Intersect(b *AABB) bool {
	if b.center.x+b.half.x < a.center.x-a.half.x {
		return false
	}
	if b.center.y+b.half.y < a.center.y-a.half.y {
		return false
	}
	if b.center.x-b.half.x > a.center.x+a.half.x {
		return false
	}
	if b.center.y-b.half.y > a.center.y+a.half.y {
		return false
	}

	return true
}

// Coordinates return the x and y coordinates of a point.
func (p *Point) Coordinates() (float64, float64) {
	return p.x, p.y
}

// Data returns the data stored within a point.
func (p *Point) Data() interface{} {
	return p.data
}

// HalfPoint is a convenience function for generating the half point
// required to created an axis aligned bounding box. It takes an
// argument of metres as float64.
func (p *Point) HalfPoint(m float64) *Point {
	p2 := boundaryPoint(p, m)
	return &Point{p2.x - p.x, p2.y - p.y, nil}
}

func (qt *QuadTree) divide() {
	if qt.nodes[0] != nil {
		return
	}

	bb := &AABB{
		&Point{qt.boundary.center.x - qt.boundary.half.x/2, qt.boundary.center.y + qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[0] = New(bb, qt.depth, qt)

	bb = &AABB{
		&Point{qt.boundary.center.x + qt.boundary.half.x/2, qt.boundary.center.y + qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[1] = New(bb, qt.depth, qt)

	bb = &AABB{
		&Point{qt.boundary.center.x - qt.boundary.half.x/2, qt.boundary.center.y - qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[2] = New(bb, qt.depth, qt)

	bb = &AABB{
		&Point{qt.boundary.center.x + qt.boundary.half.x/2, qt.boundary.center.y - qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[3] = New(bb, qt.depth, qt)

	for _, p := range qt.points {
		for _, node := range qt.nodes {
			if node.Insert(p) {
				break
			}
		}
	}

	qt.points = nil
}

func (qt *QuadTree) knearest(a *AABB, i int, v map[*QuadTree]bool, fn filter) []*Point {
	var results []*Point

	if !qt.boundary.Intersect(a) {
		return results
	}

	if _, ok := v[qt]; ok {
		return results
	} else {
		v[qt] = true
	}

	for _, p := range qt.points {
		if a.ContainsPoint(p) {
			results = append(results, p)
		}

		if len(results) >= i {
			return results[:i]
		}
	}

	if qt.nodes[0] != nil {
		for _, node := range qt.nodes {
			results = append(results, node.knearest(a, i, v, fn)...)

			if len(results) >= i {
				return results[:i]
			}
		}
		if len(results) >= i {
			results = results[:i]
		}
	}

	if qt.parent == nil {
		return results
	}

	return qt.parent.knearest(a, i, v, fn)
}

// Insert will attempt to insert the point into the QuadTree. It will
// recursively search until it finds the leaf node. If the leaf node
// is at capacity then it will try split the node. If the tree is at
// max depth then point will be stored in the leaf.
func (qt *QuadTree) Insert(p *Point) bool {
	if !qt.boundary.ContainsPoint(p) {
		return false
	}

	if qt.nodes[0] == nil {
		if len(qt.points) < Capacity {
			qt.points = append(qt.points, p)
			return true
		}

		if qt.depth < MaxDepth {
			qt.divide()
		} else {
			qt.points = append(qt.points, p)
			return true
		}
	}

	for _, node := range qt.nodes {
		if node.Insert(p) {
			return true
		}
	}

	return false
}

// KNearest returns the k nearest points within the QuadTree that fall within
// the bounds of the axis aligned bounding box. A filter function can be used
// which is evaluated against each point. The search begins at the leaf and
// recurses towards the parent until k nearest have been found or root node is
// hit.
func (qt *QuadTree) KNearest(a *AABB, i int, fn filter) []*Point {
	var results []*Point

	if !qt.boundary.Intersect(a) {
		return results
	}

	// hit the leaf
	if qt.nodes[0] == nil {
		v := make(map[*QuadTree]bool)
		results = append(results, qt.knearest(a, i, v, fn)...)

		if len(results) >= i {
			results = results[:i]
		}

		return results
	}

	for _, node := range qt.nodes {
		results = append(results, node.KNearest(a, i, fn)...)

		if len(results) >= i {
			return results[:i]
		}
	}

	if len(results) >= i {
		results = results[:i]
	}

	return results
}

// Remove attemps to remove a point from the QuadTree. It will recurse until
// the leaf node is found and then try to remove the point.
func (qt *QuadTree) Remove(p *Point) bool {
	if !qt.boundary.ContainsPoint(p) {
		return false
	}

	if qt.nodes[0] == nil {
		for i, ep := range qt.points {
			if ep != p {
				continue
			}

			// remove point
			if last := len(qt.points) - 1; i == last {
				qt.points = qt.points[:last]
			} else {
				qt.points[i] = qt.points[last]
				qt.points = qt.points[:last]
			}
			return true
		}

		return false
	}

	for _, node := range qt.nodes {
		if node.Remove(p) {
			return true
		}
	}

	return false
}

// RInsert is used in conjuction with Update to try reveser insert a point.
func (qt *QuadTree) RInsert(p *Point) bool {
	// Try insert down the tree
	if qt.Insert(p) {
		return true
	}

	// hit root node
	if qt.parent == nil {
		return false
	}

	// try rinsert parent
	return qt.parent.RInsert(p)
}

// Search will return all the points within the given axis aligned bounding
// box. It recursively searches downward through the tree.
func (qt *QuadTree) Search(a *AABB) []*Point {
	var results []*Point

	if !qt.boundary.Intersect(a) {
		return results
	}

	for _, p := range qt.points {
		if a.ContainsPoint(p) {
			results = append(results, p)
		}
	}

	if qt.nodes[0] == nil {
		return results
	}

	for _, node := range qt.nodes {
		results = append(results, node.Search(a)...)
	}

	return results
}

// Update will update the location of a point within the tree. It is
// optimised to attempt reinsertion within the same node and recurse
// back up the tree until it finds a suitable node.
func (qt *QuadTree) Update(p *Point, np *Point) bool {
	if !qt.boundary.ContainsPoint(p) {
		return false
	}

	// At the leaf
	if qt.nodes[0] == nil {
		for i, ep := range qt.points {
			if ep != p {
				continue
			}

			// set new coords
			p.x = np.x
			p.y = np.y

			// now do we move?
			if qt.boundary.ContainsPoint(np) {
				return true
			}

			// remove from current node
			if last := len(qt.points) - 1; i == last {
				qt.points = qt.points[:last]
			} else {
				qt.points[i] = qt.points[last]
				qt.points = qt.points[:last]
			}

			// well shit now...reinsert
			return qt.RInsert(p)
		}
		return false
	}

	for _, node := range qt.nodes {
		if node.Update(p, np) {
			return true
		}
	}

	return false
}
<commit_msg>Fix bug where the wrong knearest list is returned (most of the time empty) when k is bigger than the actual object count on the tree<commit_after>package quadtree

import (
	"math"
)

var (
	Capacity = 8
	MaxDepth = 6
)

type AABB struct {
	center *Point
	half   *Point
}

type Point struct {
	x    float64
	y    float64
	data interface{}
}

type QuadTree struct {
	boundary *AABB
	depth    int
	points   []*Point
	parent   *QuadTree
	nodes    [4]*QuadTree
}

type filter func(*Point) bool

func deg2Rad(deg float64) float64 {
	return deg * (math.Pi / 180)
}

func rad2Deg(rad float64) float64 {
	return (180.0 * rad) / math.Pi
}

func boundaryPoint(x *Point, m float64) *Point {
	x2 := deg2Rad(x.x)
	y2 := deg2Rad(x.y)

	// Radius of Earth at given latitude
	radius := earthRadius(x2)
	// Radius of the parallel at given latitude
	pradius := radius * math.Cos(x2)

	xMax := x2 + m/radius
	yMax := y2 + m/pradius

	return &Point{rad2Deg(xMax), rad2Deg(yMax), nil}
}

// Earth radius at a given latitude, according to the WGS-84 ellipsoid [m]
func earthRadius(x float64) float64 {
	masm := 6378137.0 // Major semiaxis [m]
	mism := 6356752.3 // Minor semiaxis [m]

	an := masm * masm * math.Cos(x)
	bn := mism * mism * math.Sin(x)
	ad := masm * math.Cos(x)
	bd := mism * math.Sin(x)
	return math.Sqrt((an*an + bn*bn) / (ad*ad + bd*bd))
}

// New creates a new *QuadTree. It requires a boundary defining the center
// and half points, depth at which the QuadTree resides and parent node.
// Depth of 0 and parent as nil implies the root node.
func New(boundary *AABB, depth int, parent *QuadTree) *QuadTree {
	return &QuadTree{
		boundary: boundary,
		depth:    depth,
		parent:   parent,
	}
}

// NewAABB creates an axis aligned bounding box. It takes the center and half
// point.
func NewAABB(center, half *Point) *AABB {
	return &AABB{center, half}
}

// NewPoint generates a new *Point struct.
func NewPoint(x, y float64, data interface{}) *Point {
	return &Point{x, y, data}
}

// ContainsPoint checks whether the point provided resides within the axis
// aligned bounding box.
func (a *AABB) ContainsPoint(p *Point) bool {
	if p.x < a.center.x-a.half.x {
		return false
	}
	if p.y < a.center.y-a.half.y {
		return false
	}
	if p.x > a.center.x+a.half.x {
		return false
	}
	if p.y > a.center.y+a.half.y {
		return false
	}

	return true
}

// Intersect checks whether two axis aligned bounding boxes overlap.
func (a *AABB) Intersect(b *AABB) bool {
	if b.center.x+b.half.x < a.center.x-a.half.x {
		return false
	}
	if b.center.y+b.half.y < a.center.y-a.half.y {
		return false
	}
	if b.center.x-b.half.x > a.center.x+a.half.x {
		return false
	}
	if b.center.y-b.half.y > a.center.y+a.half.y {
		return false
	}

	return true
}

// Coordinates return the x and y coordinates of a point.
func (p *Point) Coordinates() (float64, float64) {
	return p.x, p.y
}

// Data returns the data stored within a point.
func (p *Point) Data() interface{} {
	return p.data
}

// HalfPoint is a convenience function for generating the half point
// required to created an axis aligned bounding box. It takes an
// argument of metres as float64.
func (p *Point) HalfPoint(m float64) *Point {
	p2 := boundaryPoint(p, m)
	return &Point{p2.x - p.x, p2.y - p.y, nil}
}

func (qt *QuadTree) divide() {
	if qt.nodes[0] != nil {
		return
	}

	bb := &AABB{
		&Point{qt.boundary.center.x - qt.boundary.half.x/2, qt.boundary.center.y + qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[0] = New(bb, qt.depth, qt)

	bb = &AABB{
		&Point{qt.boundary.center.x + qt.boundary.half.x/2, qt.boundary.center.y + qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[1] = New(bb, qt.depth, qt)

	bb = &AABB{
		&Point{qt.boundary.center.x - qt.boundary.half.x/2, qt.boundary.center.y - qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[2] = New(bb, qt.depth, qt)

	bb = &AABB{
		&Point{qt.boundary.center.x + qt.boundary.half.x/2, qt.boundary.center.y - qt.boundary.half.y/2, nil},
		&Point{qt.boundary.half.x / 2, qt.boundary.half.y / 2, nil},
	}

	qt.nodes[3] = New(bb, qt.depth, qt)

	for _, p := range qt.points {
		for _, node := range qt.nodes {
			if node.Insert(p) {
				break
			}
		}
	}

	qt.points = nil
}

func (qt *QuadTree) knearest(a *AABB, i int, v map[*QuadTree]bool, fn filter) []*Point {
	var results []*Point

	if !qt.boundary.Intersect(a) {
		return results
	}

	if _, ok := v[qt]; ok {
		return results
	} else {
		v[qt] = true
	}

	for _, p := range qt.points {
		if a.ContainsPoint(p) {
			results = append(results, p)
		}

		if len(results) >= i {
			return results[:i]
		}
	}

	if qt.nodes[0] != nil {
		for _, node := range qt.nodes {
			results = append(results, node.knearest(a, i, v, fn)...)

			if len(results) >= i {
				return results[:i]
			}
		}
		if len(results) >= i {
			results = results[:i]
		}
	}

	if qt.parent == nil {
		return results
	}

	results = append(results, qt.parent.knearest(a, i, v, fn)...)
	if len(results) >= i {
		results = results[:i]
	}
	return results
}

// Insert will attempt to insert the point into the QuadTree. It will
// recursively search until it finds the leaf node. If the leaf node
// is at capacity then it will try split the node. If the tree is at
// max depth then point will be stored in the leaf.
func (qt *QuadTree) Insert(p *Point) bool {
	if !qt.boundary.ContainsPoint(p) {
		return false
	}

	if qt.nodes[0] == nil {
		if len(qt.points) < Capacity {
			qt.points = append(qt.points, p)
			return true
		}

		if qt.depth < MaxDepth {
			qt.divide()
		} else {
			qt.points = append(qt.points, p)
			return true
		}
	}

	for _, node := range qt.nodes {
		if node.Insert(p) {
			return true
		}
	}

	return false
}

// KNearest returns the k nearest points within the QuadTree that fall within
// the bounds of the axis aligned bounding box. A filter function can be used
// which is evaluated against each point. The search begins at the leaf and
// recurses towards the parent until k nearest have been found or root node is
// hit.
func (qt *QuadTree) KNearest(a *AABB, i int, fn filter) []*Point {
	var results []*Point

	if !qt.boundary.Intersect(a) {
		return results
	}

	// hit the leaf
	if qt.nodes[0] == nil {
		v := make(map[*QuadTree]bool)
		results = append(results, qt.knearest(a, i, v, fn)...)

		if len(results) >= i {
			results = results[:i]
		}

		return results
	}

	for _, node := range qt.nodes {
		results = append(results, node.KNearest(a, i, fn)...)

		if len(results) >= i {
			return results[:i]
		}
	}

	if len(results) >= i {
		results = results[:i]
	}

	return results
}

// Remove attemps to remove a point from the QuadTree. It will recurse until
// the leaf node is found and then try to remove the point.
func (qt *QuadTree) Remove(p *Point) bool {
	if !qt.boundary.ContainsPoint(p) {
		return false
	}

	if qt.nodes[0] == nil {
		for i, ep := range qt.points {
			if ep != p {
				continue
			}

			// remove point
			if last := len(qt.points) - 1; i == last {
				qt.points = qt.points[:last]
			} else {
				qt.points[i] = qt.points[last]
				qt.points = qt.points[:last]
			}
			return true
		}

		return false
	}

	for _, node := range qt.nodes {
		if node.Remove(p) {
			return true
		}
	}

	return false
}

// RInsert is used in conjuction with Update to try reveser insert a point.
func (qt *QuadTree) RInsert(p *Point) bool {
	// Try insert down the tree
	if qt.Insert(p) {
		return true
	}

	// hit root node
	if qt.parent == nil {
		return false
	}

	// try rinsert parent
	return qt.parent.RInsert(p)
}

// Search will return all the points within the given axis aligned bounding
// box. It recursively searches downward through the tree.
func (qt *QuadTree) Search(a *AABB) []*Point {
	var results []*Point

	if !qt.boundary.Intersect(a) {
		return results
	}

	for _, p := range qt.points {
		if a.ContainsPoint(p) {
			results = append(results, p)
		}
	}

	if qt.nodes[0] == nil {
		return results
	}

	for _, node := range qt.nodes {
		results = append(results, node.Search(a)...)
	}

	return results
}

// Update will update the location of a point within the tree. It is
// optimised to attempt reinsertion within the same node and recurse
// back up the tree until it finds a suitable node.
func (qt *QuadTree) Update(p *Point, np *Point) bool {
	if !qt.boundary.ContainsPoint(p) {
		return false
	}

	// At the leaf
	if qt.nodes[0] == nil {
		for i, ep := range qt.points {
			if ep != p {
				continue
			}

			// set new coords
			p.x = np.x
			p.y = np.y

			// now do we move?
			if qt.boundary.ContainsPoint(np) {
				return true
			}

			// remove from current node
			if last := len(qt.points) - 1; i == last {
				qt.points = qt.points[:last]
			} else {
				qt.points[i] = qt.points[last]
				qt.points = qt.points[:last]
			}

			// well shit now...reinsert
			return qt.RInsert(p)
		}
		return false
	}

	for _, node := range qt.nodes {
		if node.Update(p, np) {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before>// +build reciever

package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/golang-mcr/machiavelli/twitter"
	"golang.org/x/oauth2"
	gcfg "gopkg.in/gcfg.v1"
)

func main() {
	var configFile string
	flag.StringVar(&configFile, "config", "", "configuration file (.gcfg)")
	flag.Parse()

	var cfg config
	if err := gcfg.ReadFileInto(&cfg, configFile); err != nil {
		fmt.Fprintf(os.Stderr, "error getting config variables: %v", err)
		return
	}

	//auth := &oauth2.Config{}
	// token := &oauth2.Token{AccessToken: cfg.twitter.accessToken}

	config := oauth1.NewConfig(cfg.twitter.consumerKey, cfg.twitter.consumerSecret)
	token := oauth1.NewToken(cfg.twitter.accessToken, cfg.twitter.accessSecret)
	// OAuth1 http.Client will automatically authorize Requests
	httpClient := config.Client(oauth1.NoContext, token)

	// OAuth2 http.Client will automatically authorize Requests
	httpClient := auth.Client(oauth2.NoContext, token)
	client := twitter.NewClient(httpClient)
	_, stop := client.Listen("test")
	stop()
	fmt.Println("machiavelli")
}
<commit_msg>Fix build error due to typo<commit_after>// +build receiver

package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/golang-mcr/machiavelli/twitter"
	"golang.org/x/oauth2"
	gcfg "gopkg.in/gcfg.v1"
)

func main() {
	var configFile string
	flag.StringVar(&configFile, "config", "", "configuration file (.gcfg)")
	flag.Parse()

	var cfg config
	if err := gcfg.ReadFileInto(&cfg, configFile); err != nil {
		fmt.Fprintf(os.Stderr, "error getting config variables: %v", err)
		return
	}

	//auth := &oauth2.Config{}
	// token := &oauth2.Token{AccessToken: cfg.twitter.accessToken}

	config := oauth1.NewConfig(cfg.twitter.consumerKey, cfg.twitter.consumerSecret)
	token := oauth1.NewToken(cfg.twitter.accessToken, cfg.twitter.accessSecret)
	// OAuth1 http.Client will automatically authorize Requests
	httpClient := config.Client(oauth1.NoContext, token)

	// OAuth2 http.Client will automatically authorize Requests
	httpClient := auth.Client(oauth2.NoContext, token)
	client := twitter.NewClient(httpClient)
	_, stop := client.Listen("test")
	stop()
	fmt.Println("machiavelli")
}
<|endoftext|>


<commit_before>package negroni

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"runtime"
	"runtime/debug"
)

// Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one.
type Recovery struct {
	Logger           *log.Logger
	PrintStack       bool
	ErrorHandlerFunc func(interface{})
	StackAll         bool
	StackSize        int
}

// NewRecovery returns a new instance of Recovery
func NewRecovery() *Recovery {
	return &Recovery{
		Logger:     log.New(os.Stdout, "[negroni] ", 0),
		PrintStack: true,
		StackAll:   false,
		StackSize:  1024 * 8,
	}
}

func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	defer func() {
		if err := recover(); err != nil {
			if rw.Header().Get("Content-Type") == "" {
				rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
			}

			rw.WriteHeader(http.StatusInternalServerError)

			stack := make([]byte, rec.StackSize)
			stack = stack[:runtime.Stack(stack, rec.StackAll)]

			f := "PANIC: %s\n%s"
			rec.Logger.Printf(f, err, stack)

			if rec.PrintStack {
				fmt.Fprintf(rw, f, err, stack)
			}

			if rec.ErrorHandlerFunc != nil {
				defer func() {
					if err := recover(); err != nil {
						rec.Logger.Printf("provided ErrorHandlerFunc panic'd: %s, trace:\n%s", err, debug.Stack())
						rec.Logger.Printf("%s\n", debug.Stack())
					}
				}()
				rec.ErrorHandlerFunc(err)
			}
		}
	}()

	next(rw, r)
}
<commit_msg>fixup! Recover panics thrown by the Recovery handler ErrorHandlerFunc<commit_after>package negroni

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"runtime"
	"runtime/debug"
)

// Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one.
type Recovery struct {
	Logger           *log.Logger
	PrintStack       bool
	ErrorHandlerFunc func(interface{})
	StackAll         bool
	StackSize        int
}

// NewRecovery returns a new instance of Recovery
func NewRecovery() *Recovery {
	return &Recovery{
		Logger:     log.New(os.Stdout, "[negroni] ", 0),
		PrintStack: true,
		StackAll:   false,
		StackSize:  1024 * 8,
	}
}

func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	defer func() {
		if err := recover(); err != nil {
			if rw.Header().Get("Content-Type") == "" {
				rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
			}

			rw.WriteHeader(http.StatusInternalServerError)

			stack := make([]byte, rec.StackSize)
			stack = stack[:runtime.Stack(stack, rec.StackAll)]

			f := "PANIC: %s\n%s"
			rec.Logger.Printf(f, err, stack)

			if rec.PrintStack {
				fmt.Fprintf(rw, f, err, stack)
			}

			if rec.ErrorHandlerFunc != nil {
				func() {
					defer func() {
						if err := recover(); err != nil {
							rec.Logger.Printf("provided ErrorHandlerFunc panic'd: %s, trace:\n%s", err, debug.Stack())
							rec.Logger.Printf("%s\n", debug.Stack())
						}
					}()
					rec.ErrorHandlerFunc(err)
				}()
			}
		}
	}()

	next(rw, r)
}
<|endoftext|>