<commit_before>// This example demonstrates decoding a JPEG image and examining its pixels.
package main

import (
	"github.com/cartland/go/imagic"
	"image"
	"log"
	"os"
	// _ "image/gif"
	_ "image/jpeg"
	"image/png"
)

func main() {
	// Decode the JPEG data.
	reader, err := os.Open("testdata/Chefchaouen.jpg")
	if err != nil {
		log.Fatal(err)
	}
	defer reader.Close()
	bg, _, err := image.Decode(reader)
	if err != nil {
		log.Fatal(err)
	}

	reader, err = os.Open("testdata/borrodepth.png")
	if err != nil {
		log.Fatal(err)
	}
	defer reader.Close()
	dm, _, err := image.Decode(reader)
	if err != nil {
		log.Fatal(err)
	}

	configWallEyed := imagic.Config{60, 100, false}
	configCrossEyed := imagic.Config{100, 160, true}

	wall := imagic.Imagic(dm, bg, configWallEyed)
	writer, err := os.Create("testdata/wallOutput.png")
	png.Encode(writer, wall)

	cross := imagic.Imagic(dm, bg, configCrossEyed)
	writer, err = os.Create("testdata/crossOutput.png")
	png.Encode(writer, cross)
}
<commit_msg>Add copyright<commit_after>/*
 * Copyright 2014 Chris Cartland
 *
 * 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.
 */
// This example demonstrates decoding a JPEG image and examining its pixels.
package main

import (
	"github.com/cartland/go/imagic"
	"image"
	"log"
	"os"
	// _ "image/gif"
	_ "image/jpeg"
	"image/png"
)

func main() {
	// Decode the JPEG data.
	reader, err := os.Open("testdata/Chefchaouen.jpg")
	if err != nil {
		log.Fatal(err)
	}
	defer reader.Close()
	bg, _, err := image.Decode(reader)
	if err != nil {
		log.Fatal(err)
	}

	reader, err = os.Open("testdata/borrodepth.png")
	if err != nil {
		log.Fatal(err)
	}
	defer reader.Close()
	dm, _, err := image.Decode(reader)
	if err != nil {
		log.Fatal(err)
	}

	configWallEyed := imagic.Config{60, 100, false}
	configCrossEyed := imagic.Config{100, 160, true}

	wall := imagic.Imagic(dm, bg, configWallEyed)
	writer, err := os.Create("testdata/wallOutput.png")
	png.Encode(writer, wall)

	cross := imagic.Imagic(dm, bg, configCrossEyed)
	writer, err = os.Create("testdata/crossOutput.png")
	png.Encode(writer, cross)
}
<|endoftext|>


<commit_before>package com

import (
	"os"
	"runtime"
)

const (
	IsWindows = runtime.GOOS == "windows"
	IsLinux   = runtime.GOOS == "linux"
	IsMac     = runtime.GOOS == "darwin"
	Is32Bit   = runtime.GOARCH == "386"
	Is64Bit   = runtime.GOARCH == "amd64"
)

// ExitOnSuccess 成功时推出程序
func ExitOnSuccess(msg string) {
	os.Stdout.WriteString(msg)
	os.Exit(0)
}

// ExitOnFailure 失败时推出程序
func ExitOnFailure(msg string, errCodes ...int) {
	errCode := 1
	if len(errCodes) > 0 {
		errCode = errCodes[0]
	}
	os.Stderr.WriteString(msg)
	os.Exit(errCode)
}
<commit_msg>fix-typo<commit_after>package com

import (
	"os"
	"runtime"
)

const (
	IsWindows = runtime.GOOS == "windows"
	IsLinux   = runtime.GOOS == "linux"
	IsMac     = runtime.GOOS == "darwin"
	Is32Bit   = runtime.GOARCH == "386"
	Is64Bit   = runtime.GOARCH == "amd64"
)

// ExitOnSuccess 成功时退出程序
func ExitOnSuccess(msg string) {
	os.Stdout.WriteString(msg)
	os.Exit(0)
}

// ExitOnFailure 失败时退出程序
func ExitOnFailure(msg string, errCodes ...int) {
	errCode := 1
	if len(errCodes) > 0 {
		errCode = errCodes[0]
	}
	os.Stderr.WriteString(msg)
	os.Exit(errCode)
}
<|endoftext|>


<commit_before>package ari

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"
)

// AllDTMF is a string which contains all possible
// DTMF digits.
const AllDTMF = "0123456789ABCD*#"

// PlaybackStartTimeout is the time to allow for Asterisk to
// send the PlaybackStarted before giving up.
var PlaybackStartTimeout = 1 * time.Second

// MaxPlaybackTime is the maximum amount of time to allow for
// a playback to complete.
var MaxPlaybackTime = 10 * time.Minute

// Playback describes a session of playing media to a channel
// MediaURI is of the form 'type:name', where type can be one of:
//  - sound : a Sound on the Asterisk system
//  - recording : a StoredRecording on the Asterisk system
//  - number : a number, to be spoken (integers, positive or negative)
//  - digits : a set of digits, to be spoken (includes -*#0123456789)
//  - characters : a set of characters, to be spoken
//  - tone : a tone sequence, which may optionally take a tonezone parameter (e.g, tone:ring:tonezone=fr)
//
// TargetURI is of the form 'type:id', and looks like the following two options:
//  - bridge:bridgeID
//  - channel:channelID

// Playback describes an ARI playback handle
type Playback struct {
	ID        string `json:"id"` // Unique ID for this playback session
	Language  string `json:"language,omitempty"`
	MediaURI  string `json:"media_uri"`  // URI for the media which is to be played
	State     string `json:"state"`      // State of the playback operation
	TargetURI string `json:"target_uri"` // URI of the channel or bridge on which the media should be played (follows format of 'type':'name')

	client *Client // Reference to the client which created or returned this channel
}

// PlaybackOptions describes various options which
// are available to playback operations.
type PlaybackOptions struct {
	// ID is an optional ID to use for the playback's ID. If one
	// is not supplied, an ID will be randomly generated internally.
	// NOTE that this ID will only be used for the FIRST playback
	// in a queue.  All subsequent playback IDs will be randomly generated.
	ID string

	// DTMF is an optional channel for received DTMF tones received during the playback.
	// This channel will NOT be closed by the playback.
	DTMF chan<- *ChannelDtmfReceived

	// ExitOnDTMF defines a list of DTMF digits on receipt of which will
	// terminate the playback of the queue.  You may set this to AllDTMF
	// in order to match any DTMF digit.
	ExitOnDTMF string

	// Done is an optional channel for receiving notification when the playback
	// is complete.  This is useful if the playback is to be executed asynchronously.
	// This channel will be closed by the playback when playback the is complete.
	Done chan<- struct{}
}

// GetPlaybackDetails returns a playback's details.
// (Equivalent to GET /playbacks/{playbackID})
func (c *Client) GetPlaybackDetails(playbackID string) (Playback, error) {
	var m Playback
	err := c.Get("/playbacks/"+playbackID, &m)
	if err != nil {
		return m, err
	}
	return m, nil
}

// Control the current Playback
func (p *Playback) Control(operation string) error {
	if p.client == nil {
		return fmt.Errorf("No client found in Playback")
	}
	return p.client.ControlPlayback(p.ID, operation)
}

// Stop the current Playback.
func (p *Playback) Stop() error {
	if p.client == nil {
		return fmt.Errorf("No client found in Playback")
	}
	return p.client.StopPlayback(p.ID)
}

// ControlPlayback allows the user to manipulate an in-process playback.
// TODO: list available operations.
// (Equivalent to POST /playbacks/{playbackID}/control)
func (c *Client) ControlPlayback(playbackID string, operation string) error {

	//Request structure for controlling playback. Operation is required.
	type request struct {
		Operation string `json:"operation"`
	}

	req := request{operation}

	//Make the request
	err := c.Post("/playbacks/"+playbackID+"/control", nil, &req)

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

// StopPlayback stops a playback session.
// (Equivalent to DELETE /playbacks/{playbackID})
func (c *Client) StopPlayback(playbackID string) error {
	err := c.Delete("/playbacks/"+playbackID, nil, nil)
	return err
}

// A Player is anyhing which can "Play" an mediaURI
type Player interface {
	Play(string) (string, error)
	GetClient() *Client
}

// Play plays audio to the given Player, waiting for completion
// and returning any error encountered during playback.
func Play(ctx context.Context, p Player, mediaURI string) error {
	c := p.GetClient()
	if c == nil {
		return fmt.Errorf("Failed to find *ari.Client in Player")
	}

	s := c.Bus.Subscribe("PlaybackStarted", "PlaybackFinished")
	defer s.Cancel()

	id, err := p.Play(mediaURI)
	if err != nil {
		return err
	}
	defer c.StopPlayback(id)

	// Wait for the playback to start
	startTimer := time.After(PlaybackStartTimeout)
PlaybackStartLoop:
	for {
		select {
		case <-ctx.Done():
			return nil
		case v := <-s.C:
			if v == nil {
				Logger.Debug("Nil event received")
				continue PlaybackStartLoop
			}
			switch v.GetType() {
			case "PlaybackStarted":
				e := v.(*PlaybackStarted)
				if e.Playback.ID != id {
					Logger.Debug("Ignoring unrelated playback")
					continue PlaybackStartLoop
				}
				Logger.Debug("Playback started")
				break PlaybackStartLoop
			case "PlaybackFinished":
				e := v.(*PlaybackFinished)
				if e.Playback.ID != id {
					Logger.Debug("Ignoring unrelated playback")
					continue PlaybackStartLoop
				}
				Logger.Debug("Playback stopped (before PlaybackStated received)")
				return nil
			default:
				Logger.Debug("Unhandled e.Type", v.GetType())
				continue PlaybackStartLoop
			}
		case <-startTimer:
			Logger.Error("Playback timed out")
			return fmt.Errorf("Timeout waiting for start of playback")
		}
	}

	// Playback has started.  Wait for it to finish
	stopTimer := time.After(MaxPlaybackTime)
PlaybackStopLoop:
	for {
		select {
		case <-ctx.Done():
			return nil
		case v := <-s.C:
			if v == nil {
				Logger.Debug("Nil event received")
				continue PlaybackStopLoop
			}
			switch v.GetType() {
			case "PlaybackFinished":
				e := v.(*PlaybackFinished)
				if e.Playback.ID != id {
					Logger.Debug("Ignoring unrelated playback")
					continue PlaybackStopLoop
				}
				Logger.Debug("Playback stopped")
				return nil
			default:
				Logger.Debug("Unhandled e.Type", v.GetType())
				continue PlaybackStopLoop
			}
		case <-stopTimer:
			Logger.Error("Playback timed out")
			return fmt.Errorf("Timeout waiting for start of playback")
		}
	}
}

// PlaybackQueue represents a sequence of audio playbacks
// which are to be played on the associated Player
type PlaybackQueue struct {
	queue []string // List of mediaURI to be played
	mu    sync.Mutex

	receivedDTMF string // Storage for received DTMF, if we are listening for them
}

// NewPlaybackQueue creates (but does not start) a new playback queue.
func NewPlaybackQueue() *PlaybackQueue {
	return &PlaybackQueue{}
}

// Add appends one or more mediaURIs to the playback queue
func (pq *PlaybackQueue) Add(mediaURIs ...string) {
	// Make sure our queue exists
	pq.mu.Lock()
	if pq.queue == nil {
		pq.queue = []string{}
	}
	pq.mu.Unlock()

	// Add each media URI to the queue
	for _, u := range mediaURIs {
		if u == "" {
			continue
		}

		pq.mu.Lock()
		pq.queue = append(pq.queue, u)
		pq.mu.Unlock()
	}
}

// Flush empties a playback queue.
// NOTE that this does NOT stop the current playback.
func (pq *PlaybackQueue) Flush() {
	pq.mu.Lock()
	pq.queue = []string{}
	pq.mu.Unlock()
}

// ReceivedDTMF returns any DTMF which has been received
// by the PlaybackQueue.
func (pq *PlaybackQueue) ReceivedDTMF() string {
	return pq.receivedDTMF
}

// Play starts the playback of the queue to the Player.
func (pq *PlaybackQueue) Play(ctx context.Context, p Player, opts *PlaybackOptions) error {
	if opts == nil {
		opts = &PlaybackOptions{}
	}

	// Handle any options we were given
	if opts != nil {
		// Close the done channel when we finish,
		// if we were given one.
		if opts.Done != nil {
			defer close(opts.Done)
		}

		// Listen for DTMF, if we were asked to do so
		if opts.DTMF != nil {
			go func() {
				dtmfSub := p.GetClient().Bus.Subscribe("ChannelDtmfReceived")
				defer dtmfSub.Cancel()
				for {
					select {
					case <-ctx.Done():
						return
					case e := <-dtmfSub.C:
						opts.DTMF <- e.(*ChannelDtmfReceived)
					}
				}
			}()
		}
	}

	// Record any DTMF (this is separate from opts.DTMF) so that we can
	//  - Service ReceivedDTMF requests
	//  - Exit if we were given an ExitOnDTMF list
	var cancel context.CancelFunc
	ctx, cancel = context.WithCancel(ctx)
	go func() {
		dtmfSub := p.GetClient().Bus.Subscribe("ChannelDtmfReceived")
		defer dtmfSub.Cancel()
		for {
			select {
			case <-ctx.Done():
				return
			case e := <-dtmfSub.C:
				digit := e.(*ChannelDtmfReceived).Digit
				pq.receivedDTMF += digit
				if strings.Contains(opts.ExitOnDTMF, digit) {
					cancel()
				}
			}
		}
	}()

	// Start the playback
	for i := 0; len(pq.queue) > i; i++ {
		// Make sure our context isn't closed
		select {
		case <-ctx.Done():
			return nil
		default:
		}
		// Get the next clip
		err := Play(ctx, p, pq.queue[i])
		if err != nil {
			return err
		}
	}

	return nil
}

// PlayAsync plays the queue, returing immediately with an error channel,
// which will pass any errors and be closed on completion of the queue.
func (pq *PlaybackQueue) PlayAsync(ctx context.Context, p Player, opts *PlaybackOptions) chan error {
	errChan := make(chan error)
	go func() {
		err := pq.Play(ctx, p, opts)
		if err != nil {
			errChan <- err
		}
		close(errChan)
		return
	}()

	return errChan
}

// IsOpenPattern determines whether the regular expression is
// open-ended (allows for an indeterminite number of trailing
// parts) or not.
func IsOpenPattern(p string) bool {
	strings.TrimSuffix(p, "$")
	if strings.HasSuffix(p, ".") {
		return true
	}
	if strings.HasSuffix(p, "*") {
		return true
	}
	return false
}
<commit_msg>playback - fix error wording<commit_after>package ari

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"
)

// AllDTMF is a string which contains all possible
// DTMF digits.
const AllDTMF = "0123456789ABCD*#"

// PlaybackStartTimeout is the time to allow for Asterisk to
// send the PlaybackStarted before giving up.
var PlaybackStartTimeout = 1 * time.Second

// MaxPlaybackTime is the maximum amount of time to allow for
// a playback to complete.
var MaxPlaybackTime = 10 * time.Minute

// Playback describes a session of playing media to a channel
// MediaURI is of the form 'type:name', where type can be one of:
//  - sound : a Sound on the Asterisk system
//  - recording : a StoredRecording on the Asterisk system
//  - number : a number, to be spoken (integers, positive or negative)
//  - digits : a set of digits, to be spoken (includes -*#0123456789)
//  - characters : a set of characters, to be spoken
//  - tone : a tone sequence, which may optionally take a tonezone parameter (e.g, tone:ring:tonezone=fr)
//
// TargetURI is of the form 'type:id', and looks like the following two options:
//  - bridge:bridgeID
//  - channel:channelID

// Playback describes an ARI playback handle
type Playback struct {
	ID        string `json:"id"` // Unique ID for this playback session
	Language  string `json:"language,omitempty"`
	MediaURI  string `json:"media_uri"`  // URI for the media which is to be played
	State     string `json:"state"`      // State of the playback operation
	TargetURI string `json:"target_uri"` // URI of the channel or bridge on which the media should be played (follows format of 'type':'name')

	client *Client // Reference to the client which created or returned this channel
}

// PlaybackOptions describes various options which
// are available to playback operations.
type PlaybackOptions struct {
	// ID is an optional ID to use for the playback's ID. If one
	// is not supplied, an ID will be randomly generated internally.
	// NOTE that this ID will only be used for the FIRST playback
	// in a queue.  All subsequent playback IDs will be randomly generated.
	ID string

	// DTMF is an optional channel for received DTMF tones received during the playback.
	// This channel will NOT be closed by the playback.
	DTMF chan<- *ChannelDtmfReceived

	// ExitOnDTMF defines a list of DTMF digits on receipt of which will
	// terminate the playback of the queue.  You may set this to AllDTMF
	// in order to match any DTMF digit.
	ExitOnDTMF string

	// Done is an optional channel for receiving notification when the playback
	// is complete.  This is useful if the playback is to be executed asynchronously.
	// This channel will be closed by the playback when playback the is complete.
	Done chan<- struct{}
}

// GetPlaybackDetails returns a playback's details.
// (Equivalent to GET /playbacks/{playbackID})
func (c *Client) GetPlaybackDetails(playbackID string) (Playback, error) {
	var m Playback
	err := c.Get("/playbacks/"+playbackID, &m)
	if err != nil {
		return m, err
	}
	return m, nil
}

// Control the current Playback
func (p *Playback) Control(operation string) error {
	if p.client == nil {
		return fmt.Errorf("No client found in Playback")
	}
	return p.client.ControlPlayback(p.ID, operation)
}

// Stop the current Playback.
func (p *Playback) Stop() error {
	if p.client == nil {
		return fmt.Errorf("No client found in Playback")
	}
	return p.client.StopPlayback(p.ID)
}

// ControlPlayback allows the user to manipulate an in-process playback.
// TODO: list available operations.
// (Equivalent to POST /playbacks/{playbackID}/control)
func (c *Client) ControlPlayback(playbackID string, operation string) error {

	//Request structure for controlling playback. Operation is required.
	type request struct {
		Operation string `json:"operation"`
	}

	req := request{operation}

	//Make the request
	err := c.Post("/playbacks/"+playbackID+"/control", nil, &req)

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

// StopPlayback stops a playback session.
// (Equivalent to DELETE /playbacks/{playbackID})
func (c *Client) StopPlayback(playbackID string) error {
	err := c.Delete("/playbacks/"+playbackID, nil, nil)
	return err
}

// A Player is anyhing which can "Play" an mediaURI
type Player interface {
	Play(string) (string, error)
	GetClient() *Client
}

// Play plays audio to the given Player, waiting for completion
// and returning any error encountered during playback.
func Play(ctx context.Context, p Player, mediaURI string) error {
	c := p.GetClient()
	if c == nil {
		return fmt.Errorf("Failed to find *ari.Client in Player")
	}

	s := c.Bus.Subscribe("PlaybackStarted", "PlaybackFinished")
	defer s.Cancel()

	id, err := p.Play(mediaURI)
	if err != nil {
		return err
	}
	defer c.StopPlayback(id)

	// Wait for the playback to start
	startTimer := time.After(PlaybackStartTimeout)
PlaybackStartLoop:
	for {
		select {
		case <-ctx.Done():
			return nil
		case v := <-s.C:
			if v == nil {
				Logger.Debug("Nil event received")
				continue PlaybackStartLoop
			}
			switch v.GetType() {
			case "PlaybackStarted":
				e := v.(*PlaybackStarted)
				if e.Playback.ID != id {
					Logger.Debug("Ignoring unrelated playback")
					continue PlaybackStartLoop
				}
				Logger.Debug("Playback started")
				break PlaybackStartLoop
			case "PlaybackFinished":
				e := v.(*PlaybackFinished)
				if e.Playback.ID != id {
					Logger.Debug("Ignoring unrelated playback")
					continue PlaybackStartLoop
				}
				Logger.Debug("Playback stopped (before PlaybackStated received)")
				return nil
			default:
				Logger.Debug("Unhandled e.Type", v.GetType())
				continue PlaybackStartLoop
			}
		case <-startTimer:
			Logger.Error("Playback timed out")
			return fmt.Errorf("Timeout waiting for start of playback")
		}
	}

	// Playback has started.  Wait for it to finish
	stopTimer := time.After(MaxPlaybackTime)
PlaybackStopLoop:
	for {
		select {
		case <-ctx.Done():
			return nil
		case v := <-s.C:
			if v == nil {
				Logger.Debug("Nil event received")
				continue PlaybackStopLoop
			}
			switch v.GetType() {
			case "PlaybackFinished":
				e := v.(*PlaybackFinished)
				if e.Playback.ID != id {
					Logger.Debug("Ignoring unrelated playback")
					continue PlaybackStopLoop
				}
				Logger.Debug("Playback stopped")
				return nil
			default:
				Logger.Debug("Unhandled e.Type", v.GetType())
				continue PlaybackStopLoop
			}
		case <-stopTimer:
			Logger.Error("Playback timed out")
			return fmt.Errorf("Timeout waiting for stop of playback")
		}
	}
}

// PlaybackQueue represents a sequence of audio playbacks
// which are to be played on the associated Player
type PlaybackQueue struct {
	queue []string // List of mediaURI to be played
	mu    sync.Mutex

	receivedDTMF string // Storage for received DTMF, if we are listening for them
}

// NewPlaybackQueue creates (but does not start) a new playback queue.
func NewPlaybackQueue() *PlaybackQueue {
	return &PlaybackQueue{}
}

// Add appends one or more mediaURIs to the playback queue
func (pq *PlaybackQueue) Add(mediaURIs ...string) {
	// Make sure our queue exists
	pq.mu.Lock()
	if pq.queue == nil {
		pq.queue = []string{}
	}
	pq.mu.Unlock()

	// Add each media URI to the queue
	for _, u := range mediaURIs {
		if u == "" {
			continue
		}

		pq.mu.Lock()
		pq.queue = append(pq.queue, u)
		pq.mu.Unlock()
	}
}

// Flush empties a playback queue.
// NOTE that this does NOT stop the current playback.
func (pq *PlaybackQueue) Flush() {
	pq.mu.Lock()
	pq.queue = []string{}
	pq.mu.Unlock()
}

// ReceivedDTMF returns any DTMF which has been received
// by the PlaybackQueue.
func (pq *PlaybackQueue) ReceivedDTMF() string {
	return pq.receivedDTMF
}

// Play starts the playback of the queue to the Player.
func (pq *PlaybackQueue) Play(ctx context.Context, p Player, opts *PlaybackOptions) error {
	if opts == nil {
		opts = &PlaybackOptions{}
	}

	// Handle any options we were given
	if opts != nil {
		// Close the done channel when we finish,
		// if we were given one.
		if opts.Done != nil {
			defer close(opts.Done)
		}

		// Listen for DTMF, if we were asked to do so
		if opts.DTMF != nil {
			go func() {
				dtmfSub := p.GetClient().Bus.Subscribe("ChannelDtmfReceived")
				defer dtmfSub.Cancel()
				for {
					select {
					case <-ctx.Done():
						return
					case e := <-dtmfSub.C:
						opts.DTMF <- e.(*ChannelDtmfReceived)
					}
				}
			}()
		}
	}

	// Record any DTMF (this is separate from opts.DTMF) so that we can
	//  - Service ReceivedDTMF requests
	//  - Exit if we were given an ExitOnDTMF list
	var cancel context.CancelFunc
	ctx, cancel = context.WithCancel(ctx)
	go func() {
		dtmfSub := p.GetClient().Bus.Subscribe("ChannelDtmfReceived")
		defer dtmfSub.Cancel()
		for {
			select {
			case <-ctx.Done():
				return
			case e := <-dtmfSub.C:
				digit := e.(*ChannelDtmfReceived).Digit
				pq.receivedDTMF += digit
				if strings.Contains(opts.ExitOnDTMF, digit) {
					cancel()
				}
			}
		}
	}()

	// Start the playback
	for i := 0; len(pq.queue) > i; i++ {
		// Make sure our context isn't closed
		select {
		case <-ctx.Done():
			return nil
		default:
		}
		// Get the next clip
		err := Play(ctx, p, pq.queue[i])
		if err != nil {
			return err
		}
	}

	return nil
}

// PlayAsync plays the queue, returing immediately with an error channel,
// which will pass any errors and be closed on completion of the queue.
func (pq *PlaybackQueue) PlayAsync(ctx context.Context, p Player, opts *PlaybackOptions) chan error {
	errChan := make(chan error)
	go func() {
		err := pq.Play(ctx, p, opts)
		if err != nil {
			errChan <- err
		}
		close(errChan)
		return
	}()

	return errChan
}

// IsOpenPattern determines whether the regular expression is
// open-ended (allows for an indeterminite number of trailing
// parts) or not.
func IsOpenPattern(p string) bool {
	strings.TrimSuffix(p, "$")
	if strings.HasSuffix(p, ".") {
		return true
	}
	if strings.HasSuffix(p, "*") {
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"container/vector"
	"flag"
	"fmt"
	"igo/build"
	"igo/deps"
	"igo/set"
	"os"
	"path"
	"strings"
)

// executeCommand runs the specified tool with the supplied arguments (not
// including the path to the tool itself), chdir'ing to the specified directory
// first. It returns true if and only if the child process returns zero.
func executeCommand(tool string, args []string, dir string) bool {
	fmt.Printf("%s %s\n", tool, strings.Join(args, " "))

	var fullArgs vector.StringVector
	fullArgs.Push(tool)
	fullArgs.AppendVector(&args)

	pid, err := os.ForkExec(
		tool,
		fullArgs.Data(),
		os.Environ(),
		dir,
		[]*os.File{os.Stdin, os.Stdout, os.Stderr})
	if err != nil {
		panic(err)
	}

	waitMsg, err := os.Wait(pid, 0)
	if err != nil {
		panic(err)
	}

	return waitMsg.ExitStatus() == 0
}

// compileFiles invokes 6g with the appropriate arguments for compiling the
// supplied set of .go files, and exits the program if the subprocess fails.
func compileFiles(files *set.StringSet, targetBaseName string) {
	compilerPath := path.Join(os.Getenv("GOBIN"), "6g")
	gopackPath := path.Join(os.Getenv("GOBIN"), "gopack")

	targetDir, _ := path.Split(targetBaseName)
	if targetDir != "" {
		os.MkdirAll(path.Join("igo-out", targetDir), 0700)
	}

	// Compile
	var compilerArgs vector.StringVector
	compilerArgs.Push("-o")
	compilerArgs.Push(targetBaseName + ".6")

	for file := range files.Iter() {
		compilerArgs.Push(path.Join("../", file))
	}

	if !executeCommand(compilerPath, compilerArgs.Data(), "igo-out/") {
		os.Exit(1)
	}

	// Pack
	var gopackArgs vector.StringVector
	gopackArgs.Push("grc")
	gopackArgs.Push(targetBaseName + ".a")
	gopackArgs.Push(targetBaseName + ".6")

	if !executeCommand(gopackPath, gopackArgs.Data(), "igo-out/") {
		os.Exit(1)
	}
}

func main() {
	flag.Parse()

	if flag.NArg() != 2 || flag.Arg(0) != "build" {
		fmt.Println("Usage: igo build <directory name>")
		os.Exit(1)
	}

	// Grab dependency and file information for every local package, starting
	// with the specified one. We consider a package local if it starts with "./".
	requiredFiles := make(map[string]*set.StringSet)
	packageDeps := make(map[string]*set.StringSet)

	var remainingDirs vector.StringVector
	remainingDirs.Push("./" + flag.Arg(1))

	for remainingDirs.Len() > 0 {
		dir := remainingDirs.Pop()

		// Have we already processed this directory?
		_, alreadyDone := packageDeps[dir]
		if alreadyDone { continue }

		dirInfo := build.GetDirectoryInfo(dir, false)
		if dirInfo.PackageName == "" {
			fmt.Printf("Couldn't find .go files to build in directory: %s\n", dir)
			os.Exit(1)
		}

		// Stash information about this package, and add its local dependencies to
		// the queue.
		requiredFiles[dir] = dirInfo.Files
		packageDeps[dir] = dirInfo.Deps

		for dep := range dirInfo.Deps.Iter() {
			if strings.HasPrefix(dep, "./") { remainingDirs.Push(dep) }
		}
	}

	// Order the packages by their dependencies.
	totalOrder := deps.BuildTotalOrder(packageDeps)
	fmt.Println("Found these packages to compile:")
	for _, packageName := range totalOrder {
		fmt.Printf("  %s\n", packageName)
	}

	// Create a directory to hold outputs, deleting the old one first.
	os.RemoveAll("igo-out")
	os.Mkdir("igo-out", 0700)

	// Compile each of the packages in turn.
	for _, currentPackage := range totalOrder {
		fmt.Printf("\nCompiling package: %s\n", currentPackage)
		compileFiles(requiredFiles[currentPackage], currentPackage)
	}
}
<commit_msg>Ran gofmt.<commit_after>package main

import (
	"container/vector"
	"flag"
	"fmt"
	"igo/build"
	"igo/deps"
	"igo/set"
	"os"
	"path"
	"strings"
)

// executeCommand runs the specified tool with the supplied arguments (not
// including the path to the tool itself), chdir'ing to the specified directory
// first. It returns true if and only if the child process returns zero.
func executeCommand(tool string, args []string, dir string) bool {
	fmt.Printf("%s %s\n", tool, strings.Join(args, " "))

	var fullArgs vector.StringVector
	fullArgs.Push(tool)
	fullArgs.AppendVector(&args)

	pid, err := os.ForkExec(
		tool,
		fullArgs.Data(),
		os.Environ(),
		dir,
		[]*os.File{os.Stdin, os.Stdout, os.Stderr})
	if err != nil {
		panic(err)
	}

	waitMsg, err := os.Wait(pid, 0)
	if err != nil {
		panic(err)
	}

	return waitMsg.ExitStatus() == 0
}

// compileFiles invokes 6g with the appropriate arguments for compiling the
// supplied set of .go files, and exits the program if the subprocess fails.
func compileFiles(files *set.StringSet, targetBaseName string) {
	compilerPath := path.Join(os.Getenv("GOBIN"), "6g")
	gopackPath := path.Join(os.Getenv("GOBIN"), "gopack")

	targetDir, _ := path.Split(targetBaseName)
	if targetDir != "" {
		os.MkdirAll(path.Join("igo-out", targetDir), 0700)
	}

	// Compile
	var compilerArgs vector.StringVector
	compilerArgs.Push("-o")
	compilerArgs.Push(targetBaseName + ".6")

	for file := range files.Iter() {
		compilerArgs.Push(path.Join("../", file))
	}

	if !executeCommand(compilerPath, compilerArgs.Data(), "igo-out/") {
		os.Exit(1)
	}

	// Pack
	var gopackArgs vector.StringVector
	gopackArgs.Push("grc")
	gopackArgs.Push(targetBaseName + ".a")
	gopackArgs.Push(targetBaseName + ".6")

	if !executeCommand(gopackPath, gopackArgs.Data(), "igo-out/") {
		os.Exit(1)
	}
}

func main() {
	flag.Parse()

	if flag.NArg() != 2 || flag.Arg(0) != "build" {
		fmt.Println("Usage: igo build <directory name>")
		os.Exit(1)
	}

	// Grab dependency and file information for every local package, starting
	// with the specified one. We consider a package local if it starts with "./".
	requiredFiles := make(map[string]*set.StringSet)
	packageDeps := make(map[string]*set.StringSet)

	var remainingDirs vector.StringVector
	remainingDirs.Push("./" + flag.Arg(1))

	for remainingDirs.Len() > 0 {
		dir := remainingDirs.Pop()

		// Have we already processed this directory?
		_, alreadyDone := packageDeps[dir]
		if alreadyDone {
			continue
		}

		dirInfo := build.GetDirectoryInfo(dir, false)
		if dirInfo.PackageName == "" {
			fmt.Printf("Couldn't find .go files to build in directory: %s\n", dir)
			os.Exit(1)
		}

		// Stash information about this package, and add its local dependencies to
		// the queue.
		requiredFiles[dir] = dirInfo.Files
		packageDeps[dir] = dirInfo.Deps

		for dep := range dirInfo.Deps.Iter() {
			if strings.HasPrefix(dep, "./") {
				remainingDirs.Push(dep)
			}
		}
	}

	// Order the packages by their dependencies.
	totalOrder := deps.BuildTotalOrder(packageDeps)
	fmt.Println("Found these packages to compile:")
	for _, packageName := range totalOrder {
		fmt.Printf("  %s\n", packageName)
	}

	// Create a directory to hold outputs, deleting the old one first.
	os.RemoveAll("igo-out")
	os.Mkdir("igo-out", 0700)

	// Compile each of the packages in turn.
	for _, currentPackage := range totalOrder {
		fmt.Printf("\nCompiling package: %s\n", currentPackage)
		compileFiles(requiredFiles[currentPackage], currentPackage)
	}
}
<|endoftext|>


<commit_before>package main

import (
	_ "expvar"
	"github.com/couchbaselabs/logg"
	"github.com/tleyden/checkerlution"
	cbot "github.com/tleyden/checkers-bot"
	ng "github.com/tleyden/neurgo"
	"net/http"
)

func init() {
	logg.LogKeys["MAIN"] = true
	logg.LogKeys["DEBUG"] = true
	logg.LogKeys["CHECKERLUTION"] = true
	logg.LogKeys["CHECKERLUTION_SCAPE"] = true
	logg.LogKeys["CHECKERSBOT"] = true
	logg.LogKeys["NEURGO"] = false
	logg.LogKeys["SENSOR_SYNC"] = false
	logg.LogKeys["ACTUATOR_SYNC"] = false
	logg.LogKeys["NODE_PRE_SEND"] = false
	logg.LogKeys["NODE_POST_SEND"] = false
	logg.LogKeys["NODE_POST_RECV"] = false
	logg.LogKeys["NODE_STATE"] = false
	ng.SeedRandom()
}

func train() {

	// run a webserver in order to view expvar output
	// at http://localhost:8080/debug/vars
	go http.ListenAndServe(":8080", nil)

	trainer := &checkerlution.CheckerlutionTrainer{}

	// checkerlution.RunTopologyMutatingTrainer()
	trainer.RunPopulationTrainer()

}

func run() {

	LOAD_CORTEX_FROM_FILE := false

	checkersBotFlags := cbot.ParseCmdLine()

	thinker := &checkerlution.Checkerlution{}
	thinker.SetMode(checkerlution.RUNNING_MODE)

	if LOAD_CORTEX_FROM_FILE {
		filename := "checkerlution_trained.json"
		cortex, err := ng.NewCortexFromJSONFile(filename)
		if err != nil {
			logg.LogPanic("Error reading cortex from: %v.  Err: %v", filename, err)
		}
		thinker.StartWithCortex(cortex, checkersBotFlags.Team)

	} else {
		thinker.Start(checkersBotFlags.Team)
	}

	game := cbot.NewGame(checkersBotFlags.Team, thinker)
	game.SetServerUrl(checkersBotFlags.SyncGatewayUrl)
	game.SetFeedType(checkersBotFlags.FeedType)
	game.SetDelayBeforeMove(checkersBotFlags.RandomDelayBeforeMove)

	logg.LogTo("CHECKERLUTION", "Starting game loop")
	game.GameLoop()
	logg.LogTo("CHECKERLUTION", "Game loop finished")

}

func main() {
	MODE := 1
	if MODE == 0 {
		run()
	} else {
		train()
	}

}
<commit_msg>Enable more debugging<commit_after>package main

import (
	_ "expvar"
	"github.com/couchbaselabs/logg"
	"github.com/tleyden/checkerlution"
	cbot "github.com/tleyden/checkers-bot"
	ng "github.com/tleyden/neurgo"
	"net/http"
)

func init() {
	logg.LogKeys["MAIN"] = true
	logg.LogKeys["DEBUG"] = true
	logg.LogKeys["CHECKERLUTION"] = true
	logg.LogKeys["CHECKERLUTION_SCAPE"] = true
	logg.LogKeys["CHECKERSBOT"] = true
	logg.LogKeys["NEURGO"] = false
	logg.LogKeys["NEURVOLVE"] = true
	logg.LogKeys["SENSOR_SYNC"] = false
	logg.LogKeys["ACTUATOR_SYNC"] = false
	logg.LogKeys["NODE_PRE_SEND"] = false
	logg.LogKeys["NODE_POST_SEND"] = false
	logg.LogKeys["NODE_POST_RECV"] = false
	logg.LogKeys["NODE_STATE"] = false
	ng.SeedRandom()
}

func train() {

	// run a webserver in order to view expvar output
	// at http://localhost:8080/debug/vars
	go http.ListenAndServe(":8080", nil)

	trainer := &checkerlution.CheckerlutionTrainer{}

	// checkerlution.RunTopologyMutatingTrainer()
	trainer.RunPopulationTrainer()

}

func run() {

	LOAD_CORTEX_FROM_FILE := false

	checkersBotFlags := cbot.ParseCmdLine()

	thinker := &checkerlution.Checkerlution{}
	thinker.SetMode(checkerlution.RUNNING_MODE)

	if LOAD_CORTEX_FROM_FILE {
		filename := "checkerlution_trained.json"
		cortex, err := ng.NewCortexFromJSONFile(filename)
		if err != nil {
			logg.LogPanic("Error reading cortex from: %v.  Err: %v", filename, err)
		}
		thinker.StartWithCortex(cortex, checkersBotFlags.Team)

	} else {
		thinker.Start(checkersBotFlags.Team)
	}

	game := cbot.NewGame(checkersBotFlags.Team, thinker)
	game.SetServerUrl(checkersBotFlags.SyncGatewayUrl)
	game.SetFeedType(checkersBotFlags.FeedType)
	game.SetDelayBeforeMove(checkersBotFlags.RandomDelayBeforeMove)

	logg.LogTo("CHECKERLUTION", "Starting game loop")
	game.GameLoop()
	logg.LogTo("CHECKERLUTION", "Game loop finished")

}

func main() {
	MODE := 1
	if MODE == 0 {
		run()
	} else {
		train()
	}

}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"os"
	"fmt"
	"strings"
	"log"
	"flag"
	"github.com/fatih/color"
	"io"
)

var (
	Input *bufio.Reader
	Namespace string
	Variables map[string]string
	Verbose bool
)

func prompt(text string) (string, error) {
	fmt.Print(color.New(color.Bold).Sprintf(text + " "))
	line, err := Input.ReadString('\n')
	if err != nil {
		return "", err
	}
	response := strings.Trim(line, "\n")
	for from, to := range Variables {
		response = strings.Replace(response, from, to, -1)
	}
	return response, nil
}

func namespaceSelector(selector func([]string)(string, error)) error {
	namespaces, err := GetNamespaces()
	if err != nil {
		return err
	}

	targets := make([]string, len(namespaces.Items))
	for num, ns := range namespaces.Items {
		targets[num] = ns.Name
	}

	response, err := selector(targets)
	if err != nil {
		return err
	}
	Namespace = ClosestString(response, targets)
	return nil
}

func printIndexedLine(index, line string) {
	coloredIndex := color.New(color.FgBlue).Sprintf("%s", index)
	fmt.Printf("%s \t%s\n", coloredIndex, line)
}

func pickNamespace() error {
	return namespaceSelector(func(namespaces []string) (string, error) {
		for n, ns := range namespaces {
			key := fmt.Sprintf("$%d", n)
			Variables[key] = ns
			printIndexedLine(key, ns)
		}
		return prompt("# namespace")
	})
}

func switchNamespace(ns string) error {
	return namespaceSelector(func(namespaces []string) (string, error) {
		return ns, nil
	})
}

func repl() error {
	command, err := prompt("# " + Namespace)
	if err != nil {
		return err
	}

	parts := strings.Split(command, " ")
	if parts[0] == "namespace" || parts[0] == "ns" {
		if len(parts) > 1 {
			switchNamespace(parts[1])
		} else {
			pickNamespace()
		}
		return nil
	}

	output, err := KubectlSh(command)
	if output == "" {
		return err
	}

	if err == nil && strings.HasPrefix(command, "get") {
		variableIndex := 0
		for _, line := range strings.Split(output, "\n") {
			if strings.HasPrefix(line, "NAME ") {
				fmt.Printf("   \t%s\n", line)
			} else {
				variableIndex++
				printIndexedLine(fmt.Sprintf("$%v", variableIndex), line)
			}
			key := fmt.Sprintf("$%d", variableIndex)
			Variables[key] = strings.Split(line, " ")[0]
		}
	} else {
		fmt.Println(output)
	}
	return err
}

func main() {
	flag.BoolVar(&Verbose, "verbose", false, "Verbose")
	flag.Parse()

	Variables = make(map[string]string)
	Input = bufio.NewReader(os.Stdin)

	err := KubernetesSetup()
	if err != nil {
		log.Fatal(err)
	}

	err = pickNamespace()
	if err == io.EOF {
		return
	} else if err != nil {
		log.Fatal(err)
	}

	for {
		err = repl()
		if err == io.EOF {
			break
		}
	}
}
<commit_msg>add explicit exit/quit command<commit_after>package main

import (
	"bufio"
	"os"
	"fmt"
	"strings"
	"log"
	"flag"
	"github.com/fatih/color"
	"io"
)

var (
	Input *bufio.Reader
	Namespace string
	Variables map[string]string
	Verbose bool
)

func prompt(text string) (string, error) {
	fmt.Print(color.New(color.Bold).Sprintf(text + " "))
	line, err := Input.ReadString('\n')
	if err != nil {
		return "", err
	}
	response := strings.Trim(line, "\n")
	for from, to := range Variables {
		response = strings.Replace(response, from, to, -1)
	}
	return response, nil
}

func namespaceSelector(selector func([]string)(string, error)) error {
	namespaces, err := GetNamespaces()
	if err != nil {
		return err
	}

	targets := make([]string, len(namespaces.Items))
	for num, ns := range namespaces.Items {
		targets[num] = ns.Name
	}

	response, err := selector(targets)
	if err != nil {
		return err
	}
	Namespace = ClosestString(response, targets)
	return nil
}

func printIndexedLine(index, line string) {
	coloredIndex := color.New(color.FgBlue).Sprintf("%s", index)
	fmt.Printf("%s \t%s\n", coloredIndex, line)
}

func pickNamespace() error {
	return namespaceSelector(func(namespaces []string) (string, error) {
		for n, ns := range namespaces {
			key := fmt.Sprintf("$%d", n)
			Variables[key] = ns
			printIndexedLine(key, ns)
		}
		return prompt("# namespace")
	})
}

func switchNamespace(ns string) error {
	return namespaceSelector(func(namespaces []string) (string, error) {
		return ns, nil
	})
}

func repl() error {
	command, err := prompt("# " + Namespace)
	if err != nil {
		return err
	}

	parts := strings.Split(command, " ")
	if parts[0] == "exit" || parts[0] == "quit" {
		os.Exit(0)
	}
	if parts[0] == "namespace" || parts[0] == "ns" {
		if len(parts) > 1 {
			switchNamespace(parts[1])
		} else {
			pickNamespace()
		}
		return nil
	}

	output, err := KubectlSh(command)
	if output == "" {
		return err
	}

	if err == nil && strings.HasPrefix(command, "get") {
		variableIndex := 0
		for _, line := range strings.Split(output, "\n") {
			if strings.HasPrefix(line, "NAME ") {
				fmt.Printf("   \t%s\n", line)
			} else {
				variableIndex++
				printIndexedLine(fmt.Sprintf("$%v", variableIndex), line)
			}
			key := fmt.Sprintf("$%d", variableIndex)
			Variables[key] = strings.Split(line, " ")[0]
		}
	} else {
		fmt.Println(output)
	}
	return err
}

func main() {
	flag.BoolVar(&Verbose, "verbose", false, "Verbose")
	flag.Parse()

	Variables = make(map[string]string)
	Input = bufio.NewReader(os.Stdin)

	err := KubernetesSetup()
	if err != nil {
		log.Fatal(err)
	}

	err = pickNamespace()
	if err == io.EOF {
		return
	} else if err != nil {
		log.Fatal(err)
	}

	for {
		err = repl()
		if err == io.EOF {
			break
		}
	}
}
<|endoftext|>


<commit_before>// (c) 2021, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package main

import (
	"fmt"
	"log"
	"os"
	"syscall"

	appPlugin "github.com/ava-labs/avalanchego/main/plugin"
	"github.com/ava-labs/avalanchego/main/process"
	"github.com/ava-labs/avalanchego/utils"
	"github.com/ava-labs/avalanchego/utils/logging"
	"github.com/ava-labs/avalanchego/utils/perms"
	"github.com/hashicorp/go-hclog"
	"github.com/hashicorp/go-plugin"
)

const (
	header = "" +
		`     _____               .__                       .__` + "\n" +
		`    /  _  \___  _______  |  | _____    ____   ____ |  |__   ____    ,_ o` + "\n" +
		`   /  /_\  \  \/ /\__  \ |  | \__  \  /    \_/ ___\|  |  \_/ __ \   / //\,` + "\n" +
		`  /    |    \   /  / __ \|  |__/ __ \|   |  \  \___|   Y  \  ___/    \>> |` + "\n" +
		`  \____|__  /\_/  (____  /____(____  /___|  /\___  >___|  /\___  >    \\` + "\n" +
		`          \/           \/          \/     \/     \/     \/     \/`
)

// main is the primary entry point to Avalanche.
func main() {
	// parse config using viper
	if err := parseViper(); err != nil {
		// Returns exit code 1
		log.Fatalf("parsing parameters returned with error %s", err)
	}

	// Set the data directory permissions to be read write.
	if err := perms.ChmodR(defaultDataDir, true, perms.ReadWriteExecute); err != nil {
		log.Fatalf("failed to restrict the permissions of the data directory with error %s", err)
	}

	c := Config
	// Create the logger
	logFactory := logging.NewFactory(c.LoggingConfig)
	defer logFactory.Close()

	log, err := logFactory.Make()
	if err != nil {
		fmt.Printf("starting logger failed with: %s\n", err)
		os.Exit(1)
	}
	app := process.NewApp(c, logFactory, log)
	if c.PluginMode {
		plugin.Serve(&plugin.ServeConfig{
			HandshakeConfig: appPlugin.Handshake,
			Plugins: map[string]plugin.Plugin{
				"nodeProcess": appPlugin.New(app),
			},
			// A non-nil value here enables gRPC serving for this plugin
			GRPCServer: plugin.DefaultGRPCServer,
			Logger: hclog.New(&hclog.LoggerOptions{
				Level: hclog.Error,
			}),
		})
		return
	}

	fmt.Println(header)

	// If we get a a SIGINT or SIGTERM, tell the node to stop.
	// If [app.Start()] has been called, it will return.
	// If not, then when [app.Start()] is called below, it will immediately return 1.
	_ = utils.HandleSignals(
		func(os.Signal) {
			app.Stop()
		},
		syscall.SIGINT, syscall.SIGTERM,
	)
	// Start the node
	exitCode := app.Start()
	os.Exit(exitCode)
}
<commit_msg>removed defer that was never executed<commit_after>// (c) 2021, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package main

import (
	"fmt"
	"log"
	"os"
	"syscall"

	appPlugin "github.com/ava-labs/avalanchego/main/plugin"
	"github.com/ava-labs/avalanchego/main/process"
	"github.com/ava-labs/avalanchego/utils"
	"github.com/ava-labs/avalanchego/utils/logging"
	"github.com/ava-labs/avalanchego/utils/perms"
	"github.com/hashicorp/go-hclog"
	"github.com/hashicorp/go-plugin"
)

const (
	header = "" +
		`     _____               .__                       .__` + "\n" +
		`    /  _  \___  _______  |  | _____    ____   ____ |  |__   ____    ,_ o` + "\n" +
		`   /  /_\  \  \/ /\__  \ |  | \__  \  /    \_/ ___\|  |  \_/ __ \   / //\,` + "\n" +
		`  /    |    \   /  / __ \|  |__/ __ \|   |  \  \___|   Y  \  ___/    \>> |` + "\n" +
		`  \____|__  /\_/  (____  /____(____  /___|  /\___  >___|  /\___  >    \\` + "\n" +
		`          \/           \/          \/     \/     \/     \/     \/`
)

// main is the primary entry point to Avalanche.
func main() {
	// parse config using viper
	if err := parseViper(); err != nil {
		// Returns exit code 1
		log.Fatalf("parsing parameters returned with error %s", err)
	}

	// Set the data directory permissions to be read write.
	if err := perms.ChmodR(defaultDataDir, true, perms.ReadWriteExecute); err != nil {
		log.Fatalf("failed to restrict the permissions of the data directory with error %s", err)
	}

	c := Config
	// Create the logger
	logFactory := logging.NewFactory(c.LoggingConfig)

	log, err := logFactory.Make()
	if err != nil {
		logFactory.Close()
		fmt.Printf("starting logger failed with: %s\n", err)
		os.Exit(1)
	}

	app := process.NewApp(c, logFactory, log)
	if c.PluginMode {
		plugin.Serve(&plugin.ServeConfig{
			HandshakeConfig: appPlugin.Handshake,
			Plugins: map[string]plugin.Plugin{
				"nodeProcess": appPlugin.New(app),
			},
			// A non-nil value here enables gRPC serving for this plugin
			GRPCServer: plugin.DefaultGRPCServer,
			Logger: hclog.New(&hclog.LoggerOptions{
				Level: hclog.Error,
			}),
		})
		return
	}

	fmt.Println(header)

	// If we get a a SIGINT or SIGTERM, tell the node to stop.
	// If [app.Start()] has been called, it will return.
	// If not, then when [app.Start()] is called below, it will immediately return 1.
	_ = utils.HandleSignals(
		func(os.Signal) {
			app.Stop()
		},
		syscall.SIGINT, syscall.SIGTERM,
	)
	// Start the node
	exitCode := app.Start()

	logFactory.Close()
	os.Exit(exitCode)
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/bamstats"
	"github.com/codegangsta/cli"
)

func check(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

var (
	bam, annotation, loglevel string
	cpu, maxBuf, reads        int
)

func run(c *cli.Context) {
	level, err := log.ParseLevel(loglevel)
	check(err)
	log.SetLevel(level)
	if bam == "" {
		log.Fatal("no file specified")
	}
	// stats := bamstats.Coverage1(bam, annotation, cpu)
	stats := bamstats.General(bam, cpu, maxBuf, reads)
	bamstats.OutputJson(stats)
}

func main() {
	app := cli.NewApp()
	app.Name = "bamstats"
	app.Usage = "Compute mapping statistics"
	app.Version = bamstats.Version
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "bam, b",
			Value:       "",
			Usage:       "input file",
			Destination: &bam,
		},
		cli.StringFlag{
			Name:        "annotation, a",
			Value:       "",
			Usage:       "bgzip compressed and indexed annotation file",
			Destination: &annotation,
		},
		cli.StringFlag{
			Name:        "loglevel",
			Value:       "warn",
			Usage:       "logging level",
			Destination: &loglevel,
		},
		cli.IntFlag{
			Name:        "cpu, c",
			Value:       1,
			Usage:       "number of cpus to be used",
			Destination: &cpu,
		},
		cli.IntFlag{
			Name:        "max-buf",
			Value:       1000000,
			Usage:       "maximum number of buffered records",
			Destination: &maxBuf,
		},
		cli.IntFlag{
			Name:        "n",
			Value:       -1,
			Usage:       "number of reads to process",
			Destination: &reads,
		},
	}
	app.Action = run

	if len(os.Args) == 1 {
		os.Args = append(os.Args, "help")
	}
	app.Run(os.Args)
}
<commit_msg>Update cli help<commit_after>package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/bamstats"
	"github.com/codegangsta/cli"
)

func check(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

var (
	bam, annotation, loglevel string
	cpu, maxBuf, reads        int
)

func run(c *cli.Context) {
	level, err := log.ParseLevel(loglevel)
	check(err)
	log.SetLevel(level)
	if bam == "" {
		log.Fatal("no file specified")
	}
	// stats := bamstats.Coverage1(bam, annotation, cpu)
	stats := bamstats.General(bam, cpu, maxBuf, reads)
	bamstats.OutputJson(stats)
}

func main() {
	app := cli.NewApp()
	app.Name = "bamstats"
	app.Usage = "Compute mapping statistics"
	app.Version = bamstats.Version
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "bam, b",
			Value:       "",
			Usage:       "input file",
			Destination: &bam,
		},
		cli.StringFlag{
			Name:        "annotation, a",
			Value:       "",
			Usage:       "bgzip compressed and indexed annotation file",
			Destination: &annotation,
		},
		cli.StringFlag{
			Name:        "loglevel",
			Value:       "warn",
			Usage:       "logging level",
			Destination: &loglevel,
		},
		cli.IntFlag{
			Name:        "cpu, c",
			Value:       1,
			Usage:       "number of cpus to be used",
			Destination: &cpu,
		},
		cli.IntFlag{
			Name:        "max-buf",
			Value:       1000000,
			Usage:       "maximum number of buffered records",
			Destination: &maxBuf,
		},
		cli.IntFlag{
			Name:        "n",
			Value:       -1,
			Usage:       "number of records to process",
			Destination: &reads,
		},
	}
	app.Action = run

	if len(os.Args) == 1 {
		os.Args = append(os.Args, "help")
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"os/exec"
	"syscall"
	"testing"
)

func TestMain(t *testing.T) {
	shouldEqual(t, `xo`,
		`Usage: xo '/<pattern>/<formatter>/[flags]'
`)
	shouldEqual(t, `echo 'Hello there!' | xo '~hello(.*)~Hi$1~i'`,
		`Hi there!
`)
	shouldEqual(t, `echo 'Hello! - Luke' | xo '/(hello).*?-.*?(\w+)/Why $1, $2!/i'`,
		`Why Hello, Luke!
`)
	shouldEqual(t, `cat fixtures/servers.yml | xo '/.*?(production):\s*server:\s+([^:\n]+):?(\d+)?.*?user:\s+([^\n]+).*/$4@$2 -p $3?:22/mis'`,
		`user-1@192.168.1.1 -p 1234
`)
	shouldEqual(t, `cat fixtures/starwars.txt | xo '/^(\w+):(\s*\[(.*?)\]\s*)?\s*([^\n]+)/$1 said, "$4" in a $3?:normal voice./mi'`,
		`Vader said, "If only you knew the power of the Dark Side. Obi-Wan never told you what happened to your father." in a normal voice.
Luke said, "He told me enough! He told me you killed him!" in a normal voice.
Vader said, "No, I am your father." in a normal voice.
Luke said, "No. No! That's not true! That's impossible!" in a shocked voice.
`)
	shouldEqual(t, `echo '123' | xo '/(\d)(\d)(\d)(\d)?(\d)?/$1, $2, $3, 4?:FOUR $5?:FIVE/'`,
		`1, 2, 3, 4?:FOUR FIVE
`)
	shouldEqual(t, `echo 'abc' | xo '%(\w)(\w)(\w)(\w)?%$1$2$3$4?:$1%'`,
		`abca
`)
	shouldEqual(t, `echo 'Hello! My name is C3PO, human cyborg relations.' | xo '/^((\w+)! )?my name is (\w+)/$2?:Hello, $3!/i'`,
		`Hello, C3PO!
`)
	shouldEqual(t, `echo 'My name is Chewbacca, uuuuuur ahhhhhrrr uhrrr ahhhrrr aaargh!' | xo '|^((\w+)! )?my name is (\w+)|$2?:Greetings, $3!|i'`,
		`Greetings, Chewbacca!
`)
	shouldEqual(t, `cat fixtures/romans.txt | xo '/\d\s(\w+).*?to all that are in (\w+),.*?24 \[the (grace)? of ([\w\s]{21})/Romans is a letter written by $1 addressed to the people of $2 about the $3?:gospel of $4./mis'`,
		`Romans is a letter written by Paul addressed to the people of Rome about the grace of our Lord Jesus Christ.
`)
	shouldEqual(t, `echo 'hi' | xo '/(hi)/te\/st/mi'`,
		`te/st
`)
	shouldExit(t, `echo '1' | xo '/^(\s)/$1/'`, 1)
	shouldExit(t, `echo '1' | xo '/1/'`, 1)
	shouldExit(t, `echo '1' | xo ///`, 1)
	shouldExit(t, `xo ///`, 1)
}

func TestSplit(t *testing.T) {
	tests := map[string][]string{
		`%bc%b\%%`:    []string{"bc", "b%"},
		`⌘abc⌘bca⌘`:   []string{"abc", "bca"},
		`⌘abc⌘bca⌘\⌘`: []string{"abc", "bca", "⌘"},
		`\bc\bc\`:     []string{"bc", "bc"},
		`\b\\c\bc\`:   []string{`b\c`, `bc`},
		`[\[xy[xy[`:   []string{"[xy", "xy"},
		`[\\[xy[xy[`:  []string{`\[xy`, "xy"},
		`[\\[xy[xy[i`: []string{`\[xy`, "xy", "i"},
		`///`:         []string{},
		`///a`:        []string{"a"},
		``:            []string{},
	}
outer:
	for test, expected := range tests {
		actual, err := split(test)
		if err != nil {
			t.Logf("Error on split(%q)\n", test)
			continue
		}

		if len(actual) != len(expected) {
			t.Logf("Test: %q. Actual: %v, Expected: %v\n", test, actual, expected)
			continue
		}

		for i := range actual {
			if actual[i] != expected[i] {
				t.Logf("Test: %q. Actual: %v, Expected: %v\n", test, actual, expected)
				continue outer
			}
		}
	}
}

func execShellCommand(t *testing.T, cmd string) string {
	out, err := exec.Command("bash", "-c", cmd).Output()
	if err != nil {
		t.Fatalf(err.Error())
	}
	return string(out)
}

func shouldEqual(t *testing.T, cmd string, expected string) {
	result := execShellCommand(t, cmd)
	if result != expected {
		t.Fatalf("`%s` should be `%s`", result, expected)
	}
}

func shouldExit(t *testing.T, cmd string, expected int) {
	c := exec.Command("bash", "-c", cmd)
	stderr := &bytes.Buffer{}
	c.Stderr = stderr
	if err := c.Run(); err != nil {
		code := 0
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				code = status.ExitStatus()
			}
		}
		if code != expected {
			t.Fatalf("exit status `%d` should be `%d`", code, expected)
		}
	} else {
		t.Fatalf("command `%s` failed to spawn", cmd)
	}
}
<commit_msg>clean up from pull request<commit_after>package main

import (
	"bytes"
	"os/exec"
	"syscall"
	"testing"
)

func TestMain(t *testing.T) {
	shouldEqual(t, `xo`,
		`Usage: xo '/<pattern>/<formatter>/[flags]'
`)
	shouldEqual(t, `echo 'Hello there!' | xo '~hello(.*)~Hi$1~i'`,
		`Hi there!
`)
	shouldEqual(t, `echo 'Hello! - Luke' | xo '/(hello).*?-.*?(\w+)/Why $1, $2!/i'`,
		`Why Hello, Luke!
`)
	shouldEqual(t, `cat fixtures/servers.yml | xo '/.*?(production):\s*server:\s+([^:\n]+):?(\d+)?.*?user:\s+([^\n]+).*/$4@$2 -p $3?:22/mis'`,
		`user-1@192.168.1.1 -p 1234
`)
	shouldEqual(t, `cat fixtures/starwars.txt | xo '/^(\w+):(\s*\[(.*?)\]\s*)?\s*([^\n]+)/$1 said, "$4" in a $3?:normal voice./mi'`,
		`Vader said, "If only you knew the power of the Dark Side. Obi-Wan never told you what happened to your father." in a normal voice.
Luke said, "He told me enough! He told me you killed him!" in a normal voice.
Vader said, "No, I am your father." in a normal voice.
Luke said, "No. No! That's not true! That's impossible!" in a shocked voice.
`)
	shouldEqual(t, `echo '123' | xo '/(\d)(\d)(\d)(\d)?(\d)?/$1, $2, $3, 4?:FOUR $5?:FIVE/'`,
		`1, 2, 3, 4?:FOUR FIVE
`)
	shouldEqual(t, `echo 'abc' | xo '%(\w)(\w)(\w)(\w)?%$1$2$3$4?:$1%'`,
		`abca
`)
	shouldEqual(t, `echo 'Hello! My name is C3PO, human cyborg relations.' | xo '/^((\w+)! )?my name is (\w+)/$2?:Hello, $3!/i'`,
		`Hello, C3PO!
`)
	shouldEqual(t, `echo 'My name is Chewbacca, uuuuuur ahhhhhrrr uhrrr ahhhrrr aaargh!' | xo '|^((\w+)! )?my name is (\w+)|$2?:Greetings, $3!|i'`,
		`Greetings, Chewbacca!
`)
	shouldEqual(t, `cat fixtures/romans.txt | xo '/\d\s(\w+).*?to all that are in (\w+),.*?24 \[the (grace)? of ([\w\s]{21})/Romans is a letter written by $1 addressed to the people of $2 about the $3?:gospel of $4./mis'`,
		`Romans is a letter written by Paul addressed to the people of Rome about the grace of our Lord Jesus Christ.
`)
	shouldEqual(t, `echo 'hi' | xo '/(hi)/te\/st/mi'`,
		`te/st
`)
	shouldExit(t, `echo '1' | xo '/^(\s)/$1/'`, 1)
	shouldExit(t, `echo '1' | xo '/1/'`, 1)
	shouldExit(t, `echo '1' | xo ///`, 1)
	shouldExit(t, `xo ///`, 1)
}

func TestSplit(t *testing.T) {
	tests := map[string][]string{
		`%bc%b\%%`:    []string{"bc", "b%"},
		`⌘abc⌘bca⌘`:   []string{"abc", "bca"},
		`⌘abc⌘bca⌘\⌘`: []string{"abc", "bca", "⌘"},
		`\bc\bc\`:     []string{"bc", "bc"},
		`\b\\c\bc\`:   []string{`b\c`, `bc`},
		`[\[xy[xy[`:   []string{"[xy", "xy"},
		`[\\[xy[xy[`:  []string{`\[xy`, "xy"},
		`[\\[xy[xy[i`: []string{`\[xy`, "xy", "i"},
		`///`:         []string{},
		`///a`:        []string{"a"},
		``:            []string{},
	}
outer:
	for test, expected := range tests {
		actual, err := split(test)
		if err != nil {
			t.Fatalf("failed to split `%q`\n", test)
			continue
		}

		if len(actual) != len(expected) {
			t.Fatalf("`%v` should be `%v` for `%q`\n", actual, expected, test)
			continue
		}

		for i := range actual {
			if actual[i] != expected[i] {
				t.Fatalf("`%v` should be `%v` for `%q`\n", actual, expected, test)
				continue outer
			}
		}
	}
}

func execShellCommand(t *testing.T, cmd string) string {
	out, err := exec.Command("bash", "-c", cmd).Output()
	if err != nil {
		t.Fatalf("error: %s", err.Error())
	}
	return string(out)
}

func shouldEqual(t *testing.T, cmd string, expected string) {
	result := execShellCommand(t, cmd)
	if result != expected {
		t.Fatalf("`%s` should be `%s`", result, expected)
	}
}

func shouldExit(t *testing.T, cmd string, expected int) {
	c := exec.Command("bash", "-c", cmd)
	stderr := &bytes.Buffer{}
	c.Stderr = stderr
	if err := c.Run(); err != nil {
		code := 0
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				code = status.ExitStatus()
			}
		}
		if code != expected {
			t.Fatalf("exit status `%d` should be `%d`", code, expected)
		}
	} else {
		t.Fatalf("command `%s` failed to spawn", cmd)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"

	"github.com/drone/drone-plugin-go/plugin"
)

// commits is a list of commits of different types (push, pull request, tag)
// to help us verify that this clone plugin can handle multiple commit types.
var commits = []struct {
	path       string
	clone      string
	event      string
	branch     string
	commit     string
	ref        string
	file       string
	data       string
	tags       []string
	submodules map[string]string
}{
	// first commit
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPush,
		branch:     "master",
		commit:     "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
		ref:        "refs/heads/master",
		file:       "README",
		data:       "Hello World!",
		tags:       nil,
		submodules: nil,
	},
	// head commit
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPush,
		branch:     "master",
		commit:     "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
		ref:        "refs/heads/master",
		file:       "README",
		data:       "Hello World!\n",
		tags:       nil,
		submodules: nil,
	},
	// pull request commit
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPull,
		branch:     "master",
		commit:     "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
		ref:        "refs/pull/208/merge",
		file:       "README",
		data:       "Goodbye World!\n",
		tags:       nil,
		submodules: nil,
	},
	// branch
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPush,
		branch:     "test",
		commit:     "b3cbd5bbd7e81436d2eee04537ea2b4c0cad4cdf",
		ref:        "refs/heads/test",
		file:       "CONTRIBUTING.md",
		data:       "## Contributing\n",
		tags:       nil,
		submodules: nil,
	},
	// tags
	{
		path:   "github/mime-types",
		clone:  "https://github.com/github/mime-types.git",
		event:  plugin.EventTag,
		branch: "master",
		commit: "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
		ref:    "refs/tags/v1.17",
		file:   ".gitignore",
		data:   "*.swp\n*~\n.rake_tasks~\nhtml\ndoc\npkg\npublish\ncoverage\n",
		tags: []string{
			"v1.16",
			"v1.17",
			"v1.17.1",
			"v1.17.2",
			"v1.18",
			"v1.19",
			"v1.20",
			"v1.20.1",
			"v1.21",
			"v1.22",
			"v1.23",
		},
		submodules: nil,
	},
	// submodules
	{
		path:   "msteinert/drone-git-test-submodule",
		clone:  "https://github.com/msteinert/drone-git-test-submodule.git",
		event:  plugin.EventPush,
		branch: "master",
		commit: "072ae3ddb6883c8db653f8d4432b07c035b93753",
		ref:    "refs/heads/master",
		file:   "Hello-World/README",
		data:   "Hello World!\n",
		tags:   nil,
		submodules: map[string]string{
			"Hello-World": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
		},
	},
}

// TestClone tests the ability to clone a specific commit into
// a fresh, empty directory every time.
func TestClone(t *testing.T) {

	for _, c := range commits {
		dir := setup()

		recursive := false
		if c.submodules != nil {
			recursive = true
		}

		tags := false
		if c.tags != nil {
			tags = true
		}

		r := &plugin.Repo{Clone: c.clone}
		b := &plugin.Build{Commit: c.commit, Branch: c.branch, Ref: c.ref, Event: c.event}
		w := &plugin.Workspace{Path: dir}
		v := &Params{
			Recursive: recursive,
			Tags:      tags,
		}
		if err := clone(r, b, w, v); err != nil {
			t.Errorf("Expected successful clone. Got error. %s.", err)
		}

		data := readFile(dir, c.file)
		if data != c.data {
			t.Errorf("Expected %s to contain [%s]. Got [%s].", c.file, c.data, data)
		}

		if c.tags != nil {
			tags, err := getTags(dir)
			if err != nil {
				t.Error(err)
			}
			for _, tag := range c.tags {
				if !tags[tag] {
					t.Errorf("Expected tag [%s] to exist.", tag)
				}
			}
		}

		if c.submodules != nil {
			submodules, err := getSubmodules(dir)
			if err != nil {
				t.Error(err)
			}
			for k, v := range c.submodules {
				if submodules[k] != v {
					t.Errorf("Expected submodule [%s:%s] to exist.", k, v)
				}
			}
		}

		teardown(dir)
	}
}

// TestCloneNonEmpty tests the ability to clone a specific commit into
// a non-empty directory. This is useful if the git workspace is cached
// and re-stored for every build.
func TestCloneNonEmpty(t *testing.T) {
	dir := setup()
	defer teardown(dir)

	for _, c := range commits {

		recursive := false
		if c.submodules != nil {
			recursive = true
		}

		tags := false
		if c.tags != nil {
			tags = true
		}

		r := &plugin.Repo{Clone: c.clone}
		b := &plugin.Build{Commit: c.commit, Branch: c.branch, Ref: c.ref, Event: c.event}
		w := &plugin.Workspace{Path: filepath.Join(dir, c.path)}
		v := &Params{
			Recursive: recursive,
			Tags:      tags,
		}
		if err := clone(r, b, w, v); err != nil {
			t.Errorf("Expected successful clone. Got error. %s.", err)
			break
		}

		data := readFile(w.Path, c.file)
		if data != c.data {
			t.Errorf("Expected %s to contain [%s]. Got [%s].", c.file, c.data, data)
			break
		}

		if c.tags != nil {
			tags, err := getTags(w.Path)
			if err != nil {
				t.Error(err)
			}
			for _, tag := range c.tags {
				if !tags[tag] {
					t.Errorf("Expected tag [%s] to exist.", tag)
				}
			}
		}

		if c.submodules != nil {
			submodules, err := getSubmodules(w.Path)
			if err != nil {
				t.Error(err)
			}
			for k, v := range c.submodules {
				if submodules[k] != v {
					t.Errorf("Expected submodule [%s:%s] to exist.", k, v)
				}
			}
		}
	}
}

// TestClone tests if the arguments to `git fetch` are constructed properly.
func TestFetch(t *testing.T) {
	testdata := []struct {
		build *plugin.Build
		tags  bool
		depth int
		exp   []string
	}{
		{
			&plugin.Build{Ref: "refs/heads/master"},
			false,
			50,
			[]string{
				"git",
				"fetch",
				"--no-tags",
				"--depth=50",
				"origin",
				"+refs/heads/master:",
			},
		},
		{
			&plugin.Build{Ref: "refs/heads/master"},
			true,
			100,
			[]string{
				"git",
				"fetch",
				"--tags",
				"--depth=100",
				"origin",
				"+refs/heads/master:",
			},
		},
	}
	for _, td := range testdata {
		c := fetch(td.build, td.tags, td.depth)
		if len(c.Args) != len(td.exp) {
			t.Errorf("Expected: %s, got %s", td.exp, c.Args)
		}
		for i := range c.Args {
			if c.Args[i] != td.exp[i] {
				t.Errorf("Expected: %s, got %s", td.exp, c.Args)
			}
		}
	}
}

// TestUpdateSubmodules tests if the arguments to `git submodule update`
// are constructed properly.
func TestUpdateSubmodules(t *testing.T) {
	testdata := []struct {
		depth int
		exp   []string
	}{
		{
			50,
			[]string{
				"git",
				"submodule",
				"update",
				"--init",
				"--recursive",
			},
		},
		{
			100,
			[]string{
				"git",
				"submodule",
				"update",
				"--init",
				"--recursive",
			},
		},
	}
	for _, td := range testdata {
		c := updateSubmodules()
		if len(c.Args) != len(td.exp) {
			t.Errorf("Expected: %s, got %s", td.exp, c.Args)
		}
		for i := range c.Args {
			if c.Args[i] != td.exp[i] {
				t.Errorf("Expected: %s, got %s", td.exp, c.Args)
			}
		}
	}
}

// helper function that will setup a temporary workspace.
// to which we can clone the repositroy
func setup() string {
	dir, _ := ioutil.TempDir("/tmp", "drone_git_test_")
	os.Mkdir(dir, 0777)
	return dir
}

// helper function to delete the temporary workspace.
func teardown(dir string) {
	os.RemoveAll(dir)
}

// helper function to read a file in the temporary worskapce.
func readFile(dir, file string) string {
	filename := filepath.Join(dir, file)
	data, _ := ioutil.ReadFile(filename)
	return string(data)
}

// getTags returns all of the tags in a git repository as a map.
func getTags(dir string) (map[string]bool, error) {
	cmd := exec.Command("git", "tag")
	cmd.Dir = dir
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	tags := make(map[string]bool)
	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		tags[scanner.Text()] = true
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	if err := cmd.Wait(); err != nil {
		return nil, err
	}
	return tags, nil
}

// getSubmodules returns all of the submodules in a git repository as a map.
func getSubmodules(dir string) (map[string]string, error) {
	cmd := exec.Command("git", "submodule", "status")
	cmd.Dir = dir
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	submodules := make(map[string]string)
	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		a := strings.Split(strings.TrimSpace(scanner.Text()), " ")
		submodules[a[1]] = a[0]
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	if err := cmd.Wait(); err != nil {
		return nil, err
	}
	return submodules, nil
}
<commit_msg>add a test<commit_after>package main

import (
	"bufio"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"

	"github.com/drone/drone-plugin-go/plugin"
)

// commits is a list of commits of different types (push, pull request, tag)
// to help us verify that this clone plugin can handle multiple commit types.
var commits = []struct {
	path       string
	clone      string
	event      string
	branch     string
	commit     string
	ref        string
	file       string
	data       string
	tags       []string
	submodules map[string]string
}{
	// first commit
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPush,
		branch:     "master",
		commit:     "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
		ref:        "refs/heads/master",
		file:       "README",
		data:       "Hello World!",
		tags:       nil,
		submodules: nil,
	},
	// head commit
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPush,
		branch:     "master",
		commit:     "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
		ref:        "refs/heads/master",
		file:       "README",
		data:       "Hello World!\n",
		tags:       nil,
		submodules: nil,
	},
	// pull request commit
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPull,
		branch:     "master",
		commit:     "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
		ref:        "refs/pull/208/merge",
		file:       "README",
		data:       "Goodbye World!\n",
		tags:       nil,
		submodules: nil,
	},
	// branch
	{
		path:       "octocat/Hello-World",
		clone:      "https://github.com/octocat/Hello-World.git",
		event:      plugin.EventPush,
		branch:     "test",
		commit:     "b3cbd5bbd7e81436d2eee04537ea2b4c0cad4cdf",
		ref:        "refs/heads/test",
		file:       "CONTRIBUTING.md",
		data:       "## Contributing\n",
		tags:       nil,
		submodules: nil,
	},
	// tags
	{
		path:   "github/mime-types",
		clone:  "https://github.com/github/mime-types.git",
		event:  plugin.EventTag,
		branch: "master",
		commit: "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
		ref:    "refs/tags/v1.17",
		file:   ".gitignore",
		data:   "*.swp\n*~\n.rake_tasks~\nhtml\ndoc\npkg\npublish\ncoverage\n",
		tags: []string{
			"v1.16",
			"v1.17",
			"v1.17.1",
			"v1.17.2",
			"v1.18",
			"v1.19",
			"v1.20",
			"v1.20.1",
			"v1.21",
			"v1.22",
			"v1.23",
		},
		submodules: nil,
	},
	// submodules
	{
		path:   "msteinert/drone-git-test-submodule",
		clone:  "https://github.com/msteinert/drone-git-test-submodule.git",
		event:  plugin.EventPush,
		branch: "master",
		commit: "072ae3ddb6883c8db653f8d4432b07c035b93753",
		ref:    "refs/heads/master",
		file:   "Hello-World/README",
		data:   "Hello World!\n",
		tags:   nil,
		submodules: map[string]string{
			"Hello-World": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
		},
	},
}

// TestClone tests the ability to clone a specific commit into
// a fresh, empty directory every time.
func TestClone(t *testing.T) {

	for _, c := range commits {
		dir := setup()

		recursive := false
		if c.submodules != nil {
			recursive = true
		}

		tags := false
		if c.tags != nil {
			tags = true
		}

		r := &plugin.Repo{Clone: c.clone}
		b := &plugin.Build{Commit: c.commit, Branch: c.branch, Ref: c.ref, Event: c.event}
		w := &plugin.Workspace{Path: dir}
		v := &Params{
			Recursive: recursive,
			Tags:      tags,
		}
		if err := clone(r, b, w, v); err != nil {
			t.Errorf("Expected successful clone. Got error. %s.", err)
		}

		data := readFile(dir, c.file)
		if data != c.data {
			t.Errorf("Expected %s to contain [%s]. Got [%s].", c.file, c.data, data)
		}

		if c.tags != nil {
			tags, err := getTags(dir)
			if err != nil {
				t.Error(err)
			}
			for _, tag := range c.tags {
				if !tags[tag] {
					t.Errorf("Expected tag [%s] to exist.", tag)
				}
			}
		}

		if c.submodules != nil {
			submodules, err := getSubmodules(dir)
			if err != nil {
				t.Error(err)
			}
			for k, v := range c.submodules {
				if submodules[k] != v {
					t.Errorf("Expected submodule [%s:%s] to exist.", k, v)
				}
			}
		}

		teardown(dir)
	}
}

// TestCloneNonEmpty tests the ability to clone a specific commit into
// a non-empty directory. This is useful if the git workspace is cached
// and re-stored for every build.
func TestCloneNonEmpty(t *testing.T) {
	dir := setup()
	defer teardown(dir)

	for _, c := range commits {

		recursive := false
		if c.submodules != nil {
			recursive = true
		}

		tags := false
		if c.tags != nil {
			tags = true
		}

		r := &plugin.Repo{Clone: c.clone}
		b := &plugin.Build{Commit: c.commit, Branch: c.branch, Ref: c.ref, Event: c.event}
		w := &plugin.Workspace{Path: filepath.Join(dir, c.path)}
		v := &Params{
			Recursive: recursive,
			Tags:      tags,
		}
		if err := clone(r, b, w, v); err != nil {
			t.Errorf("Expected successful clone. Got error. %s.", err)
			break
		}

		data := readFile(w.Path, c.file)
		if data != c.data {
			t.Errorf("Expected %s to contain [%s]. Got [%s].", c.file, c.data, data)
			break
		}

		if c.tags != nil {
			tags, err := getTags(w.Path)
			if err != nil {
				t.Error(err)
			}
			for _, tag := range c.tags {
				if !tags[tag] {
					t.Errorf("Expected tag [%s] to exist.", tag)
				}
			}
		}

		if c.submodules != nil {
			submodules, err := getSubmodules(w.Path)
			if err != nil {
				t.Error(err)
			}
			for k, v := range c.submodules {
				if submodules[k] != v {
					t.Errorf("Expected submodule [%s:%s] to exist.", k, v)
				}
			}
		}
	}
}

// TestClone tests if the arguments to `git fetch` are constructed properly.
func TestFetch(t *testing.T) {
	testdata := []struct {
		build *plugin.Build
		tags  bool
		depth int
		exp   []string
	}{
		{
			&plugin.Build{Ref: "refs/heads/master"},
			false,
			50,
			[]string{
				"git",
				"fetch",
				"--no-tags",
				"--depth=50",
				"origin",
				"+refs/heads/master:",
			},
		},
		{
			&plugin.Build{Ref: "refs/heads/master"},
			true,
			100,
			[]string{
				"git",
				"fetch",
				"--tags",
				"--depth=100",
				"origin",
				"+refs/heads/master:",
			},
		},
	}
	for _, td := range testdata {
		c := fetch(td.build, td.tags, td.depth)
		if len(c.Args) != len(td.exp) {
			t.Errorf("Expected: %s, got %s", td.exp, c.Args)
		}
		for i := range c.Args {
			if c.Args[i] != td.exp[i] {
				t.Errorf("Expected: %s, got %s", td.exp, c.Args)
			}
		}
	}
}

// TestUpdateSubmodules tests if the arguments to `git submodule update`
// are constructed properly.
func TestUpdateSubmodules(t *testing.T) {
	testdata := []struct {
		depth int
		exp   []string
	}{
		{
			50,
			[]string{
				"git",
				"submodule",
				"update",
				"--init",
				"--recursive",
			},
		},
		{
			100,
			[]string{
				"git",
				"submodule",
				"update",
				"--init",
				"--recursive",
			},
		},
	}
	for _, td := range testdata {
		c := updateSubmodules(false)
		if len(c.Args) != len(td.exp) {
			t.Errorf("Expected: %s, got %s", td.exp, c.Args)
		}
		for i := range c.Args {
			if c.Args[i] != td.exp[i] {
				t.Errorf("Expected: %s, got %s", td.exp, c.Args)
			}
		}
	}
}

// TestUpdateSubmodules tests if the arguments to `git submodule update`
// are constructed properly.
func TestUpdateSubmodulesRemote(t *testing.T) {
	testdata := []struct {
		depth int
		exp   []string
	}{
		{
			50,
			[]string{
				"git",
				"submodule",
				"update",
				"--init",
				"--recursive",
				"--remote",
			},
		},
		{
			100,
			[]string{
				"git",
				"submodule",
				"update",
				"--init",
				"--recursive",
				"--remote",
			},
		},
	}
	for _, td := range testdata {
		c := updateSubmodules(true)
		if len(c.Args) != len(td.exp) {
			t.Errorf("Expected: %s, got %s", td.exp, c.Args)
		}
		for i := range c.Args {
			if c.Args[i] != td.exp[i] {
				t.Errorf("Expected: %s, got %s", td.exp, c.Args)
			}
		}
	}
}

// helper function that will setup a temporary workspace.
// to which we can clone the repositroy
func setup() string {
	dir, _ := ioutil.TempDir("/tmp", "drone_git_test_")
	os.Mkdir(dir, 0777)
	return dir
}

// helper function to delete the temporary workspace.
func teardown(dir string) {
	os.RemoveAll(dir)
}

// helper function to read a file in the temporary worskapce.
func readFile(dir, file string) string {
	filename := filepath.Join(dir, file)
	data, _ := ioutil.ReadFile(filename)
	return string(data)
}

// getTags returns all of the tags in a git repository as a map.
func getTags(dir string) (map[string]bool, error) {
	cmd := exec.Command("git", "tag")
	cmd.Dir = dir
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	tags := make(map[string]bool)
	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		tags[scanner.Text()] = true
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	if err := cmd.Wait(); err != nil {
		return nil, err
	}
	return tags, nil
}

// getSubmodules returns all of the submodules in a git repository as a map.
func getSubmodules(dir string) (map[string]string, error) {
	cmd := exec.Command("git", "submodule", "status")
	cmd.Dir = dir
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	submodules := make(map[string]string)
	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		a := strings.Split(strings.TrimSpace(scanner.Text()), " ")
		submodules[a[1]] = a[0]
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	if err := cmd.Wait(); err != nil {
		return nil, err
	}
	return submodules, nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

// When the environment variable RUN_AS_PROTOC_GEN_GO is set, we skip running
// tests and instead act as protoc-gen-go. This allows the test binary to
// pass itself to protoc.
func init() {
	if os.Getenv("RUN_AS_PROTOC_GEN_GO") != "" {
		main()
		os.Exit(0)
	}
}

func TestGolden(t *testing.T) {
	workdir, err := ioutil.TempDir("", "protoc-gen-gohttp-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(workdir)

	// find all proto file in testdata.
	packages := map[string][]string{}
	if err := filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
		if !strings.HasSuffix(path, ".proto") {
			return nil
		}

		dir := filepath.Dir(path)
		packages[dir] = append(packages[dir], path)
		return nil
	}); err != nil {
		t.Fatal(err)
	}

	// generate gohttp files.
	for _, sources := range packages {
		args := []string{"--gohttp_out=" + workdir}
		args = append(args, sources...)
		protoc(t, args)
	}
}

func protoc(t *testing.T, args []string) {
	cmd := exec.Command("protoc", "--plugin=protoc-gen-gohttp="+os.Args[0])
	cmd.Args = append(cmd.Args, args...)
	// We set the RUN_AS_PROTOC_GEN_GO environment variable to indicate that
	// the subprocess should act as a proto compiler rather than a test.
	cmd.Env = append(os.Environ(), "RUN_AS_PROTOC_GEN_GO=1")
	out, err := cmd.CombinedOutput()
	if len(out) > 0 || err != nil {
		t.Log("RUNNING: ", strings.Join(cmd.Args, " "))
	}
	if len(out) > 0 {
		t.Log(string(out))
	}
	if err != nil {
		t.Fatalf("protoc: %v", err)
	}
}
<commit_msg>Walked all generated files<commit_after>package main

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

// When the environment variable RUN_AS_PROTOC_GEN_GO is set, we skip running
// tests and instead act as protoc-gen-go. This allows the test binary to
// pass itself to protoc.
func init() {
	if os.Getenv("RUN_AS_PROTOC_GEN_GO") != "" {
		main()
		os.Exit(0)
	}
}

func TestGolden(t *testing.T) {
	workdir, err := ioutil.TempDir("", "protoc-gen-gohttp-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(workdir)

	// Find all the proto files in testdata.
	packages := map[string][]string{}
	if err := filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
		if !strings.HasSuffix(path, ".proto") {
			return nil
		}

		dir := filepath.Dir(path)
		packages[dir] = append(packages[dir], path)

		return nil
	}); err != nil {
		t.Fatal(err)
	}

	// Compile each package, using this binary as protoc-gen-gohttp.
	for _, sources := range packages {
		args := []string{"--gohttp_out=" + workdir}
		args = append(args, sources...)
		protoc(t, args)
	}

	// Compare each generated file to the golden version.
	if err := filepath.Walk(workdir, func(path string, info os.FileInfo, _ error) error {
		t.Log(path)
		if info.IsDir() {
			return nil
		}
		return nil
	}); err != nil {
		t.Fatal(err)
	}
}

func protoc(t *testing.T, args []string) {
	cmd := exec.Command("protoc", "--plugin=protoc-gen-gohttp="+os.Args[0])
	cmd.Args = append(cmd.Args, args...)
	// We set the RUN_AS_PROTOC_GEN_GO environment variable to indicate that
	// the subprocess should act as a proto compiler rather than a test.
	cmd.Env = append(os.Environ(), "RUN_AS_PROTOC_GEN_GO=1")
	out, err := cmd.CombinedOutput()
	if len(out) > 0 || err != nil {
		t.Log("RUNNING: ", strings.Join(cmd.Args, " "))
	}
	if len(out) > 0 {
		t.Log(string(out))
	}
	if err != nil {
		t.Fatalf("protoc: %v", err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Jacob Taylor jacob@ablox.io
// License: Apache2 - http://www.apache.org/licenses/LICENSE-2.0
package main

import (
	"testing"
	"os"
	"fmt"
	"io/ioutil"
)

func TestDirectoryScan(t *testing.T) {
	tmpFolder, err := ioutil.TempDir("", "blank")
	defer os.RemoveAll(tmpFolder)
	emptyState, err := createListOfFolders(tmpFolder)
	if err != nil {
		t.Fail()
	}

	// Create 5 folders
	numberOfSubFolders := 5
	newFolders := make([]string, 0, numberOfSubFolders)
	for i:=0; i < numberOfSubFolders; i++ {
		path := fmt.Sprintf("%s/a%d", tmpFolder, i)
		newFolders = append(newFolders, path)
		err = os.Mkdir(path, os.ModeDir + os.ModePerm)
		if err != nil {
			t.Fatal(err)
		}
	}

	totalFolders := numberOfSubFolders + 1
	dirState, err := createListOfFolders(tmpFolder)
	if len(dirState) != totalFolders {
		t.Fatalf("Unexpected Number of items in state. Expected %d, found %d\n", totalFolders, len(dirState))
		t.Fail()
	}

	changed, updatedState, newPaths, deletedPaths, matchingPaths := checkForChanges(tmpFolder, dirState)
	if changed || (len(newPaths) + len(deletedPaths) + len(matchingPaths) != totalFolders) {
		t.Fatal("comparision of current state with current state did not result in empty....ouch\n")
		t.Fail()
	}

	assertEqualsTwoDirTreeMap(t, dirState, updatedState)

	//changed, updatedState, newPaths, deletedPaths, matchingPaths := checkForChanges(globalSettings.Directory, emptyState)

	_ = emptyState
}

func assertEqualsTwoDirTreeMap(t *testing.T, first, second DirTreeMap) {
	if len(first) != len(second) {
		t.Fatal("inconsistent tree lengths")
		t.Fail()
	}
	//todo continue to do the rest of the tests
}<commit_msg>adding some test todos<commit_after>// Copyright 2016 Jacob Taylor jacob@ablox.io
// License: Apache2 - http://www.apache.org/licenses/LICENSE-2.0
package main

import (
	"testing"
	"os"
	"fmt"
	"io/ioutil"
)

func TestDirectoryScan(t *testing.T) {
	tmpFolder, err := ioutil.TempDir("", "blank")
	defer os.RemoveAll(tmpFolder)
	emptyState, err := createListOfFolders(tmpFolder)
	if err != nil {
		t.Fail()
	}

	// Create 5 folders
	numberOfSubFolders := 5
	newFolders := make([]string, 0, numberOfSubFolders)
	for i:=0; i < numberOfSubFolders; i++ {
		path := fmt.Sprintf("%s/a%d", tmpFolder, i)
		newFolders = append(newFolders, path)
		err = os.Mkdir(path, os.ModeDir + os.ModePerm)
		if err != nil {
			t.Fatal(err)
		}
	}

	totalFolders := numberOfSubFolders + 1
	dirState, err := createListOfFolders(tmpFolder)
	if len(dirState) != totalFolders {
		t.Fatalf("Unexpected Number of items in state. Expected %d, found %d\n", totalFolders, len(dirState))
		t.Fail()
	}

	changed, updatedState, newPaths, deletedPaths, matchingPaths := checkForChanges(tmpFolder, dirState)
	if changed || (len(newPaths) + len(deletedPaths) + len(matchingPaths) != totalFolders) {
		t.Fatal("comparision of current state with current state did not result in empty....ouch\n")
		t.Fail()
	}

	assertEqualsTwoDirTreeMap(t, dirState, updatedState)

	//changed, updatedState, newPaths, deletedPaths, matchingPaths := checkForChanges(globalSettings.Directory, emptyState)

	// todo make some changes and verify that it is working correctly.
	// add paths
	// a, b, c, d, e, ab,abc,abd
	// delete ab and make sure it is the only one deleted
	// delete the start and end ones
	// recreate them

	_ = emptyState
}

func assertEqualsTwoDirTreeMap(t *testing.T, first, second DirTreeMap) {
	if len(first) != len(second) {
		t.Fatal("inconsistent tree lengths")
		t.Fail()
	}
	//todo continue to do the rest of the tests
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestCheck(t *testing.T) {

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{"can_i_bump": true }`)
	}))
	defer ts.Close()

	ok := check(ts.URL)
	if !ok {
		t.Fail()
	}

}

func TestCheckFail(t *testing.T) {

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{"can_i_bump": false }`)
	}))
	defer ts.Close()

	ok := check(ts.URL)
	if ok {
		t.Fail()
	}
}
<commit_msg>dry up test<commit_after>package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
)

func newTestServer(resp string) *httptest.Server {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, resp)
	}))
	return ts
}

func TestCheck(t *testing.T) {
	ts := newTestServer(`{"can_i_bump": true }`)
	defer ts.Close()

	ok := check(ts.URL)
	if !ok {
		t.Fail()
	}

}

func TestCheckCantBump(t *testing.T) {
	ts := newTestServer(`{"can_i_bump": false }`)
	defer ts.Close()

	ok := check(ts.URL)
	if ok {
		t.Fail()
	}
}
<|endoftext|>


<commit_before>package main_test

import (
	"testing"
)

func TestGet400OnNewDrillRoute(t *testing.T) {

}<commit_msg>added initial code to test TestGet400OnNewDrillRoute<commit_after>package main_test

import (
	"testing"
	"net/http"
)

func TestGet400OnNewDrillRoute(t *testing.T) {
	_, err := http.NewRequest("GET", "/drills/new", nil)
	if err != nil {
    t.Fatal("Creating 'GET /questions/1/SC' request failed!")
  }
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"

	capnp "zombiezen.com/go/capnproto2"

	. "github.com/smartystreets/goconvey/convey"

	"github.com/gorilla/mux"
)

/*

Due to composition it simply means that given an API Key, when it is delegated, the parent scope is always evaluated first
therefor when the new scope is evaluated it must be further defined than the parent otherwise it would not get evaluated

WIN, WIN, WIN, WIN!!

*/

const apiPort = 50000
const rpcPort = 60000

var rpcAddr = fmt.Sprintf(":%d", rpcPort)

func CreateKeyStore() keyStore {
	var key = "unsecure_key_number_1"
	msg, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))
	scope, _ := NewRootHTTPProxyScope(seg)
	scope.SetPath("Bang Bang")
	textList, _ := capnp.NewTextList(seg, 1)
	textList.Set(0, "GET")
	scope.SetVerbs(textList)

	byteValue, _ := msg.Marshal()

	keyStore := inProcessKeyStore{
		keys: map[string][]byte{
			key: byteValue,
		},
	}

	return keyStore
}

func StartAPISecurityGateway(keyStore keyStore) {
	serverListener, _ := net.Listen("tcp", rpcAddr)
	upStreamURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", apiPort))
	var gateway = apiSecurityGateway{
		upStream: *upStreamURL,
		keyStore: keyStore,
	}
	go gateway.start(serverListener)
}

func CreateAPISecurityGatewayProxy() apiSecurityGatewayProxy {
	var gatewayProxy = apiSecurityGatewayProxy{
		upStream: rpcAddr,
	}

	return gatewayProxy

}

func TestSomething(t *testing.T) {
	Convey("Does something", t, func() {

		Convey("Test Routing", func() {
			req, _ := http.NewRequest("GET", "http://localhost:3000/fubar/2", nil)
			r := mux.NewRouter()
			r.Path("/fubar/{id:(1|2)}")
			var match mux.RouteMatch
			result := r.Match(req, &match)

			So(result, ShouldEqual, true)
		})

		Convey("Request", func() {
			keyStore := CreateKeyStore()
			StartAPISecurityGateway(keyStore)

			gatewayProxy := CreateAPISecurityGatewayProxy()
			ts := httptest.NewServer(gatewayProxy.handler())
			defer ts.Close()

			endpoint := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				w.WriteHeader(200)
				fmt.Fprintln(w, "You Made It!")
			}))
			defer endpoint.Close()

			//Set a key without restriction
			Convey("without restriction", func() {

				client := &http.Client{}
				req, _ := http.NewRequest("GET", endpoint.URL, nil)
				req.Header.Add("If-None-Match", `W/"wyzzy"`)
				resp, _ := client.Do(req)

				defer resp.Body.Close()
				body, _ := ioutil.ReadAll(resp.Body)
				So(string(body), ShouldEqual, "You Made It!\n")
			})
		})

		Convey("Delegation", func() {
			Convey("From an ALL powerful master", func() {
				/*
					json := `{
						"paths" : ["/fubar/:id"]
						"pathValues" : {
							"id" : "(1|2)"
						}
					}`

					client := &http.Client{}

					req, err := http.NewRequest("GET", "http://example.com", nil)
					req.Header.Add("If-None-Match", `W/"wyzzy"`)
					resp, err := client.Do(req)
				*/
			})
		})
	})
}
<commit_msg>refactoring tests<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"

	capnp "zombiezen.com/go/capnproto2"

	. "github.com/smartystreets/goconvey/convey"

	"github.com/gorilla/mux"
)

/*

Due to composition it simply means that given an API Key, when it is delegated, the parent scope is always evaluated first
therefor when the new scope is evaluated it must be further defined than the parent otherwise it would not get evaluated

WIN, WIN, WIN, WIN!!

*/

const apiPort = 50000
const rpcPort = 60000

var rpcAddr = fmt.Sprintf(":%d", rpcPort)

func CreateKeyStore() keyStore {
	var key = "unsecure_key_number_1"
	msg, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))
	scope, _ := NewRootHTTPProxyScope(seg)
	scope.SetPath("Bang Bang")
	textList, _ := capnp.NewTextList(seg, 1)
	textList.Set(0, "GET")
	scope.SetVerbs(textList)

	byteValue, _ := msg.Marshal()

	keyStore := inProcessKeyStore{
		keys: map[string][]byte{
			key: byteValue,
		},
	}

	return keyStore
}

func StartAPISecurityGateway(keyStore keyStore) {
	serverListener, _ := net.Listen("tcp", rpcAddr)
	upStreamURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", apiPort))
	var gateway = apiSecurityGateway{
		upStream: *upStreamURL,
		keyStore: keyStore,
	}
	go gateway.start(serverListener)
}

func CreateAPISecurityGatewayProxy() *httptest.Server {
	var gatewayProxy = apiSecurityGatewayProxy{
		upStream: rpcAddr,
	}

	ts := httptest.NewUnstartedServer(gatewayProxy.handler())
	return ts
}

func CreateFakeEndpoint() *httptest.Server {
	server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(200)
		fmt.Fprintln(w, "You Made It!")
	}))
	return server
}

func TestSomething(t *testing.T) {
	Convey("Does something", t, func() {

		Convey("Test my knowledge of MUX", func() {
			req, _ := http.NewRequest("GET", "http://localhost:3000/fubar/2", nil)
			r := mux.NewRouter()
			r.Path("/fubar/{id:(1|2)}")
			var match mux.RouteMatch
			result := r.Match(req, &match)

			So(result, ShouldEqual, true)
		})

		Convey("Request", func() {
			keyStore := CreateKeyStore()
			StartAPISecurityGateway(keyStore)

			gatewayProxy := CreateAPISecurityGatewayProxy()
			defer gatewayProxy.Close()
			gatewayProxy.Start()

			fakeEndpoint := CreateFakeEndpoint()
			defer fakeEndpoint.Close()
			fakeEndpoint.Start()

			//Set a key without restriction
			Convey("without restriction", func() {

				client := &http.Client{}
				req, _ := http.NewRequest("GET", fakeEndpoint.URL, nil)
				req.Header.Add("If-None-Match", `W/"wyzzy"`)
				resp, _ := client.Do(req)

				defer resp.Body.Close()
				body, _ := ioutil.ReadAll(resp.Body)
				So(string(body), ShouldEqual, "You Made It!\n")
			})
		})

		Convey("Delegation", func() {
			Convey("From an ALL powerful master", func() {
				/*
					json := `{
						"paths" : ["/fubar/:id"]
						"pathValues" : {
							"id" : "(1|2)"
						}
					}`

					client := &http.Client{}

					req, err := http.NewRequest("GET", "http://example.com", nil)
					req.Header.Add("If-None-Match", `W/"wyzzy"`)
					resp, err := client.Do(req)
				*/
			})
		})
	})
}
<|endoftext|>


<commit_before>package core

import (
	"github.com/MG-RAST/AWE/lib/logger"
)

type ClientMap struct {
	RWMutex
	_map map[string]*Client
}

func NewClientMap() *ClientMap {
	cm := &ClientMap{_map: make(map[string]*Client)}
	cm.RWMutex.Init("ClientMap")
	return cm
}

func (cl *ClientMap) Add(client *Client, lock bool) {

	if lock {
		cl.LockNamed("(ClientMap) Add")
		defer cl.Unlock()
	}

	_, found := cl._map[client.Id]
	if found {
		log.Warn("Client Id % already exists.", client.Id)
	}

	cl._map[client.Id] = client

	return
}

func (cl *ClientMap) Get(client_id string, lock bool) (client *Client, ok bool, err error) {

	if lock {
		read_lock, xerr := cl.RLockNamed("Get")
		if xerr != nil {
			err = xerr
			return
		}
		defer cl.RUnlockNamed(read_lock)
	}

	client, ok = cl._map[client_id]

	return
}

func (cl *ClientMap) Delete(client_id string, lock bool) (err error) {

	if lock {
		err = cl.LockNamed("(ClientMap) Delete")
		if err != nil {
			return
		}
	}
	delete(cl._map, client_id)
	if lock {
		cl.Unlock()
		logger.Debug(3, "(ClientMap) Delete done\n")
	}

	return
}

func (cl *ClientMap) GetClientIds() (ids []string, err error) {

	read_lock, err := cl.RLockNamed("GetClientIds")
	if err != nil {
		return
	}
	defer cl.RUnlockNamed(read_lock)
	for id, _ := range cl._map {
		ids = append(ids, id)
	}

	return
}

func (cl *ClientMap) GetClients() (clients []*Client, err error) {

	clients = []*Client{}
	read_lock, err := cl.RLockNamed("GetClients")
	if err != nil {
		return
	}
	defer cl.RUnlockNamed(read_lock)
	for _, client := range cl._map {
		clients = append(clients, client)
	}

	return
}
<commit_msg>fix logger call<commit_after>package core

import (
	"github.com/MG-RAST/AWE/lib/logger"
)

type ClientMap struct {
	RWMutex
	_map map[string]*Client
}

func NewClientMap() *ClientMap {
	cm := &ClientMap{_map: make(map[string]*Client)}
	cm.RWMutex.Init("ClientMap")
	return cm
}

func (cl *ClientMap) Add(client *Client, lock bool) {

	if lock {
		cl.LockNamed("(ClientMap) Add")
		defer cl.Unlock()
	}

	_, found := cl._map[client.Id]
	if found {
		logger.Warning("Client Id % already exists.", client.Id)
	}

	cl._map[client.Id] = client

	return
}

func (cl *ClientMap) Get(client_id string, lock bool) (client *Client, ok bool, err error) {

	if lock {
		read_lock, xerr := cl.RLockNamed("Get")
		if xerr != nil {
			err = xerr
			return
		}
		defer cl.RUnlockNamed(read_lock)
	}

	client, ok = cl._map[client_id]

	return
}

func (cl *ClientMap) Delete(client_id string, lock bool) (err error) {

	if lock {
		err = cl.LockNamed("(ClientMap) Delete")
		if err != nil {
			return
		}
	}
	delete(cl._map, client_id)
	if lock {
		cl.Unlock()
		logger.Debug(3, "(ClientMap) Delete done\n")
	}

	return
}

func (cl *ClientMap) GetClientIds() (ids []string, err error) {

	read_lock, err := cl.RLockNamed("GetClientIds")
	if err != nil {
		return
	}
	defer cl.RUnlockNamed(read_lock)
	for id, _ := range cl._map {
		ids = append(ids, id)
	}

	return
}

func (cl *ClientMap) GetClients() (clients []*Client, err error) {

	clients = []*Client{}
	read_lock, err := cl.RLockNamed("GetClients")
	if err != nil {
		return
	}
	defer cl.RUnlockNamed(read_lock)
	for _, client := range cl._map {
		clients = append(clients, client)
	}

	return
}
<|endoftext|>