<commit_before>package acidic

import (
	"time"

	"github.com/smartystreets/acidic/contracts/messages"
	"log"
	"reflect"
)

type Transaction struct {
	raised    Dispatcher
	id        string
	status    uint64
	operation uint64
	started   time.Time
	updated   time.Time
	ttl       time.Duration
}

func NewTransaction(raised Dispatcher, id string, started time.Time, ttl time.Duration) *Transaction {
	return &Transaction{
		raised:    raised,
		id:        id,
		operation: 0,
		started:   started,
		updated:   started,
		ttl:       ttl,
	}
}

func (this *Transaction) Handle(message interface{}) error {
	switch message := message.(type) {

	case messages.StoreItemCommand:
		return this.handleStoreItem(message)
	case messages.DeleteItemCommand:
		return this.handleDeleteItem(message)
	case messages.ItemStoredEvent, messages.ItemDeletedEvent:
		return this.handleWriteCompleted(message)
	case messages.ItemStoreFailedEvent, messages.ItemDeleteFailedEvent:
		return this.handleWriteFailed(message)

	case messages.CommitTransactionCommand:
		return this.handleCommitTransaction(message)
	case messages.TransactionCommittedEvent:
		return this.handleTransactionCommitted(message)
	case messages.TransactionCommitFailedEvent:
		return this.handleTransactionCommitFailed(message)

	case messages.AbortTransactionCommand:
		return this.handleAbortTransaction(message)

	default:
		log.Panicf("Unknown message type: %s", reflect.TypeOf(message).Name())
		return nil
	}
}

func (this *Transaction) handleStoreItem(message messages.StoreItemCommand) error {
	if this.status == txAborted || this.status == txFailed || this.status == txCommitted {
		log.Panicf("Invalid state")
	}
	//if this.status != txReady && this.status == this

	// if !(ready||writing), return error
	// if timed out, raise TransactionFailed and return timeout error
	// concurrency: check outstanding map for possible failures, if so, return concurrency error
	// concurrency: if etags match, return an error that releases the context but is a success, eg. AlreadyWrittenError
	// raise StoringItemEvent
	return nil
}
func (this *Transaction) handleDeleteItem(message messages.DeleteItemCommand) error {
	// if (!ready|writing), return error
	// if timed out, raise TransactionFailed and return timeout error
	// concurrency: check outstanding map for possible concurrency issues; if so, return concurrency error
	// concurrency: if etags match, return an error that releases the context but is a success, eg. AlreadyWrittenError
	// raise DeletingItemEvent
	return nil
}
func (this *Transaction) handleWriteCompleted(message interface{}) error {
	// if (aborted|failed), return
	// if tx timed out, raise TransactionFailed+reason=TransactionTimeoutError
	// apply message
	// if state == txWritingCommitting and > 1 outstanding writes, done
	// raise TransactionCommittingEvent
	return nil
}
func (this *Transaction) handleWriteFailed(message interface{}) error {
	// if (aborted|failed), return
	// raise TransactionFailed+reason=WriteError
	return nil
}

func (this *Transaction) handleCommitTransaction(message messages.CommitTransactionCommand) error {
	// if (txAborted|txFailed), return error
	// if (txWritingCommitting, txCommitting), return nil
	// if txCommitted, return AlreadyCommittedError (which is a HTTP 200/no-op) to the caller
	// if timed out, raise TransactionFailed and return timeout error

	// if state=txWriting, raise TransactionPendingCommitEvent (which transitions to txWritingCommitting)
	// if state=txReady, raise TransactionCommittingEvent
	return nil
}
func (this *Transaction) handleTransactionCommitted(message messages.TransactionCommittedEvent) error {
	this.Apply(message)
	return nil
}
func (this *Transaction) handleTransactionCommitFailed(message messages.TransactionCommitFailedEvent) error {
	// if (txAborted|txFailed), return
	// raise TransactionFailed
	return nil
}

func (this *Transaction) handleAbortTransaction(message messages.AbortTransactionCommand) error {
	// if (txAborted), return nil
	// if (txFailed), return TransactionFailedError
	// if (txCommitted), return AlreadyCommittedError
	// if (txCommitting|txWritingCommitting), return InvalidTransitionError
	// raise TransactionAbortedEvent
	return nil
}

func (this *Transaction) Apply(message interface{}) {
	switch message := message.(type) {

	case messages.StoringItemEvent:
		this.applyStoringItem(message)
	case messages.ItemStoredEvent:
		this.applyItemStored(message)
	case messages.ItemStoreFailedEvent:
		this.applyItemStoreFailed(message)

	case messages.DeletingItemEvent:
		this.applyDeletingItem(message)
	case messages.ItemDeletedEvent:
		this.applyItemDeleted(message)
	case messages.ItemDeleteFailedEvent:
		this.applyItemDeleteFailed(message)

	case messages.TransactionCommitAwaitingWritesEvent:
		this.applyTransactionAwaitingWrites(message)
	case messages.TransactionCommittingEvent:
		this.applyTransactionCommitting(message)

	default:
		log.Panicf("Unknown message type: %s", reflect.TypeOf(message).Name())
	}
}

func (this *Transaction) applyStoringItem(message messages.StoringItemEvent) {
	this.updated = message.Timestamp

}
func (this *Transaction) applyItemStored(message messages.ItemStoredEvent) {
	this.updated = message.Timestamp
}
func (this *Transaction) applyItemStoreFailed(message messages.ItemStoreFailedEvent) {
	this.updated = message.Timestamp
}

func (this *Transaction) applyDeletingItem(message messages.DeletingItemEvent) {
	this.updated = message.Timestamp
}
func (this *Transaction) applyItemDeleted(message messages.ItemDeletedEvent) {
	this.updated = message.Timestamp
}
func (this *Transaction) applyItemDeleteFailed(message messages.ItemDeleteFailedEvent) {
	this.updated = message.Timestamp
}

func (this *Transaction) applyTransactionAwaitingWrites(message messages.TransactionCommitAwaitingWritesEvent) {
	this.updated = message.Timestamp
	this.status = txCommittingAwaitingWrites
}
func (this *Transaction) applyTransactionCommitting(message messages.TransactionCommittingEvent) {
	this.updated = message.Timestamp
}
<commit_msg>Updating status.<commit_after>package acidic

import (
	"time"

	"github.com/smartystreets/acidic/contracts/messages"
	"log"
	"reflect"
)

type Transaction struct {
	raised    Dispatcher
	id        string
	status    uint64
	operation uint64
	started   time.Time
	updated   time.Time
	ttl       time.Duration
}

func NewTransaction(raised Dispatcher, id string, started time.Time, ttl time.Duration) *Transaction {
	return &Transaction{
		raised:    raised,
		id:        id,
		operation: 0,
		started:   started,
		updated:   started,
		ttl:       ttl,
	}
}

func (this *Transaction) Handle(message interface{}) error {
	switch message := message.(type) {

	case messages.StoreItemCommand:
		return this.handleStoreItem(message)
	case messages.DeleteItemCommand:
		return this.handleDeleteItem(message)
	case messages.ItemStoredEvent, messages.ItemDeletedEvent:
		return this.handleWriteCompleted(message)
	case messages.ItemStoreFailedEvent, messages.ItemDeleteFailedEvent:
		return this.handleWriteFailed(message)

	case messages.CommitTransactionCommand:
		return this.handleCommitTransaction(message)
	case messages.TransactionCommittedEvent:
		return this.handleTransactionCommitted(message)
	case messages.TransactionCommitFailedEvent:
		return this.handleTransactionCommitFailed(message)

	case messages.AbortTransactionCommand:
		return this.handleAbortTransaction(message)

	default:
		log.Panicf("Unknown message type: %s", reflect.TypeOf(message).Name())
		return nil
	}
}

func (this *Transaction) handleStoreItem(message messages.StoreItemCommand) error {
	if this.status == txAborted || this.status == txFailed || this.status == txCommitted {
		log.Panicf("Invalid state")
	}
	//if this.status != txReady && this.status == this

	// if !(ready||writing), return error
	// if timed out, raise TransactionFailed and return timeout error
	// concurrency: check outstanding map for possible failures, if so, return concurrency error
	// concurrency: if etags match, return an error that releases the context but is a success, eg. AlreadyWrittenError
	// raise StoringItemEvent
	return nil
}
func (this *Transaction) handleDeleteItem(message messages.DeleteItemCommand) error {
	// if (!ready|writing), return error
	// if timed out, raise TransactionFailed and return timeout error
	// concurrency: check outstanding map for possible concurrency issues; if so, return concurrency error
	// concurrency: if etags match, return an error that releases the context but is a success, eg. AlreadyWrittenError
	// raise DeletingItemEvent
	return nil
}
func (this *Transaction) handleWriteCompleted(message interface{}) error {
	// if (aborted|failed), return
	// if tx timed out, raise TransactionFailed+reason=TransactionTimeoutError
	// apply message
	// if state == txWritingCommitting and > 1 outstanding writes, done
	// raise TransactionCommittingEvent
	return nil
}
func (this *Transaction) handleWriteFailed(message interface{}) error {
	// if (aborted|failed), return
	// raise TransactionFailed+reason=WriteError
	return nil
}

func (this *Transaction) handleCommitTransaction(message messages.CommitTransactionCommand) error {
	// if (txAborted|txFailed), return error
	// if (txWritingCommitting, txCommitting), return nil
	// if txCommitted, return AlreadyCommittedError (which is a HTTP 200/no-op) to the caller
	// if timed out, raise TransactionFailed and return timeout error

	// if state=txWriting, raise TransactionPendingCommitEvent (which transitions to txWritingCommitting)
	// if state=txReady, raise TransactionCommittingEvent
	return nil
}
func (this *Transaction) handleTransactionCommitted(message messages.TransactionCommittedEvent) error {
	this.Apply(message)
	return nil
}
func (this *Transaction) handleTransactionCommitFailed(message messages.TransactionCommitFailedEvent) error {
	// if (txAborted|txFailed), return
	// raise TransactionFailed
	return nil
}

func (this *Transaction) handleAbortTransaction(message messages.AbortTransactionCommand) error {
	// if (txAborted), return nil
	// if (txFailed), return TransactionFailedError
	// if (txCommitted), return AlreadyCommittedError
	// if (txCommitting|txWritingCommitting), return InvalidTransitionError
	// raise TransactionAbortedEvent
	return nil
}

func (this *Transaction) Apply(message interface{}) {
	switch message := message.(type) {

	case messages.StoringItemEvent:
		this.applyStoringItem(message)
	case messages.ItemStoredEvent:
		this.applyItemStored(message)
	case messages.ItemStoreFailedEvent:
		this.applyItemStoreFailed(message)

	case messages.DeletingItemEvent:
		this.applyDeletingItem(message)
	case messages.ItemDeletedEvent:
		this.applyItemDeleted(message)
	case messages.ItemDeleteFailedEvent:
		this.applyItemDeleteFailed(message)

	case messages.TransactionCommitAwaitingWritesEvent:
		this.applyTransactionAwaitingWrites(message)
	case messages.TransactionCommittingEvent:
		this.applyTransactionCommitting(message)

	default:
		log.Panicf("Unknown message type: %s", reflect.TypeOf(message).Name())
	}
}

func (this *Transaction) applyStoringItem(message messages.StoringItemEvent) {
	this.updated = message.Timestamp
	if this.status != txCommittingAwaitingWrites {
		this.status = txWriting
	}
}
func (this *Transaction) applyItemStored(message messages.ItemStoredEvent) {
	this.updated = message.Timestamp
}
func (this *Transaction) applyItemStoreFailed(message messages.ItemStoreFailedEvent) {
	this.updated = message.Timestamp
	this.status = txFailed
}

func (this *Transaction) applyDeletingItem(message messages.DeletingItemEvent) {
	this.updated = message.Timestamp
	if this.status != txCommittingAwaitingWrites {
		this.status = txWriting
	}
}
func (this *Transaction) applyItemDeleted(message messages.ItemDeletedEvent) {
	this.updated = message.Timestamp
}
func (this *Transaction) applyItemDeleteFailed(message messages.ItemDeleteFailedEvent) {
	this.updated = message.Timestamp
	this.status = txFailed
}

func (this *Transaction) applyTransactionAwaitingWrites(message messages.TransactionCommitAwaitingWritesEvent) {
	this.updated = message.Timestamp
	this.status = txCommittingAwaitingWrites
}
func (this *Transaction) applyTransactionCommitting(message messages.TransactionCommittingEvent) {
	this.updated = message.Timestamp
	this.status = txCommitting
}
<|endoftext|>


<commit_before>package qiniu

import (
	"github.com/7sDream/rikka/api"
	"github.com/7sDream/rikka/plugins"
)

const (
	statePreparing     = "preparing"
	statePreparingCode = 2
	statePreparingDesc = "Rikka is preparing to upload your image to Qiniu cloud"

	stateUploading     = "uploading"
	stateUploadingCode = 3
	stateUploadingDesc = "Rikka is uploading your image to Qiniu cloud"
)

func buildPreparingState(taskID string) *api.State {
	return &api.State{
		TaskID:      taskID,
		State:       statePreparing,
		StateCode:   statePreparingCode,
		Description: statePreparingDesc,
	}
}

func buildUploadingState(taskID string) *api.State {
	return &api.State{
		TaskID:      taskID,
		State:       stateUploading,
		StateCode:   statePreparingCode,
		Description: stateUploadingDesc,
	}
}

func (qnp qiniuPlugin) StateRequestHandle(taskID string) (pState *api.State, err error) {
	l.Debug("Recieve a state request of taskID", taskID)

	pState, err = plugins.GetTaskState(taskID)
	if err == nil {
		if pState.StateCode == api.StateErrorCode {
			l.Warn("Get a error state of task", taskID, *pState)
		} else {
			l.Debug("Get a normal state of task", taskID, *pState)
		}
		return pState, nil
	}

	l.Debug("State of task", taskID, "not found, just return a finish state")
	return api.BuildFinishState(taskID), nil
}
<commit_msg>[Fix][Plugin][Qiniu] wrong code of uploading state<commit_after>package qiniu

import (
	"github.com/7sDream/rikka/api"
	"github.com/7sDream/rikka/plugins"
)

const (
	statePreparing     = "preparing"
	statePreparingCode = 2
	statePreparingDesc = "Rikka is preparing to upload your image to Qiniu cloud"

	stateUploading     = "uploading"
	stateUploadingCode = 3
	stateUploadingDesc = "Rikka is uploading your image to Qiniu cloud"
)

func buildPreparingState(taskID string) *api.State {
	return &api.State{
		TaskID:      taskID,
		State:       statePreparing,
		StateCode:   statePreparingCode,
		Description: statePreparingDesc,
	}
}

func buildUploadingState(taskID string) *api.State {
	return &api.State{
		TaskID:      taskID,
		State:       stateUploading,
		StateCode:   stateUploadingCode,
		Description: stateUploadingDesc,
	}
}

func (qnp qiniuPlugin) StateRequestHandle(taskID string) (pState *api.State, err error) {
	l.Debug("Recieve a state request of taskID", taskID)

	pState, err = plugins.GetTaskState(taskID)
	if err == nil {
		if pState.StateCode == api.StateErrorCode {
			l.Warn("Get a error state of task", taskID, *pState)
		} else {
			l.Debug("Get a normal state of task", taskID, *pState)
		}
		return pState, nil
	}

	l.Debug("State of task", taskID, "not found, just return a finish state")
	return api.BuildFinishState(taskID), nil
}
<|endoftext|>


<commit_before>package url

import (
	"context"
	"net/url"
	"regexp"
	"text/template"

	"golang.org/x/oauth2/clientcredentials"

	"github.com/Sirupsen/logrus"
	"github.com/zmb3/spotify"

	"github.com/belak/go-seabird"
	"github.com/go-irc/irc"
)

func init() {
	seabird.RegisterPlugin("url/spotify", newSpotifyProvider)
}

type spotifyConfig struct {
	ClientID     string
	ClientSecret string
}

type spotifyProvider struct {
	api spotify.Client
}

var spotifyPrefix = "[Spotify]"

type spotifyMatch struct {
	regex    *regexp.Regexp
	template *template.Template
	lookup   func(*spotifyProvider, *logrus.Entry, spotify.ID) interface{}
}

var spotifyMatchers = []spotifyMatch{
	{
		regex: regexp.MustCompile(`^/album/(.+)$`),
		template: TemplateMustCompile("spotifyAlbum", `
			{{- .Name }} by
			{{- range $index, $element := .Artists }}
			{{- if $index }},{{ end }} {{ $element.Name -}}
			{{- end }}`),
		lookup: func(s *spotifyProvider, logger *logrus.Entry, id spotify.ID) interface{} {
			album, err := s.api.GetAlbum(id)
			if err != nil {
				logger.WithError(err).Error("Failed to get album info from Spotify")
				return nil
			}
			return album
		},
	},
}

var spotifyAlbumRegex = regexp.MustCompile(`^/album/(.+)$`)

func newSpotifyProvider(b *seabird.Bot, urlPlugin *Plugin) error {
	s := &spotifyProvider{}

	sc := &spotifyConfig{}
	err := b.Config("spotify", sc)
	if err != nil {
		return err
	}

	config := &clientcredentials.Config{
		ClientID:     sc.ClientID,
		ClientSecret: sc.ClientSecret,
		TokenURL:     spotify.TokenURL,
	}
	token, err := config.Token(context.Background())
	if err != nil {
		return err
	}

	s.api = spotify.Authenticator{}.NewClient(token)

	urlPlugin.RegisterProvider("open.spotify.com", s.Handle)

	return nil
}

func (s *spotifyProvider) Handle(b *seabird.Bot, m *irc.Message, u *url.URL) bool {
	logger := b.GetLogger()

	for _, matcher := range spotifyMatchers {
		if !matcher.regex.MatchString(u.Path) {
			continue
		}

		matches := matcher.regex.FindStringSubmatch(u.Path)
		if len(matches) != 2 {
			return false
		}

		data := matcher.lookup(s, logger, spotify.ID(matches[1]))
		if data == nil {
			return false
		}

		return RenderRespond(b, m, logger, matcher.template, spotifyPrefix, data)
	}

	return false
}
<commit_msg>Add artist, track and playlist URL matchers for Spotify<commit_after>package url

import (
	"context"
	"net/url"
	"regexp"
	"text/template"

	"golang.org/x/oauth2/clientcredentials"

	"github.com/Sirupsen/logrus"
	"github.com/zmb3/spotify"

	"github.com/belak/go-seabird"
	"github.com/go-irc/irc"
)

func init() {
	seabird.RegisterPlugin("url/spotify", newSpotifyProvider)
}

type spotifyConfig struct {
	ClientID     string
	ClientSecret string
}

type spotifyProvider struct {
	api spotify.Client
}

var spotifyPrefix = "[Spotify]"

type spotifyMatch struct {
	matchCount int
	regex      *regexp.Regexp
	template   *template.Template
	lookup     func(*spotifyProvider, *logrus.Entry, []string) interface{}
}

var spotifyMatchers = []spotifyMatch{
	{
		matchCount: 1,
		regex:      regexp.MustCompile(`^/artist/(.+)$`),
		template:   TemplateMustCompile("spotifyArtist", `{{- .Name -}}`),
		lookup: func(s *spotifyProvider, logger *logrus.Entry, matches []string) interface{} {
			artist, err := s.api.GetArtist(spotify.ID(matches[0]))
			if err != nil {
				logger.WithError(err).Error("Failed to get artist info from Spotify")
				return nil
			}
			return artist
		},
	},
	{
		matchCount: 1,
		regex:      regexp.MustCompile(`^/album/(.+)$`),
		template: TemplateMustCompile("spotifyAlbum", `
			{{- .Name }} by
			{{- range $index, $element := .Artists }}
			{{- if $index }},{{ end }} {{ $element.Name -}}
			{{- end }}`),
		lookup: func(s *spotifyProvider, logger *logrus.Entry, matches []string) interface{} {
			album, err := s.api.GetAlbum(spotify.ID(matches[0]))
			if err != nil {
				logger.WithError(err).Error("Failed to get album info from Spotify")
				return nil
			}
			return album
		},
	},
	{
		matchCount: 1,
		regex:      regexp.MustCompile(`^/track/(.+)$`),
		template: TemplateMustCompile("spotifyTrack", `
			"{{ .Name }}" from {{ .Album.Name }} by
			{{- range $index, $element := .Artists }}
			{{- if $index }},{{ end }} {{ $element.Name }}
			{{- end }}`),
		lookup: func(s *spotifyProvider, logger *logrus.Entry, matches []string) interface{} {
			track, err := s.api.GetTrack(spotify.ID(matches[0]))
			if err != nil {
				logger.WithError(err).Error("Failed to get track info from Spotify")
				return nil
			}
			return track
		},
	},
	{
		matchCount: 2,
		regex:      regexp.MustCompile(`^/user/([^/]*)/playlist/([^/]*)$`),
		template: TemplateMustCompile("spotifyPlaylist", `
			"{{- .Name }}" playlist by {{ .Owner.DisplayName }}`),
		lookup: func(s *spotifyProvider, logger *logrus.Entry, matches []string) interface{} {
			playlist, err := s.api.GetPlaylist(matches[0], spotify.ID(matches[1]))
			if err != nil {
				logger.WithError(err).Error("Failed to get track info from Spotify")
				return nil
			}
			return playlist
		},
	},
}

func newSpotifyProvider(b *seabird.Bot, urlPlugin *Plugin) error {
	s := &spotifyProvider{}

	sc := &spotifyConfig{}
	err := b.Config("spotify", sc)
	if err != nil {
		return err
	}

	config := &clientcredentials.Config{
		ClientID:     sc.ClientID,
		ClientSecret: sc.ClientSecret,
		TokenURL:     spotify.TokenURL,
	}
	token, err := config.Token(context.Background())
	if err != nil {
		return err
	}

	s.api = spotify.Authenticator{}.NewClient(token)

	urlPlugin.RegisterProvider("open.spotify.com", s.Handle)

	return nil
}

func (s *spotifyProvider) Handle(b *seabird.Bot, m *irc.Message, u *url.URL) bool {
	logger := b.GetLogger()

	for _, matcher := range spotifyMatchers {
		if !matcher.regex.MatchString(u.Path) {
			continue
		}

		matches := matcher.regex.FindStringSubmatch(u.Path)
		if len(matches) != matcher.matchCount+1 {
			return false
		}

		data := matcher.lookup(s, logger, matches[1:])
		if data == nil {
			return false
		}

		return RenderRespond(b, m, logger, matcher.template, spotifyPrefix, data)
	}

	return false
}
<|endoftext|>


<commit_before>package azure

import (
	"fmt"
	"strings"

	yaml "gopkg.in/yaml.v2"

	"github.com/cloudfoundry/bosh-bootloader/storage"
	"github.com/cloudfoundry/bosh-bootloader/terraform"
)

type OpsGenerator struct {
	terraformManager terraformManager
}

type terraformManager interface {
	GetOutputs() (terraform.Outputs, error)
}

type op struct {
	Type  string
	Path  string
	Value interface{}
}

type lb struct {
	Name            string
	CloudProperties cloudProperties `yaml:"cloud_properties"`
}

type cloudProperties struct {
	ApplicationGateway string `yaml:"application_gateway,omitempty"`
	LoadBalancer       string `yaml:"load_balancer,omitempty"`
}

type network struct {
	Name    string
	Subnets []networkSubnet
	Type    string
}

type networkSubnet struct {
	AZs             []string
	Gateway         string
	Range           string
	Reserved        []string
	DNS             []string
	CloudProperties subnetCloudProperties `yaml:"cloud_properties"`
}

type subnetCloudProperties struct {
	VirtualNetworkName string `yaml:"virtual_network_name"`
	SubnetName         string `yaml:"subnet_name"`
	SecurityGroup      string `yaml:"security_group,omitempty"`
}

var marshal func(interface{}) ([]byte, error) = yaml.Marshal

func NewOpsGenerator(terraformManager terraformManager) OpsGenerator {
	return OpsGenerator{
		terraformManager: terraformManager,
	}
}

func (o OpsGenerator) GenerateVars(state storage.State) (string, error) {
	terraformOutputs, err := o.terraformManager.GetOutputs()
	if err != nil {
		return "", fmt.Errorf("Get terraform outputs: %s", err)
	}

	varsYAML := map[string]interface{}{}
	for k, v := range terraformOutputs.Map {
		varsYAML[k] = v
	}

	varsBytes, err := marshal(varsYAML)
	if err != nil {
		return "", err
	}

	return string(varsBytes), nil
}

func (o OpsGenerator) Generate(state storage.State) (string, error) {
	subnet := networkSubnet{
		AZs:      []string{"z1", "z2", "z3"},
		Gateway:  "((internal_gw))",
		Range:    "((subnet_cidr))",
		Reserved: []string{"((jumpbox__internal_ip))", "((director__internal_ip))", "((internal_gw))/30"},
		DNS:      []string{"8.8.8.8", "168.63.129.16"},
		CloudProperties: subnetCloudProperties{
			VirtualNetworkName: "((vnet_name))",
			SubnetName:         "((subnet_name))",
			SecurityGroup:      "((default_security_group))",
		},
	}

	cloudConfigOps := []op{
		{
			Type: "replace",
			Path: "/networks/-",
			Value: network{
				Name:    "default",
				Subnets: []networkSubnet{subnet},
				Type:    "manual",
			},
		},
		{
			Type: "replace",
			Path: "/networks/-",
			Value: network{
				Name:    "private",
				Subnets: []networkSubnet{subnet},
				Type:    "manual",
			},
		},
	}

	switch state.LB.Type {
	case "cf":
		lbOps := []op{
			{
				Type: "replace",
				Path: "/vm_extensions/-",
				Value: lb{
					Name: "cf-router-network-properties",
					CloudProperties: cloudProperties{
						ApplicationGateway: "((cf_app_gateway_name))",
					},
				},
			},
			{
				Type:  "replace",
				Path:  "/vm_extensions/-",
				Value: lb{Name: "cf-tcp-router-network-properties"},
			},
			{
				Type:  "replace",
				Path:  "/vm_extensions/-",
				Value: lb{Name: "diego-ssh-proxy-network-properties"},
			}}
		cloudConfigOps = append(cloudConfigOps, lbOps...)
	case "concourse":
		lbOp := op{
			Type: "replace",
			Path: "/vm_extensions/-",
			Value: lb{
				Name: "lb",
				CloudProperties: cloudProperties{
					LoadBalancer: "((concourse_lb_name))",
				},
			},
		}
		cloudConfigOps = append(cloudConfigOps, lbOp)
	}

	cloudConfigOpsYAML, err := marshal(cloudConfigOps)
	if err != nil {
		return "", err
	}

	return strings.Join([]string{
		BaseOps,
		string(cloudConfigOpsYAML),
	}, "\n"), nil
}
<commit_msg>Add cf security group to azure cloud config.<commit_after>package azure

import (
	"fmt"
	"strings"

	yaml "gopkg.in/yaml.v2"

	"github.com/cloudfoundry/bosh-bootloader/storage"
	"github.com/cloudfoundry/bosh-bootloader/terraform"
)

type OpsGenerator struct {
	terraformManager terraformManager
}

type terraformManager interface {
	GetOutputs() (terraform.Outputs, error)
}

type op struct {
	Type  string
	Path  string
	Value interface{}
}

type lb struct {
	Name            string
	CloudProperties cloudProperties `yaml:"cloud_properties"`
}

type cloudProperties struct {
	ApplicationGateway string `yaml:"application_gateway,omitempty"`
	SecurityGroup      string `yaml:"security_group,omitempty"`
	LoadBalancer       string `yaml:"load_balancer,omitempty"`
}

type network struct {
	Name    string
	Subnets []networkSubnet
	Type    string
}

type networkSubnet struct {
	AZs             []string
	Gateway         string
	Range           string
	Reserved        []string
	DNS             []string
	CloudProperties subnetCloudProperties `yaml:"cloud_properties"`
}

type subnetCloudProperties struct {
	VirtualNetworkName string `yaml:"virtual_network_name"`
	SubnetName         string `yaml:"subnet_name"`
	SecurityGroup      string `yaml:"security_group,omitempty"`
}

var marshal func(interface{}) ([]byte, error) = yaml.Marshal

func NewOpsGenerator(terraformManager terraformManager) OpsGenerator {
	return OpsGenerator{
		terraformManager: terraformManager,
	}
}

func (o OpsGenerator) GenerateVars(state storage.State) (string, error) {
	terraformOutputs, err := o.terraformManager.GetOutputs()
	if err != nil {
		return "", fmt.Errorf("Get terraform outputs: %s", err)
	}

	varsYAML := map[string]interface{}{}
	for k, v := range terraformOutputs.Map {
		varsYAML[k] = v
	}

	varsBytes, err := marshal(varsYAML)
	if err != nil {
		return "", err
	}

	return string(varsBytes), nil
}

func (o OpsGenerator) Generate(state storage.State) (string, error) {
	subnet := networkSubnet{
		AZs:      []string{"z1", "z2", "z3"},
		Gateway:  "((internal_gw))",
		Range:    "((subnet_cidr))",
		Reserved: []string{"((jumpbox__internal_ip))", "((director__internal_ip))", "((internal_gw))/30"},
		DNS:      []string{"8.8.8.8", "168.63.129.16"},
		CloudProperties: subnetCloudProperties{
			VirtualNetworkName: "((vnet_name))",
			SubnetName:         "((subnet_name))",
			SecurityGroup:      "((default_security_group))",
		},
	}

	cloudConfigOps := []op{
		{
			Type: "replace",
			Path: "/networks/-",
			Value: network{
				Name:    "default",
				Subnets: []networkSubnet{subnet},
				Type:    "manual",
			},
		},
		{
			Type: "replace",
			Path: "/networks/-",
			Value: network{
				Name:    "private",
				Subnets: []networkSubnet{subnet},
				Type:    "manual",
			},
		},
	}

	switch state.LB.Type {
	case "cf":
		lbOps := []op{
			{
				Type: "replace",
				Path: "/vm_extensions/-",
				Value: lb{
					Name: "cf-router-network-properties",
					CloudProperties: cloudProperties{
						ApplicationGateway: "((cf_app_gateway_name))",
						SecurityGroup:      "((cf_security_group))",
					},
				},
			},
			{
				Type:  "replace",
				Path:  "/vm_extensions/-",
				Value: lb{Name: "cf-tcp-router-network-properties"},
			},
			{
				Type:  "replace",
				Path:  "/vm_extensions/-",
				Value: lb{Name: "diego-ssh-proxy-network-properties"},
			}}
		cloudConfigOps = append(cloudConfigOps, lbOps...)
	case "concourse":
		lbOp := op{
			Type: "replace",
			Path: "/vm_extensions/-",
			Value: lb{
				Name: "lb",
				CloudProperties: cloudProperties{
					LoadBalancer: "((concourse_lb_name))",
				},
			},
		}
		cloudConfigOps = append(cloudConfigOps, lbOp)
	}

	cloudConfigOpsYAML, err := marshal(cloudConfigOps)
	if err != nil {
		return "", err
	}

	return strings.Join([]string{
		BaseOps,
		string(cloudConfigOpsYAML),
	}, "\n"), nil
}
<|endoftext|>


<commit_before>package game

import (
	"bytes"
	"encoding/json"
	"testing"
)

func Benchmark_segments(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		Standard.segments()
	}
}

func Test_segments(t *testing.T) {
	numSegs := len(Standard.segments())
	if numSegs != 55 {
		t.Error("number segments in standard game: expected 55, got", numSegs)
	}
}

func Benchmark_futures(b *testing.B) {
	b.ReportAllocs()
	for n := 0; n <= b.N; n++ {
		Standard.Futures()
	}
}

func TestFuturesAreValid(t *testing.T) {
	futures := Standard.Futures()
	for _, f := range futures {
		if !Standard.ValidFuture(f) {
			t.Error("expected future ", f, "to be a valid future for game", Standard)
		}
	}
}

func TestGameMarshalJSON(t *testing.T) {
	g := Standard
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(&g); err != nil {
		t.Fatal(err)
	}

	data := buf.Bytes()
	canonical_encoded := `{"board":{"whitePositions":[{"q":0,"r":2},{"q":-3,"r":4},{"q":-2,"r":2},{"q":-1,"r":3},{"q":0,"r":3},{"q":0,"r":4},{"q":1,"r":3},{"q":-4,"r":4},{"q":-3,"r":3},{"q":-2,"r":3},{"q":-1,"r":2},{"q":-4,"r":3},{"q":-2,"r":4},{"q":-1,"r":4}],"blackPositions":[{"q":3,"r":-3},{"q":1,"r":-2},{"q":2,"r":-4},{"q":2,"r":-3},{"q":4,"r":-3},{"q":0,"r":-4},{"q":3,"r":-4},{"q":4,"r":-4},{"q":-1,"r":-3},{"q":1,"r":-4},{"q":2,"r":-2},{"q":0,"r":-3},{"q":0,"r":-2},{"q":1,"r":-3}],"edgeLength":5},"nextPlayer":"white","movesRemaining":1000,"marblesPerMove":3,"lossThreshold":8}`
	var canonical_decoded State
	if err := json.NewDecoder(bytes.NewBufferString(canonical_encoded)).Decode(&canonical_decoded); err != nil {
		t.Fatal(err)
	}
	if !g.eq(&canonical_decoded) {
		t.Error("standard game did not match canonical serialized game")
	}
	var gprime State
	if err := json.NewDecoder(bytes.NewBuffer(data)).Decode(&gprime); err != nil {
		t.Fatal(err)
	}
	if !g.eq(&gprime) {
		t.Error("game changed by serialization operation")
		t.Log("before", g)
		t.Log("serialized", buf.String())
		t.Log("after", gprime)
	}
}
<commit_msg>benchmark state.eq<commit_after>package game

import (
	"bytes"
	"encoding/json"
	"testing"
)

func Benchmark_segments(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		Standard.segments()
	}
}

func Test_segments(t *testing.T) {
	numSegs := len(Standard.segments())
	if numSegs != 55 {
		t.Error("number segments in standard game: expected 55, got", numSegs)
	}
}

func Benchmark_futures(b *testing.B) {
	b.ReportAllocs()
	for n := 0; n <= b.N; n++ {
		Standard.Futures()
	}
}

func Benchmark_Equal(b *testing.B) {
	b.ReportAllocs()

	fs := Standard.Futures()
	b.ResetTimer()
	for n := 0; n <= b.N; n++ {
		Standard.eq(fs[1])
	}
}

func TestFuturesAreValid(t *testing.T) {
	futures := Standard.Futures()
	for _, f := range futures {
		if !Standard.ValidFuture(f) {
			t.Error("expected future ", f, "to be a valid future for game", Standard)
		}
	}
}

func TestGameMarshalJSON(t *testing.T) {
	g := Standard
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(&g); err != nil {
		t.Fatal(err)
	}

	data := buf.Bytes()
	canonical_encoded := `{"board":{"whitePositions":[{"q":0,"r":2},{"q":-3,"r":4},{"q":-2,"r":2},{"q":-1,"r":3},{"q":0,"r":3},{"q":0,"r":4},{"q":1,"r":3},{"q":-4,"r":4},{"q":-3,"r":3},{"q":-2,"r":3},{"q":-1,"r":2},{"q":-4,"r":3},{"q":-2,"r":4},{"q":-1,"r":4}],"blackPositions":[{"q":3,"r":-3},{"q":1,"r":-2},{"q":2,"r":-4},{"q":2,"r":-3},{"q":4,"r":-3},{"q":0,"r":-4},{"q":3,"r":-4},{"q":4,"r":-4},{"q":-1,"r":-3},{"q":1,"r":-4},{"q":2,"r":-2},{"q":0,"r":-3},{"q":0,"r":-2},{"q":1,"r":-3}],"edgeLength":5},"nextPlayer":"white","movesRemaining":1000,"marblesPerMove":3,"lossThreshold":8}`
	var canonical_decoded State
	if err := json.NewDecoder(bytes.NewBufferString(canonical_encoded)).Decode(&canonical_decoded); err != nil {
		t.Fatal(err)
	}
	if !g.eq(&canonical_decoded) {
		t.Error("standard game did not match canonical serialized game")
	}
	var gprime State
	if err := json.NewDecoder(bytes.NewBuffer(data)).Decode(&gprime); err != nil {
		t.Fatal(err)
	}
	if !g.eq(&gprime) {
		t.Error("game changed by serialization operation")
		t.Log("before", g)
		t.Log("serialized", buf.String())
		t.Log("after", gprime)
	}
}
<|endoftext|>


<commit_before>// Package intcode implements an intocde computer.
package intcode

import (
	"fmt"
	"strconv"

	"github.com/bewuethr/advent-of-code/go/convert"
)

const (
	// Instructions
	add         = 1
	mult        = 2
	input       = 3
	output      = 4
	jumpIfTrue  = 5
	jumpIfFalse = 6
	lessThan    = 7
	equals      = 8
	adjustBase  = 9
	halt        = 99

	// Modes
	positionMode  = 0
	immediateMode = 1
	relativeMode  = 2
)

// nargs maps instructions to the number of arguments they use.
var nargs = map[int]int{
	add:         3,
	mult:        3,
	input:       1,
	output:      1,
	jumpIfTrue:  2,
	jumpIfFalse: 2,
	lessThan:    3,
	equals:      3,
	adjustBase:  1,
	halt:        0,
}

// param is a type for values in memory, where index is the optional location
// of the value; it is nil for immediate mode parameters.
type param struct {
	value int
	index *int
}

// methodMap is a map from instructions to the corresponding Computer methods.
var methodMap = map[int]func(*Computer, []param){
	add:         (*Computer).add,
	mult:        (*Computer).mult,
	input:       (*Computer).input,
	output:      (*Computer).output,
	jumpIfTrue:  (*Computer).jumpIfTrue,
	jumpIfFalse: (*Computer).jumpIfFalse,
	lessThan:    (*Computer).lessThan,
	equals:      (*Computer).equals,
	adjustBase:  (*Computer).adjustBase,
}

// Computer is an opcode computer.
type Computer struct {
	opcodes   []int
	inputVals []int
	instrPtr  int
	relOffset int
}

// NewComputer returns an opcode computer with its memory initalized to opcodes.
func NewComputer(opcodes []int) *Computer {
	return &Computer{
		opcodes:   opcodes,
		instrPtr:  0,
		relOffset: 0,
	}
}

// RunProgram executes the program in the memory of the computer.
func (c *Computer) RunProgram(inputVals ...int) error {
	c.inputVals = inputVals
	for {
		code, params, err := c.parseInstruction(c.opcodes[c.instrPtr])
		if err != nil {
			return err
		}

		if code == halt {
			return nil
		}

		methodMap[code](c, params)
	}
}

// Value returns the value at position idx; if the index is out of range, extra
// memory is appended.
func (c *Computer) Value(idx int) int {
	if idx < len(c.opcodes) {
		return c.opcodes[idx]
	}

	if idx < cap(c.opcodes) {
		c.opcodes = c.opcodes[:cap(c.opcodes)]
		return c.opcodes[idx]
	}

	// Index larger than even backing array, allocate new slice
	newOpcodes := make([]int, idx+1, (2*idx)+1)
	copy(newOpcodes, c.opcodes)
	c.opcodes = newOpcodes
	return c.opcodes[idx]
}

func (c *Computer) add(params []param) {
	c.opcodes[*params[2].index] = params[0].value + params[1].value
	c.instrPtr += nargs[add] + 1
}

func (c *Computer) mult(params []param) {
	c.opcodes[*params[2].index] = params[0].value * params[1].value
	c.instrPtr += nargs[mult] + 1
}

func (c *Computer) input(params []param) {
	c.opcodes[*params[0].index] = c.inputVals[0]
	c.inputVals = c.inputVals[1:]
	c.instrPtr += nargs[input] + 1
}

func (c *Computer) output(params []param) {
	fmt.Println(params[0].value)
	c.instrPtr += nargs[output] + 1
}

func (c *Computer) jumpIfTrue(params []param) {
	if params[0].value != 0 {
		c.instrPtr = params[1].value
	} else {
		c.instrPtr += nargs[jumpIfTrue] + 1
	}
}

func (c *Computer) jumpIfFalse(params []param) {
	if params[0].value == 0 {
		c.instrPtr = params[1].value
	} else {
		c.instrPtr += nargs[jumpIfFalse] + 1
	}
}

func (c *Computer) lessThan(params []param) {
	if params[0].value < params[1].value {
		c.opcodes[*params[2].index] = 1
	} else {
		c.opcodes[*params[2].index] = 0
	}
	c.instrPtr += nargs[lessThan] + 1
}

func (c *Computer) equals(params []param) {
	if params[0].value == params[1].value {
		c.opcodes[*params[2].index] = 1
	} else {
		c.opcodes[*params[2].index] = 0
	}
	c.instrPtr += nargs[equals] + 1
}

func (c *Computer) adjustBase(params []param) {
	c.relOffset += params[0].value
	c.instrPtr += nargs[adjustBase] + 1
}

// parseInstruction reads a value from memory and extracts the opcode as well as
// the parameter values for the instruction, taking the parameter mode into
// account.
func (c *Computer) parseInstruction(val int) (code int, params []param, err error) {
	code = val % 100
	var modes []int
	if valStr := strconv.Itoa(val); len(valStr) > 2 {
		valStr = valStr[:len(valStr)-2]

		var modesStr []string
		for _, m := range valStr {
			modesStr = append([]string{string(m)}, modesStr...)
		}

		var err error
		modes, err = convert.StrSliceToInt(modesStr)
		if err != nil {
			return 0, nil, fmt.Errorf("converting modes %v to int: %w", modesStr, err)
		}
	}

	for len(modes) < nargs[code] {
		modes = append(modes, 0)
	}

	params, err = c.getParams(modes)
	return code, params, err
}

// getParams takes a slice of parameter modes and returns the corresponding
// parameter values based on the current value of the instruction pointer.
func (c *Computer) getParams(modes []int) ([]param, error) {
	var params []param

	for i := 0; i < len(modes); i++ {
		var p param
		switch modes[i] {
		case positionMode:
			idx := c.Value(c.instrPtr + i + 1)
			p = param{
				value: c.Value(idx),
				index: &idx,
			}

		case immediateMode:
			p.value = c.Value(c.instrPtr + i + 1)

		case relativeMode:
			idx := c.Value(c.instrPtr+i+1) + c.relOffset
			p = param{
				value: c.Value(idx),
				index: &idx,
			}

		default:
			return nil, fmt.Errorf("unknown parameter mode %q", modes[i])
		}

		params = append(params, p)
	}

	return params, nil
}
<commit_msg>Uddate intcode computer to use channels<commit_after>// Package intcode implements an intcode computer.
package intcode

import (
	"fmt"
	"strconv"

	"github.com/bewuethr/advent-of-code/go/convert"
)

const (
	// Instructions
	add         = 1
	mult        = 2
	input       = 3
	output      = 4
	jumpIfTrue  = 5
	jumpIfFalse = 6
	lessThan    = 7
	equals      = 8
	adjustBase  = 9
	halt        = 99

	// Modes
	positionMode  = 0
	immediateMode = 1
	relativeMode  = 2
)

// nargs maps instructions to the number of arguments they use.
var nargs = map[int]int{
	add:         3,
	mult:        3,
	input:       1,
	output:      1,
	jumpIfTrue:  2,
	jumpIfFalse: 2,
	lessThan:    3,
	equals:      3,
	adjustBase:  1,
	halt:        0,
}

// param is a type for values in memory, where index is the optional location
// of the value; it is nil for immediate mode parameters.
type param struct {
	value int
	index *int
}

// methodMap is a map from instructions to the corresponding Computer methods.
var methodMap = map[int]func(*Computer, []param){
	add:         (*Computer).add,
	mult:        (*Computer).mult,
	input:       (*Computer).input,
	output:      (*Computer).output,
	jumpIfTrue:  (*Computer).jumpIfTrue,
	jumpIfFalse: (*Computer).jumpIfFalse,
	lessThan:    (*Computer).lessThan,
	equals:      (*Computer).equals,
	adjustBase:  (*Computer).adjustBase,
}

// Computer is an opcode computer. Input is read through the Input channel,
// output from the Output channel; the "halt" instruction closes the Done
// channel, and any errors can be read from the Err channel.
type Computer struct {
	opcodes   []int
	instrPtr  int
	relOffset int
	Done      chan struct{}
	Input     chan int
	Output    chan int
	Err       chan error
}

// NewComputer returns an opcode computer with its memory initalized to opcodes.
func NewComputer(opcodes []int) *Computer {
	var (
		done   = make(chan struct{})
		input  = make(chan int)
		output = make(chan int)
		err    = make(chan error)
	)

	return &Computer{
		opcodes:   opcodes,
		instrPtr:  0,
		relOffset: 0,
		Done:      done,
		Input:     input,
		Output:    output,
		Err:       err,
	}
}

// RunProgram starts a goroutine that executes the program in the memory of the
// computer. It is typically used like this:
//
//     Loop:
//         for {
//             select {
//             case v := <-c.Output:
//                 // Do something with output.
//             case <-c.Done:
//                 break Loop
//             case err := <-c.Err:
//                 // Handle error.
//             }
//         }
//
// TODO Rename StartProgram
func (c *Computer) RunProgram() {
	go func() {
		for {
			code, params, err := c.parseInstruction(c.opcodes[c.instrPtr])
			fmt.Printf("code %v, params %v\n", code, params)
			if err != nil {
				c.Err <- err
				return
			}

			if code == halt {
				close(c.Done)
				return
			}

			methodMap[code](c, params)
		}
	}()
}

// Value returns the value at position idx; if the index is out of range, extra
// memory is appended.
func (c *Computer) Value(idx int) int {
	if idx < len(c.opcodes) {
		return c.opcodes[idx]
	}

	if idx < cap(c.opcodes) {
		c.opcodes = c.opcodes[:cap(c.opcodes)]
		return c.opcodes[idx]
	}

	// Index larger than even backing array, allocate new slice
	newOpcodes := make([]int, idx+1, (2*idx)+1)
	copy(newOpcodes, c.opcodes)
	c.opcodes = newOpcodes
	return c.opcodes[idx]
}

func (c *Computer) add(params []param) {
	c.opcodes[*params[2].index] = params[0].value + params[1].value
	c.instrPtr += nargs[add] + 1
}

func (c *Computer) mult(params []param) {
	c.opcodes[*params[2].index] = params[0].value * params[1].value
	c.instrPtr += nargs[mult] + 1
}

func (c *Computer) input(params []param) {
	c.opcodes[*params[0].index] = <-c.Input
	c.instrPtr += nargs[input] + 1
}

func (c *Computer) output(params []param) {
	c.Output <- params[0].value
	c.instrPtr += nargs[output] + 1
}

func (c *Computer) jumpIfTrue(params []param) {
	if params[0].value != 0 {
		c.instrPtr = params[1].value
	} else {
		c.instrPtr += nargs[jumpIfTrue] + 1
	}
}

func (c *Computer) jumpIfFalse(params []param) {
	if params[0].value == 0 {
		c.instrPtr = params[1].value
	} else {
		c.instrPtr += nargs[jumpIfFalse] + 1
	}
}

func (c *Computer) lessThan(params []param) {
	if params[0].value < params[1].value {
		c.opcodes[*params[2].index] = 1
	} else {
		c.opcodes[*params[2].index] = 0
	}
	c.instrPtr += nargs[lessThan] + 1
}

func (c *Computer) equals(params []param) {
	if params[0].value == params[1].value {
		c.opcodes[*params[2].index] = 1
	} else {
		c.opcodes[*params[2].index] = 0
	}
	c.instrPtr += nargs[equals] + 1
}

func (c *Computer) adjustBase(params []param) {
	c.relOffset += params[0].value
	c.instrPtr += nargs[adjustBase] + 1
}

// parseInstruction reads a value from memory and extracts the opcode as well as
// the parameter values for the instruction, taking the parameter mode into
// account.
func (c *Computer) parseInstruction(val int) (code int, params []param, err error) {
	code = val % 100
	var modes []int
	if valStr := strconv.Itoa(val); len(valStr) > 2 {
		valStr = valStr[:len(valStr)-2]

		var modesStr []string
		for _, m := range valStr {
			modesStr = append([]string{string(m)}, modesStr...)
		}

		var err error
		modes, err = convert.StrSliceToInt(modesStr)
		if err != nil {
			return 0, nil, fmt.Errorf("converting modes %v to int: %w", modesStr, err)
		}
	}

	for len(modes) < nargs[code] {
		modes = append(modes, 0)
	}

	params, err = c.getParams(modes)
	return code, params, err
}

// getParams takes a slice of parameter modes and returns the corresponding
// parameter values based on the current value of the instruction pointer.
func (c *Computer) getParams(modes []int) ([]param, error) {
	var params []param

	for i := 0; i < len(modes); i++ {
		var p param
		switch modes[i] {
		case positionMode:
			idx := c.Value(c.instrPtr + i + 1)
			p = param{
				value: c.Value(idx),
				index: &idx,
			}

		case immediateMode:
			p.value = c.Value(c.instrPtr + i + 1)

		case relativeMode:
			idx := c.Value(c.instrPtr+i+1) + c.relOffset
			p = param{
				value: c.Value(idx),
				index: &idx,
			}

		default:
			return nil, fmt.Errorf("unknown parameter mode %q", modes[i])
		}

		params = append(params, p)
	}

	return params, nil
}
<|endoftext|>


<commit_before>package isogram
<commit_msg>Initial isogram solution<commit_after>package isogram

// IsIsogram returns whether the provided string is an isogram.
// In other words, whether the string does not contain any duplicate characters.
func IsIsogram(s string) bool {
	return true
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Incomplete source tree on Android.

// +build !android

package ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run with "go test -cpu=8 to" set GOMAXPROCS.

import (
	"go/ast"
	"go/build"
	"go/token"
	"runtime"
	"testing"
	"time"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/go/ssa/ssautil"
)

// Skip the set of packages that transitively depend on
// cmd/internal/objfile, which uses vendoring,
// which go/loader does not yet support.
// TODO(adonovan): add support for vendoring and delete this.
var skip = map[string]bool{
	"cmd/addr2line":        true,
	"cmd/internal/objfile": true,
	"cmd/nm":               true,
	"cmd/objdump":          true,
	"cmd/pprof":            true,
}

func bytesAllocated() uint64 {
	runtime.GC()
	var stats runtime.MemStats
	runtime.ReadMemStats(&stats)
	return stats.Alloc
}

func TestStdlib(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping in short mode; too slow (golang.org/issue/14113)")
	}
	// Load, parse and type-check the program.
	t0 := time.Now()
	alloc0 := bytesAllocated()

	// Load, parse and type-check the program.
	ctxt := build.Default // copy
	ctxt.GOPATH = ""      // disable GOPATH
	conf := loader.Config{Build: &ctxt}
	for _, path := range buildutil.AllPackages(conf.Build) {
		if skip[path] {
			continue
		}
		conf.ImportWithTests(path)
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()
	alloc1 := bytesAllocated()

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssautil.CreateProgram(iprog, mode)

	t2 := time.Now()

	// Build SSA.
	prog.Build()

	t3 := time.Now()
	alloc3 := bytesAllocated()

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Keep iprog reachable until after we've measured memory usage.
	if len(iprog.AllPackages) == 0 {
		print() // unreachable
	}

	allFuncs := ssautil.AllFunctions(prog)

	// Check that all non-synthetic functions have distinct names.
	// Synthetic wrappers for exported methods should be distinct too,
	// except for unexported ones (explained at (*Function).RelString).
	byName := make(map[string]*ssa.Function)
	for fn := range allFuncs {
		if fn.Synthetic == "" || ast.IsExported(fn.Name()) {
			str := fn.String()
			prev := byName[str]
			byName[str] = fn
			if prev != nil {
				t.Errorf("%s: duplicate function named %s",
					prog.Fset.Position(fn.Pos()), str)
				t.Errorf("%s:   (previously defined here)",
					prog.Fset.Position(prev.Pos()))
			}
		}
	}

	// Dump some statistics.
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB AST+types:        ", int64(alloc1-alloc0)/1e6)
	t.Log("#MB SSA:              ", int64(alloc3-alloc1)/1e6)
}
<commit_msg>go/ssa: avoid no-arg println(), for gccgo compatibility<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Incomplete source tree on Android.

// +build !android

package ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run with "go test -cpu=8 to" set GOMAXPROCS.

import (
	"go/ast"
	"go/build"
	"go/token"
	"runtime"
	"testing"
	"time"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/go/ssa/ssautil"
)

// Skip the set of packages that transitively depend on
// cmd/internal/objfile, which uses vendoring,
// which go/loader does not yet support.
// TODO(adonovan): add support for vendoring and delete this.
var skip = map[string]bool{
	"cmd/addr2line":        true,
	"cmd/internal/objfile": true,
	"cmd/nm":               true,
	"cmd/objdump":          true,
	"cmd/pprof":            true,
}

func bytesAllocated() uint64 {
	runtime.GC()
	var stats runtime.MemStats
	runtime.ReadMemStats(&stats)
	return stats.Alloc
}

func TestStdlib(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping in short mode; too slow (golang.org/issue/14113)")
	}
	// Load, parse and type-check the program.
	t0 := time.Now()
	alloc0 := bytesAllocated()

	// Load, parse and type-check the program.
	ctxt := build.Default // copy
	ctxt.GOPATH = ""      // disable GOPATH
	conf := loader.Config{Build: &ctxt}
	for _, path := range buildutil.AllPackages(conf.Build) {
		if skip[path] {
			continue
		}
		conf.ImportWithTests(path)
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()
	alloc1 := bytesAllocated()

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssautil.CreateProgram(iprog, mode)

	t2 := time.Now()

	// Build SSA.
	prog.Build()

	t3 := time.Now()
	alloc3 := bytesAllocated()

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Keep iprog reachable until after we've measured memory usage.
	if len(iprog.AllPackages) == 0 {
		panic("unreachable")
	}

	allFuncs := ssautil.AllFunctions(prog)

	// Check that all non-synthetic functions have distinct names.
	// Synthetic wrappers for exported methods should be distinct too,
	// except for unexported ones (explained at (*Function).RelString).
	byName := make(map[string]*ssa.Function)
	for fn := range allFuncs {
		if fn.Synthetic == "" || ast.IsExported(fn.Name()) {
			str := fn.String()
			prev := byName[str]
			byName[str] = fn
			if prev != nil {
				t.Errorf("%s: duplicate function named %s",
					prog.Fset.Position(fn.Pos()), str)
				t.Errorf("%s:   (previously defined here)",
					prog.Fset.Position(prev.Pos()))
			}
		}
	}

	// Dump some statistics.
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB AST+types:        ", int64(alloc1-alloc0)/1e6)
	t.Log("#MB SSA:              ", int64(alloc3-alloc1)/1e6)
}
<|endoftext|>


<commit_before>package tricorder

import (
	"github.com/Symantec/tricorder/go/tricorder/units"
	"github.com/Symantec/tricorder/go/tricorder/wrapper"
	"os"
	"runtime"
	"strings"
	"syscall"
	"time"
)

func getProgramArgs() string {
	return strings.Join(os.Args[1:], "|")
}

func timeValToDuration(val *wrapper.Timeval) time.Duration {
	return time.Duration(val.Sec)*time.Second + time.Duration(val.Usec)*time.Nanosecond
}

func initDefaultMetrics() {
	programArgs := getProgramArgs()
	var totalMemory uint64
	memStatsGroup := NewGroup()
	memStatsGroup.RegisterUpdateFunc(func() time.Time {
		var memStats runtime.MemStats
		runtime.ReadMemStats(&memStats)
		totalMemory = memStats.Sys - memStats.HeapReleased
		return time.Now()
	})
	RegisterMetricInGroup(
		"/proc/memory/total",
		&totalMemory,
		memStatsGroup,
		units.Byte,
		"System memory currently allocated to process")
	var numGoroutines int
	var resourceUsage wrapper.Rusage
	var userTime time.Duration
	var sysTime time.Duration
	var maxResidentSetSize int64
	resourceUsageGroup := NewGroup()
	resourceUsageGroup.RegisterUpdateFunc(func() time.Time {
		numGoroutines = runtime.NumGoroutine()
		wrapper.Getrusage(syscall.RUSAGE_SELF, &resourceUsage)
		userTime = timeValToDuration(&resourceUsage.Utime)
		sysTime = timeValToDuration(&resourceUsage.Stime)
		maxResidentSetSize = resourceUsage.Maxrss
		return time.Now()
	})
	RegisterMetricInGroup(
		"/proc/cpu/user",
		&userTime,
		resourceUsageGroup,
		units.Second,
		"User CPU time used")
	RegisterMetricInGroup(
		"/proc/cpu/sys",
		&sysTime,
		resourceUsageGroup,
		units.Second,
		"User CPU time used")
	RegisterMetricInGroup(
		"/proc/go/num-goroutines",
		&numGoroutines,
		resourceUsageGroup,
		units.None,
		"Number of goroutines")
	RegisterMetricInGroup(
		"/proc/memory/max-resident-set-size",
		&maxResidentSetSize,
		resourceUsageGroup,
		units.Byte,
		"Maximum resident set size")
	RegisterMetricInGroup(
		"/proc/memory/shared",
		&resourceUsage.Ixrss,
		resourceUsageGroup,
		units.Byte,
		"Integral shared memory size")
	RegisterMetricInGroup(
		"/proc/memory/unshared-data",
		&resourceUsage.Idrss,
		resourceUsageGroup,
		units.Byte,
		"Integral unshared data size")
	RegisterMetricInGroup(
		"/proc/memory/unshared-stack",
		&resourceUsage.Isrss,
		resourceUsageGroup,
		units.Byte,
		"Integral unshared stack size")
	RegisterMetricInGroup(
		"/proc/memory/soft-page-fault",
		&resourceUsage.Minflt,
		resourceUsageGroup,
		units.None,
		"Soft page faults")
	RegisterMetricInGroup(
		"/proc/memory/hard-page-fault",
		&resourceUsage.Majflt,
		resourceUsageGroup,
		units.None,
		"Hard page faults")
	RegisterMetricInGroup(
		"/proc/memory/swaps",
		&resourceUsage.Nswap,
		resourceUsageGroup,
		units.None,
		"Swaps")
	RegisterMetricInGroup(
		"/proc/io/input",
		&resourceUsage.Inblock,
		resourceUsageGroup,
		units.None,
		"Block input operations")
	RegisterMetricInGroup(
		"/proc/io/output",
		&resourceUsage.Oublock,
		resourceUsageGroup,
		units.None,
		"Block output operations")
	RegisterMetricInGroup(
		"/proc/ipc/sent",
		&resourceUsage.Msgsnd,
		resourceUsageGroup,
		units.None,
		"IPC messages sent")
	RegisterMetricInGroup(
		"/proc/ipc/received",
		&resourceUsage.Msgrcv,
		resourceUsageGroup,
		units.None,
		"IPC messages received")
	RegisterMetricInGroup(
		"/proc/signals/received",
		&resourceUsage.Nsignals,
		resourceUsageGroup,
		units.None,
		"Signals received")
	RegisterMetricInGroup(
		"/proc/scheduler/involuntary-switches",
		&resourceUsage.Nivcsw,
		resourceUsageGroup,
		units.None,
		"Involuntary context switches")
	RegisterMetricInGroup(
		"/proc/scheduler/voluntary-switches",
		&resourceUsage.Nvcsw,
		resourceUsageGroup,
		units.None,
		"Voluntary context switches")
	RegisterMetric("/proc/name", &os.Args[0], units.None, "Program name")
	RegisterMetric("/proc/args", &programArgs, units.None, "Program args")
	RegisterMetric("/proc/start-time", &appStartTime, units.None, "Program start time")
}

func init() {
	initDefaultMetrics()
	initHttpFramework()
	initHtmlHandlers()
	initJsonHandlers()
	initRpcHandlers()
}
<commit_msg>Add  a check for MemStats.Sys >= MemStats.HeapReleased<commit_after>package tricorder

import (
	"github.com/Symantec/tricorder/go/tricorder/units"
	"github.com/Symantec/tricorder/go/tricorder/wrapper"
	"os"
	"runtime"
	"strings"
	"syscall"
	"time"
)

func getProgramArgs() string {
	return strings.Join(os.Args[1:], "|")
}

func timeValToDuration(val *wrapper.Timeval) time.Duration {
	return time.Duration(val.Sec)*time.Second + time.Duration(val.Usec)*time.Nanosecond
}

func initDefaultMetrics() {
	programArgs := getProgramArgs()
	var totalMemory uint64
	memStatsGroup := NewGroup()
	memStatsGroup.RegisterUpdateFunc(func() time.Time {
		var memStats runtime.MemStats
		runtime.ReadMemStats(&memStats)
		if memStats.Sys >= memStats.HeapReleased {
			totalMemory = memStats.Sys - memStats.HeapReleased
		}
		return time.Now()
	})
	RegisterMetricInGroup(
		"/proc/memory/total",
		&totalMemory,
		memStatsGroup,
		units.Byte,
		"System memory currently allocated to process")
	var numGoroutines int
	var resourceUsage wrapper.Rusage
	var userTime time.Duration
	var sysTime time.Duration
	var maxResidentSetSize int64
	resourceUsageGroup := NewGroup()
	resourceUsageGroup.RegisterUpdateFunc(func() time.Time {
		numGoroutines = runtime.NumGoroutine()
		wrapper.Getrusage(syscall.RUSAGE_SELF, &resourceUsage)
		userTime = timeValToDuration(&resourceUsage.Utime)
		sysTime = timeValToDuration(&resourceUsage.Stime)
		maxResidentSetSize = resourceUsage.Maxrss
		return time.Now()
	})
	RegisterMetricInGroup(
		"/proc/cpu/user",
		&userTime,
		resourceUsageGroup,
		units.Second,
		"User CPU time used")
	RegisterMetricInGroup(
		"/proc/cpu/sys",
		&sysTime,
		resourceUsageGroup,
		units.Second,
		"User CPU time used")
	RegisterMetricInGroup(
		"/proc/go/num-goroutines",
		&numGoroutines,
		resourceUsageGroup,
		units.None,
		"Number of goroutines")
	RegisterMetricInGroup(
		"/proc/memory/max-resident-set-size",
		&maxResidentSetSize,
		resourceUsageGroup,
		units.Byte,
		"Maximum resident set size")
	RegisterMetricInGroup(
		"/proc/memory/shared",
		&resourceUsage.Ixrss,
		resourceUsageGroup,
		units.Byte,
		"Integral shared memory size")
	RegisterMetricInGroup(
		"/proc/memory/unshared-data",
		&resourceUsage.Idrss,
		resourceUsageGroup,
		units.Byte,
		"Integral unshared data size")
	RegisterMetricInGroup(
		"/proc/memory/unshared-stack",
		&resourceUsage.Isrss,
		resourceUsageGroup,
		units.Byte,
		"Integral unshared stack size")
	RegisterMetricInGroup(
		"/proc/memory/soft-page-fault",
		&resourceUsage.Minflt,
		resourceUsageGroup,
		units.None,
		"Soft page faults")
	RegisterMetricInGroup(
		"/proc/memory/hard-page-fault",
		&resourceUsage.Majflt,
		resourceUsageGroup,
		units.None,
		"Hard page faults")
	RegisterMetricInGroup(
		"/proc/memory/swaps",
		&resourceUsage.Nswap,
		resourceUsageGroup,
		units.None,
		"Swaps")
	RegisterMetricInGroup(
		"/proc/io/input",
		&resourceUsage.Inblock,
		resourceUsageGroup,
		units.None,
		"Block input operations")
	RegisterMetricInGroup(
		"/proc/io/output",
		&resourceUsage.Oublock,
		resourceUsageGroup,
		units.None,
		"Block output operations")
	RegisterMetricInGroup(
		"/proc/ipc/sent",
		&resourceUsage.Msgsnd,
		resourceUsageGroup,
		units.None,
		"IPC messages sent")
	RegisterMetricInGroup(
		"/proc/ipc/received",
		&resourceUsage.Msgrcv,
		resourceUsageGroup,
		units.None,
		"IPC messages received")
	RegisterMetricInGroup(
		"/proc/signals/received",
		&resourceUsage.Nsignals,
		resourceUsageGroup,
		units.None,
		"Signals received")
	RegisterMetricInGroup(
		"/proc/scheduler/involuntary-switches",
		&resourceUsage.Nivcsw,
		resourceUsageGroup,
		units.None,
		"Involuntary context switches")
	RegisterMetricInGroup(
		"/proc/scheduler/voluntary-switches",
		&resourceUsage.Nvcsw,
		resourceUsageGroup,
		units.None,
		"Voluntary context switches")
	RegisterMetric("/proc/name", &os.Args[0], units.None, "Program name")
	RegisterMetric("/proc/args", &programArgs, units.None, "Program args")
	RegisterMetric("/proc/start-time", &appStartTime, units.None, "Program start time")
}

func init() {
	initDefaultMetrics()
	initHttpFramework()
	initHtmlHandlers()
	initJsonHandlers()
	initRpcHandlers()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/bndr/gojenkins"
	ui "github.com/gizak/termui"
	"github.com/golang/glog"
	tm "github.com/nsf/termbox-go"
	"regexp"
	"time"
)

func init() {
	flag.Parse()
}

var sampleInterval = flag.Duration("interval", 5*time.Second, "Interval between sampling (default:5s)")
var jenkinsUrl = flag.String("jenkinsUrl", "", "Jenkins Url")
var filter = flag.String("filter", "", "Filter job")

var filterBuildName *regexp.Regexp

func main() {
	defer glog.Flush()
	flag.Parse()

	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()

	jenkins := gojenkins.CreateJenkins(*jenkinsUrl).Init()
	ls, infobox, redbox, yellowbox, greenbox := initWidgets()

	if *filter != "" {
		filterBuildName = regexp.MustCompile(*filter)
	}

	evt := make(chan tm.Event)
	go func() {
		for {
			evt <- tm.PollEvent()
		}
	}()

	ticker := time.NewTicker(*sampleInterval).C
	for {
		select {
		case e := <-evt:
			if e.Type == tm.EventKey && e.Ch == 'q' {
				return
			}
		case <-ticker:
			// alway resize, strange behaviour with tm.EventResize
			resizeUI(ls)
			ls.Items = ls.Items[:0]
			resetBox(infobox, redbox, yellowbox, greenbox)
			jenkinsPoll(jenkins, infobox, ls, redbox, yellowbox, greenbox)
			ui.Render(ui.Body)
		}
	}
}

func resizeUI(ls *ui.List) {
	w, h := tm.Size()
	ui.Body.Width = w
	ls.Height = h - 6
	ui.Body.Align()
}

func jenkinsPoll(jenkins *gojenkins.Jenkins, infobox *ui.Par, ls *ui.List, redbox *ui.Par, yellowbox *ui.Par, greenbox *ui.Par) {
	defer func() {
		if r := recover(); r != nil {
			infobox.Border.FgColor = ui.ColorRed
			//err := fmt.Errorf("%v", r)
			infobox.Text += " : /!\\ Jenkins is currently unreachable"
		}
	}()
	const layout = "Mon Jan 2 15:04:05"
	infobox.Border.FgColor = ui.ColorWhite
	infobox.Text = "Refresh at " + time.Now().Format(layout)
	jenkins.Poll()
	for _, k := range jenkins.GetAllJobs() {
		addJob(ls, k, redbox, yellowbox, greenbox)
	}
}

func resetBox(infobox *ui.Par, redbox *ui.Par, yellowbox *ui.Par, greenbox *ui.Par) {
	redbox.BgColor = ui.ColorBlack
	yellowbox.BgColor = ui.ColorBlack
	greenbox.BgColor = ui.ColorBlack
}

func addJob(list *ui.List, job *gojenkins.Job, redbox *ui.Par, yellowbox *ui.Par, greenbox *ui.Par) {
	if filterBuildName == nil || (filterBuildName != nil && filterBuildName.MatchString(job.GetName())) {
		str := job.GetName()
		if job.GetLastBuild() != nil {
			if job.IsRunning() {
				str = "...building " + str
			}
			str += " " + " " + job.GetLastBuild().GetResult()
			switch job.GetLastBuild().GetResult() {
			case "SUCCESS":
				greenbox.BgColor = ui.ColorGreen
			case "UNSTABLE":
				yellowbox.BgColor = ui.ColorYellow
			case "FAILURE":
				redbox.BgColor = ui.ColorRed
			}
		}
		list.Items = append(list.Items, str)
	}
}

// TODO make new widget traffic light
// Waiting for canvas from termui
func initWidgets() (*ui.List, *ui.Par, *ui.Par, *ui.Par, *ui.Par) {
	ui.UseTheme("Jenkins Term UI")

	title := "q to quit - " + *jenkinsUrl
	if *filter != "" {
		title += " filter on " + *filter
	}
	p := ui.NewPar(title)
	_, h := tm.Size()
	p.Height = 3
	p.TextFgColor = ui.ColorWhite
	p.Border.Label = "Go Jenkins Dashboard"
	p.Border.FgColor = ui.ColorCyan

	info := ui.NewPar("")
	info.Height = 3
	info.Y = h - 3
	info.TextFgColor = ui.ColorWhite
	info.Border.FgColor = ui.ColorWhite

	ls := ui.NewList()
	ls.ItemFgColor = ui.ColorYellow
	ls.Border.Label = "Jobs"
	ls.Y = 3
	ls.Height = h - 6

	width, height := 4, 5
	redbox, yellowbox, greenbox := ui.NewPar(""), ui.NewPar(""), ui.NewPar("")
	redbox.HasBorder, yellowbox.HasBorder, greenbox.HasBorder = false, false, false
	redbox.Height, yellowbox.Height, greenbox.Height = height, height, height
	redbox.Width, yellowbox.Width, greenbox.Width = width, width, width
	redbox.BgColor = ui.ColorRed
	yellowbox.BgColor = ui.ColorYellow
	greenbox.BgColor = ui.ColorGreen

	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(12, 0, p),
		),
		ui.NewRow(
			ui.NewCol(10, 0, ls),
			ui.NewCol(2, 0, redbox, yellowbox, greenbox),
		),
		ui.NewRow(
			ui.NewCol(12, 0, info),
		),
	)
	ui.Body.Align()
	ui.Render(ui.Body)
	return ls, info, redbox, yellowbox, greenbox
}
<commit_msg>fix : bump gojenkins master<commit_after>package main

import (
	"flag"
	"fmt"
	"regexp"
	"time"

	"github.com/bndr/gojenkins"
	ui "github.com/gizak/termui"
	"github.com/golang/glog"
	tm "github.com/nsf/termbox-go"
)

func init() {
	flag.Parse()
}

var sampleInterval = flag.Duration("interval", 5*time.Second, "Interval between sampling (default:5s)")
var jenkinsUrl = flag.String("jenkinsUrl", "", "Jenkins Url")
var filter = flag.String("filter", "", "Filter job")

var filterBuildName *regexp.Regexp

func main() {
	defer glog.Flush()
	flag.Parse()

	err := ui.Init()
	if err != nil {
		panic(err)
	}
	defer ui.Close()

	jenkins, err := gojenkins.CreateJenkins(*jenkinsUrl).Init()
	if err != nil {
		panic(err)
	}
	ls, infobox, redbox, yellowbox, greenbox := initWidgets()

	if *filter != "" {
		filterBuildName = regexp.MustCompile(*filter)
	}

	evt := make(chan tm.Event)
	go func() {
		for {
			evt <- tm.PollEvent()
		}
	}()

	ticker := time.NewTicker(*sampleInterval).C
	for {
		select {
		case e := <-evt:
			if e.Type == tm.EventKey && e.Ch == 'q' {
				return
			}
		case <-ticker:
			// alway resize, strange behaviour with tm.EventResize
			resizeUI(ls)
			ls.Items = ls.Items[:0]
			resetBox(infobox, redbox, yellowbox, greenbox)
			jenkinsPoll(jenkins, infobox, ls, redbox, yellowbox, greenbox)
			ui.Render(ui.Body)
		}
	}
}

func resizeUI(ls *ui.List) {
	w, h := tm.Size()
	ui.Body.Width = w
	ls.Height = h - 6
	ui.Body.Align()
}

func jenkinsPoll(jenkins *gojenkins.Jenkins, infobox *ui.Par, ls *ui.List, redbox *ui.Par, yellowbox *ui.Par, greenbox *ui.Par) {
	defer func() {
		if r := recover(); r != nil {
			infobox.Border.FgColor = ui.ColorRed
			//err := fmt.Errorf("%v", r)
			infobox.Text += " : /!\\ Jenkins is currently unreachable"
		}
	}()
	const layout = "Mon Jan 2 15:04:05"
	infobox.Border.FgColor = ui.ColorWhite
	infobox.Text = "Refresh at " + time.Now().Format(layout)
	jenkins.Poll()
	jobs, err := jenkins.GetAllJobs()
	if err != nil {
		infobox.Text = "Error with getAllJobs " + fmt.Sprintf("%s", err)
	}
	for _, k := range jobs {
		addJob(ls, k, redbox, yellowbox, greenbox)
	}
}

func resetBox(infobox *ui.Par, redbox *ui.Par, yellowbox *ui.Par, greenbox *ui.Par) {
	redbox.BgColor = ui.ColorBlack
	yellowbox.BgColor = ui.ColorBlack
	greenbox.BgColor = ui.ColorBlack
}

func addJob(list *ui.List, job *gojenkins.Job, redbox *ui.Par, yellowbox *ui.Par, greenbox *ui.Par) {
	if filterBuildName == nil || (filterBuildName != nil && filterBuildName.MatchString(job.GetName())) {
		str := job.GetName()
		lastBuild, _ := job.GetLastBuild()
		if lastBuild != nil {
			isRunning, _ := job.IsRunning()
			if isRunning {
				str = "...building " + str
			}
			str += " " + " " + lastBuild.GetResult()
			switch lastBuild.GetResult() {
			case "SUCCESS":
				greenbox.BgColor = ui.ColorGreen
			case "UNSTABLE":
				yellowbox.BgColor = ui.ColorYellow
			case "FAILURE":
				redbox.BgColor = ui.ColorRed
			}
		}
		list.Items = append(list.Items, str)
	}
}

// TODO make new widget traffic light
// Waiting for canvas from termui
func initWidgets() (*ui.List, *ui.Par, *ui.Par, *ui.Par, *ui.Par) {
	ui.UseTheme("Jenkins Term UI")

	title := "q to quit - " + *jenkinsUrl
	if *filter != "" {
		title += " filter on " + *filter
	}
	p := ui.NewPar(title)
	_, h := tm.Size()
	p.Height = 3
	p.TextFgColor = ui.ColorWhite
	p.Border.Label = "Go Jenkins Dashboard"
	p.Border.FgColor = ui.ColorCyan

	info := ui.NewPar("")
	info.Height = 3
	info.Y = h - 3
	info.TextFgColor = ui.ColorWhite
	info.Border.FgColor = ui.ColorWhite

	ls := ui.NewList()
	ls.ItemFgColor = ui.ColorYellow
	ls.Border.Label = "Jobs"
	ls.Y = 3
	ls.Height = h - 6

	width, height := 4, 5
	redbox, yellowbox, greenbox := ui.NewPar(""), ui.NewPar(""), ui.NewPar("")
	redbox.HasBorder, yellowbox.HasBorder, greenbox.HasBorder = false, false, false
	redbox.Height, yellowbox.Height, greenbox.Height = height, height, height
	redbox.Width, yellowbox.Width, greenbox.Width = width, width, width
	redbox.BgColor = ui.ColorRed
	yellowbox.BgColor = ui.ColorYellow
	greenbox.BgColor = ui.ColorGreen

	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(12, 0, p),
		),
		ui.NewRow(
			ui.NewCol(10, 0, ls),
			ui.NewCol(2, 0, redbox, yellowbox, greenbox),
		),
		ui.NewRow(
			ui.NewCol(12, 0, info),
		),
	)
	ui.Body.Align()
	ui.Render(ui.Body)
	return ls, info, redbox, yellowbox, greenbox
}
<|endoftext|>


<commit_before>package fasta

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"regexp"

	"github.com/brentp/xopen"
	"github.com/shenwei356/bio/seq"
	"github.com/shenwei356/util/byteutil"
)

// FastaRecord struct
type FastaRecord struct {
	ID   []byte   // id
	Name []byte   // full name
	Seq  *seq.Seq // seq
}

func (fastRecord FastaRecord) String() string {
	return fmt.Sprintf(">%s\n%s", fastRecord.Name,
		byteutil.WrapByteSlice(fastRecord.Seq.Seq, 70))
}

// NewFastaRecord is constructor of type FastaRecord
func NewFastaRecord(t *seq.Alphabet, id, name, s []byte) (*FastaRecord, error) {
	seq, err := seq.NewSeq(t, s)
	if err != nil {
		return nil, fmt.Errorf("error when parsing seq: %s (%s)", id, err)
	}
	return &FastaRecord{id, name, seq}, nil
}

// FormatSeq formats output, i.e. wrap string into fixed width
func (fastRecord *FastaRecord) FormatSeq(width int) []byte {
	return byteutil.WrapByteSlice(fastRecord.Seq.Seq, width)
}

// FastaRecordChunk  is
type FastaRecordChunk struct {
	ID   uint64
	Data []*FastaRecord
	Err  error
}

// FastaReader asynchronously parse FASTA file with buffer,
// each buffer contain a chunk of multiple fasta records (FastaRecordChunk).
// FastaReader also support safe cancellation.
type FastaReader struct {
	t  *seq.Alphabet // alphabet
	fh *xopen.Reader // file handle, xopen is such a wonderful package

	BufferSize int                   // buffer size
	ChunkSize  int                   // chunk size
	Ch         chan FastaRecordChunk // chanel for output of records chunks
	IDRegexp   *regexp.Regexp        // regexp ofr parsing record id

	firstseq  bool          // for guess alphabet by the first seq
	done      chan struct{} // for cancellation
	finished  bool          // for cancellation
	cancelled bool          // for cancellation
}

// regexp for checking idRegexp string.
// The regular expression must contains "(" and ")" to capture matched ID
var reCheckIDregexpStr = regexp.MustCompile(`\(.+\)`)

// DefaultIDRegexp is the default ID parsing regular expression
var DefaultIDRegexp = `^([^\s]+)\s?`

// NewFastaReader is constructor of FastaReader.
//
// Parameters:
//
//        t            sequence alphabet
//                     if nil is given, it will guess alphabet by the first record
//        file         file name, "-" for stdin
//        bufferSize   buffer size
//        chunkSize    chunk size
//        idRegexp     id parsing regular expression string, must contains "(" and ")" to capture matched ID
//                     "" for default value: `^([^\s]+)\s?`
//                     if record head does not match the idRegxp, whole name will be the id
//
func NewFastaReader(t *seq.Alphabet, file string, bufferSize int, chunkSize int, idRegexp string) (*FastaReader, error) {
	if bufferSize < 0 {
		bufferSize = 0
	}
	if chunkSize < 1 {
		chunkSize = 1
	}

	var r *regexp.Regexp
	if idRegexp == "" {
		r = regexp.MustCompile(DefaultIDRegexp)
	} else {
		if !reCheckIDregexpStr.MatchString(idRegexp) {
			return nil, fmt.Errorf(`regular expression must contains "(" and ")" to capture matched ID. default: %s`, DefaultIDRegexp)
		}
		var err error
		r, err = regexp.Compile(idRegexp)
		if err != nil {
			return nil, fmt.Errorf("fail to compile regexp: %s", idRegexp)
		}
	}

	fh, err := xopen.Ropen(file)
	if err != nil {
		return nil, err
	}

	fastaReader := &FastaReader{
		t:          t,
		fh:         fh,
		BufferSize: bufferSize,
		ChunkSize:  chunkSize,
		Ch:         make(chan FastaRecordChunk, bufferSize),
		IDRegexp:   r,
		firstseq:   true,
		done:       make(chan struct{}),
		finished:   false,
		cancelled:  false,
	}

	fastaReader.read()

	return fastaReader, nil
}

var reTrimRightSpace = regexp.MustCompile(`[\r\n]+$`)
var reTrimSpace = regexp.MustCompile(`[\r\n\s]+`)

// ErrorCanceled means that the reading process is canceled
var ErrorCanceled = errors.New("reading canceled")

func (fastaReader *FastaReader) read() {
	go func() {
		reader := bufio.NewReader(fastaReader.fh)
		buffer := bytes.Buffer{}
		var i int
		var id uint64
		var hasSeq bool
		var lastName, thisName []byte
		chunkData := make([]*FastaRecord, fastaReader.ChunkSize)

		for {
			select {
			case <-fastaReader.done:
				if !fastaReader.finished {
					fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], ErrorCanceled}

					fastaReader.finished = true
					fastaReader.fh.Close()
					close(fastaReader.Ch)
					return
				}
			default:

			}

			line, err := reader.ReadBytes('\n')
			if err != nil { // end of file
				fastaReader.finished = true
				fastaReader.fh.Close()

				buffer.Write(line)
				sequence := []byte(string(reTrimSpace.ReplaceAll(buffer.Bytes(), []byte(""))))
				buffer.Reset()

				fastaRecord, err := NewFastaRecord(fastaReader.t, fastaReader.parseHeadID(lastName), lastName, sequence)
				if err != nil {
					fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], err}
					fastaReader.fh.Close()
					close(fastaReader.Ch)
					return
				}
				chunkData[i] = fastaRecord
				i++
				fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], nil}
				close(fastaReader.Ch)

				return
			}

			if line[0] == '>' {
				hasSeq = true
				thisName = reTrimRightSpace.ReplaceAll(line[1:], []byte(""))
				if buffer.Len() > 0 { // no-first seq head
					// see https://golang.org/pkg/bufio/#Scanner.Bytes
					// The underlying array may point to data that will be
					// overwritten by a subsequent call to Scan.
					// It does no allocation.
					sequence := []byte(string(reTrimSpace.ReplaceAll(buffer.Bytes(), []byte(""))))
					buffer.Reset()

					// !!!! this brings bug! !!!!
					// or we can create a new bytes.Buffer
					// sequence := buffer.Bytes()
					// buffer = bytes.Buffer{}

					if fastaReader.firstseq {
						if fastaReader.t == nil {
							fastaReader.t = seq.GuessAlphabetLessConservatively(sequence)
						}
						fastaReader.firstseq = false
					}
					fastaRecord, err := NewFastaRecord(fastaReader.t, fastaReader.parseHeadID(lastName), lastName, sequence)
					if err != nil {
						fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], err}
						fastaReader.fh.Close()
						close(fastaReader.Ch)
						return
					}

					chunkData[i] = fastaRecord
					i++
					if i == fastaReader.ChunkSize {
						fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], nil}
						id++
						i = 0
						chunkData = make([]*FastaRecord, fastaReader.ChunkSize)
					}

					lastName = thisName
				} else { // first sequence name
					lastName = thisName
				}
			} else if hasSeq { // append sequence
				buffer.Write(line)
			} else {
				// some line before the first "^>"
			}
		}
	}()
}

func (fastaReader *FastaReader) parseHeadID(head []byte) []byte {
	found := fastaReader.IDRegexp.FindAllSubmatch(head, -1)
	if found == nil { // not match
		return head
	}
	return found[0][1]
}

// Cancel method cancel the reading process
func (fastaReader *FastaReader) Cancel() {
	if !fastaReader.finished && !fastaReader.cancelled {
		close(fastaReader.done)
		fastaReader.cancelled = true
	}
}

// Alphabet returns Alphabet of the file
func (fastaReader *FastaReader) Alphabet() *seq.Alphabet {
	return fastaReader.t
}
<commit_msg>fix bug of failing to guess alphabet when only one records in file<commit_after>package fasta

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"regexp"

	"github.com/brentp/xopen"
	"github.com/shenwei356/bio/seq"
	"github.com/shenwei356/util/byteutil"
)

// FastaRecord struct
type FastaRecord struct {
	ID   []byte   // id
	Name []byte   // full name
	Seq  *seq.Seq // seq
}

func (fastRecord FastaRecord) String() string {
	return fmt.Sprintf(">%s\n%s", fastRecord.Name,
		byteutil.WrapByteSlice(fastRecord.Seq.Seq, 70))
}

// NewFastaRecord is constructor of type FastaRecord
func NewFastaRecord(t *seq.Alphabet, id, name, s []byte) (*FastaRecord, error) {
	seq, err := seq.NewSeq(t, s)
	if err != nil {
		return nil, fmt.Errorf("error when parsing seq: %s (%s)", id, err)
	}
	return &FastaRecord{id, name, seq}, nil
}

// FormatSeq formats output, i.e. wrap string into fixed width
func (fastRecord *FastaRecord) FormatSeq(width int) []byte {
	return byteutil.WrapByteSlice(fastRecord.Seq.Seq, width)
}

// FastaRecordChunk  is
type FastaRecordChunk struct {
	ID   uint64
	Data []*FastaRecord
	Err  error
}

// FastaReader asynchronously parse FASTA file with buffer,
// each buffer contain a chunk of multiple fasta records (FastaRecordChunk).
// FastaReader also support safe cancellation.
type FastaReader struct {
	t  *seq.Alphabet // alphabet
	fh *xopen.Reader // file handle, xopen is such a wonderful package

	BufferSize int                   // buffer size
	ChunkSize  int                   // chunk size
	Ch         chan FastaRecordChunk // chanel for output of records chunks
	IDRegexp   *regexp.Regexp        // regexp ofr parsing record id

	firstseq  bool          // for guess alphabet by the first seq
	done      chan struct{} // for cancellation
	finished  bool          // for cancellation
	cancelled bool          // for cancellation
}

// regexp for checking idRegexp string.
// The regular expression must contains "(" and ")" to capture matched ID
var reCheckIDregexpStr = regexp.MustCompile(`\(.+\)`)

// DefaultIDRegexp is the default ID parsing regular expression
var DefaultIDRegexp = `^([^\s]+)\s?`

// NewFastaReader is constructor of FastaReader.
//
// Parameters:
//
//        t            sequence alphabet
//                     if nil is given, it will guess alphabet by the first record
//        file         file name, "-" for stdin
//        bufferSize   buffer size
//        chunkSize    chunk size
//        idRegexp     id parsing regular expression string, must contains "(" and ")" to capture matched ID
//                     "" for default value: `^([^\s]+)\s?`
//                     if record head does not match the idRegxp, whole name will be the id
//
func NewFastaReader(t *seq.Alphabet, file string, bufferSize int, chunkSize int, idRegexp string) (*FastaReader, error) {
	if bufferSize < 0 {
		bufferSize = 0
	}
	if chunkSize < 1 {
		chunkSize = 1
	}

	var r *regexp.Regexp
	if idRegexp == "" {
		r = regexp.MustCompile(DefaultIDRegexp)
	} else {
		if !reCheckIDregexpStr.MatchString(idRegexp) {
			return nil, fmt.Errorf(`regular expression must contains "(" and ")" to capture matched ID. default: %s`, DefaultIDRegexp)
		}
		var err error
		r, err = regexp.Compile(idRegexp)
		if err != nil {
			return nil, fmt.Errorf("fail to compile regexp: %s", idRegexp)
		}
	}

	fh, err := xopen.Ropen(file)
	if err != nil {
		return nil, err
	}

	fastaReader := &FastaReader{
		t:          t,
		fh:         fh,
		BufferSize: bufferSize,
		ChunkSize:  chunkSize,
		Ch:         make(chan FastaRecordChunk, bufferSize),
		IDRegexp:   r,
		firstseq:   true,
		done:       make(chan struct{}),
		finished:   false,
		cancelled:  false,
	}

	fastaReader.read()

	return fastaReader, nil
}

var reTrimRightSpace = regexp.MustCompile(`[\r\n]+$`)
var reTrimSpace = regexp.MustCompile(`[\r\n\s]+`)

// ErrorCanceled means that the reading process is canceled
var ErrorCanceled = errors.New("reading canceled")

func (fastaReader *FastaReader) read() {
	go func() {
		reader := bufio.NewReader(fastaReader.fh)
		buffer := bytes.Buffer{}
		var i int
		var id uint64
		var hasSeq bool
		var lastName, thisName []byte
		chunkData := make([]*FastaRecord, fastaReader.ChunkSize)

		for {
			select {
			case <-fastaReader.done:
				if !fastaReader.finished {
					fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], ErrorCanceled}

					fastaReader.finished = true
					fastaReader.fh.Close()
					close(fastaReader.Ch)
					return
				}
			default:

			}

			line, err := reader.ReadBytes('\n')
			if err != nil { // end of file
				fastaReader.finished = true
				fastaReader.fh.Close()

				buffer.Write(line)
				sequence := []byte(string(reTrimSpace.ReplaceAll(buffer.Bytes(), []byte(""))))
				buffer.Reset()

				if fastaReader.firstseq {
					if fastaReader.t == nil {
						fastaReader.t = seq.GuessAlphabetLessConservatively(sequence)
					}
					fastaReader.firstseq = false
				}
				fastaRecord, err := NewFastaRecord(fastaReader.t, fastaReader.parseHeadID(lastName), lastName, sequence)
				if err != nil {
					fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], err}
					fastaReader.fh.Close()
					close(fastaReader.Ch)
					return
				}
				chunkData[i] = fastaRecord
				i++
				fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], nil}
				close(fastaReader.Ch)

				return
			}

			if line[0] == '>' {
				hasSeq = true
				thisName = reTrimRightSpace.ReplaceAll(line[1:], []byte(""))
				if buffer.Len() > 0 { // no-first seq head
					// see https://golang.org/pkg/bufio/#Scanner.Bytes
					// The underlying array may point to data that will be
					// overwritten by a subsequent call to Scan.
					// It does no allocation.
					sequence := []byte(string(reTrimSpace.ReplaceAll(buffer.Bytes(), []byte(""))))
					buffer.Reset()

					// !!!! this brings bug! !!!!
					// or we can create a new bytes.Buffer
					// sequence := buffer.Bytes()
					// buffer = bytes.Buffer{}

					if fastaReader.firstseq {
						if fastaReader.t == nil {
							fastaReader.t = seq.GuessAlphabetLessConservatively(sequence)
						}
						fastaReader.firstseq = false
					}
					fastaRecord, err := NewFastaRecord(fastaReader.t, fastaReader.parseHeadID(lastName), lastName, sequence)
					if err != nil {
						fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], err}
						fastaReader.fh.Close()
						close(fastaReader.Ch)
						return
					}

					chunkData[i] = fastaRecord
					i++
					if i == fastaReader.ChunkSize {
						fastaReader.Ch <- FastaRecordChunk{id, chunkData[0:i], nil}
						id++
						i = 0
						chunkData = make([]*FastaRecord, fastaReader.ChunkSize)
					}

					lastName = thisName
				} else { // first sequence name
					lastName = thisName
				}
			} else if hasSeq { // append sequence
				buffer.Write(line)
			} else {
				// some line before the first "^>"
			}
		}
	}()
}

func (fastaReader *FastaReader) parseHeadID(head []byte) []byte {
	found := fastaReader.IDRegexp.FindAllSubmatch(head, -1)
	if found == nil { // not match
		return head
	}
	return found[0][1]
}

// Cancel method cancel the reading process
func (fastaReader *FastaReader) Cancel() {
	if !fastaReader.finished && !fastaReader.cancelled {
		close(fastaReader.done)
		fastaReader.cancelled = true
	}
}

// Alphabet returns Alphabet of the file
func (fastaReader *FastaReader) Alphabet() *seq.Alphabet {
	return fastaReader.t
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"github.com/getsentry/raven-go"
	"log"
	"net/http"
	"os"
)

func trace() *raven.Stacktrace {
	return raven.NewStacktrace(0, 2, nil)
}

func main() {
	client, err := raven.NewClient(os.Args[1], map[string]string{"foo": "bar"})
	if err != nil {
		log.Fatal(err)
	}
	httpReq, _ := http.NewRequest("GET", "http://example.com/foo?bar=true", nil)
	httpReq.RemoteAddr = "127.0.0.1:80"
	httpReq.Header = http.Header{"Content-Type": {"text/html"}, "Content-Length": {"42"}}
	packet := &raven.Packet{Message: "Test report", Interfaces: []raven.Interface{raven.NewException(errors.New("example"), trace()), raven.NewHttp(httpReq)}}
	_, ch := client.Capture(packet, nil)
	if err = <-ch; err != nil {
		log.Fatal(err)
	}
	log.Print("sent packet successfully")
}
<commit_msg>Issue #36 - add another example of raven-go package usage<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/getsentry/raven-go"
	"log"
	"net/http"
	"os"
)

func trace() *raven.Stacktrace {
	return raven.NewStacktrace(0, 2, nil)
}

func main() {
	client, err := raven.NewClient(os.Args[1], map[string]string{"foo": "bar"})
	if err != nil {
		log.Fatal(err)
	}
	httpReq, _ := http.NewRequest("GET", "http://example.com/foo?bar=true", nil)
	httpReq.RemoteAddr = "127.0.0.1:80"
	httpReq.Header = http.Header{"Content-Type": {"text/html"}, "Content-Length": {"42"}}
	packet := &raven.Packet{Message: "Test report", Interfaces: []raven.Interface{raven.NewException(errors.New("example"), trace()), raven.NewHttp(httpReq)}}
	_, ch := client.Capture(packet, nil)
	if err = <-ch; err != nil {
		log.Fatal(err)
	}
	log.Print("sent packet successfully")
}

// CheckError sends error report to sentry and records event id and error name to the logs
func CheckError(err error, r *http.Request) {
	packet = raven.NewPacket(err.Error(), raven.NewException(err, trace()), raven.NewHttp(r))
	eventID, _ := client.Capture(packet, nil)
	message := fmt.Sprintf("Error event with id \"%s\" - %s", eventID, err.Error())
	log.Println(message)
}
<|endoftext|>