<commit_before>package alita

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/mattn/go-runewidth"
)

type Justify int

const (
	JustLeft Justify = iota
	JustRight
	JustCenter
)

func (j Justify) Just(width int, s string) string {
	w := runewidth.StringWidth(s)
	switch j {
	case JustLeft:
		return s + strings.Repeat(" ", width-w)
	case JustRight:
		return strings.Repeat(" ", width-w) + s
	case JustCenter:
		n := width - w
		l, r := n/2, n/2
		if n%2 != 0 {
			r += 1
		}
		return strings.Repeat(" ", l) + s + strings.Repeat(" ", r)
	}
	return s + strings.Repeat(" ", width-w)
}

var JUSTFIES_SEQUENCE = regexp.MustCompile("^[lrc]+$")

type Padding struct {
	justfies []Justify
	width    []int
}

func NewPadding() *Padding {
	return &Padding{}
}

func (p *Padding) SetJustfies(a []Justify) {
	p.justfies = a
}

func (m *Padding) String() string {
	return fmt.Sprint(*m)
}

func (p *Padding) Set(format string) error {
	if !JUSTFIES_SEQUENCE.MatchString(format) {
		return fmt.Errorf("padding: invalid format: %s", format)
	}
	a := make([]Justify, 0)
	for _, c := range format {
		switch c {
		case 'l':
			a = append(a, JustLeft)
		case 'r':
			a = append(a, JustRight)
		case 'c':
			a = append(a, JustCenter)
		}
	}
	p.SetJustfies(a)
	return nil
}

func (p *Padding) UpdateWidth(a []string) {
	if len(a) == 1 {
		return
	}
	for i, s := range a {
		w := runewidth.StringWidth(s)
		switch {
		case i == len(p.width):
			p.width = append(p.width, w)
		case w > p.width[i]:
			p.width[i] = w
		}
	}
}

func (p *Padding) justKind(i int) Justify {
	switch len(p.justfies) {
	case 0:
		return JustLeft
	case 1:
		return p.justfies[0]
	}
	j := (i-1)%(len(p.justfies)-1) + 1
	return p.justfies[j]
}

func (p *Padding) Format(a []string) []string {
	if len(a) == 1 {
		return a
	}
	for i := 0; i < len(a); i++ {
		a[i] = p.justKind(i).Just(p.width[i], a[i])
	}
	return a
}
<commit_msg>Fix panic if pass a longer string than the width to Justfy<commit_after>package alita

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/mattn/go-runewidth"
)

type Justify int

const (
	JustLeft Justify = iota
	JustRight
	JustCenter
)

func (j Justify) Just(width int, s string) string {
	w := runewidth.StringWidth(s)
	if width <= w {
		return s
	}
	switch j {
	case JustLeft:
		return s + strings.Repeat(" ", width-w)
	case JustRight:
		return strings.Repeat(" ", width-w) + s
	case JustCenter:
		n := width - w
		l, r := n/2, n/2
		if n%2 != 0 {
			r += 1
		}
		return strings.Repeat(" ", l) + s + strings.Repeat(" ", r)
	}
	return s + strings.Repeat(" ", width-w)
}

var JUSTFIES_SEQUENCE = regexp.MustCompile("^[lrc]+$")

type Padding struct {
	justfies []Justify
	width    []int
}

func NewPadding() *Padding {
	return &Padding{}
}

func (p *Padding) SetJustfies(a []Justify) {
	p.justfies = a
}

func (m *Padding) String() string {
	return fmt.Sprint(*m)
}

func (p *Padding) Set(format string) error {
	if !JUSTFIES_SEQUENCE.MatchString(format) {
		return fmt.Errorf("padding: invalid format: %s", format)
	}
	a := make([]Justify, 0)
	for _, c := range format {
		switch c {
		case 'l':
			a = append(a, JustLeft)
		case 'r':
			a = append(a, JustRight)
		case 'c':
			a = append(a, JustCenter)
		}
	}
	p.SetJustfies(a)
	return nil
}

func (p *Padding) UpdateWidth(a []string) {
	if len(a) == 1 {
		return
	}
	for i, s := range a {
		w := runewidth.StringWidth(s)
		switch {
		case i == len(p.width):
			p.width = append(p.width, w)
		case w > p.width[i]:
			p.width[i] = w
		}
	}
}

func (p *Padding) justKind(i int) Justify {
	switch len(p.justfies) {
	case 0:
		return JustLeft
	case 1:
		return p.justfies[0]
	}
	j := (i-1)%(len(p.justfies)-1) + 1
	return p.justfies[j]
}

func (p *Padding) Format(a []string) []string {
	if len(a) == 1 {
		return a
	}
	for i := 0; i < len(a); i++ {
		a[i] = p.justKind(i).Just(p.width[i], a[i])
	}
	return a
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"net/http"
	"strings"
	"syscall"
	"time"

	"github.com/Code-Hex/golet"
)

func main() {
	cctx, cancel := context.WithCancel(context.Background())
	go func() {
		<-time.After(time.Second * 10)
		cancel()
	}()

	p := golet.New(cctx)
	p.EnableColor()

	// Execution interval
	p.SetInterval(time.Second * 1)

	// Send TERM signal when context cancel
	p.SetCtxCancelSignal(syscall.SIGTERM)

	p.Env(map[string]string{
		"NAME":  "codehex",
		"VALUE": "121",
	})

	p.Add(
		golet.Service{
			Exec: "plackup --port $PORT",
			Tag:  "plack",
		},
		golet.Service{
			Exec:   "echo 'This is cron!!'",
			Every:  "30 * * * * *",
			Worker: 2,
			Tag:    "cron",
		},
		golet.Service{
			Exec: `perl -E 'sleep 2; say "THIS IS DIE PROGRAM"; die;'`,
			Tag:  "DIE-Perl",
		},
	)

	p.Add(golet.Service{
		Code:   serveCode(),
		Worker: 3,
	})

	p.Run()
}

func serveCode() func(context.Context) error {
	return func(ctx context.Context) error {
		c := ctx.(*golet.Context)
		c.Println("Hello golet!! Port:", c.Port())
		mux := http.NewServeMux()
		mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprintf(w, "Hello, World")
			buf := strings.NewReader("This is log string\nNew line1\nNew line2\nNew line3\n")
			c.Copy(buf)
		})
		panicChan := make(chan interface{}, 1)
		go func() {
			defer func() {
				if p := recover(); p != nil {
					panicChan <- p
				}
			}()
			if err := http.ListenAndServe(c.ServePort(), mux); err != nil {
				panic(err)
			}
		}()
		for {
			select {
			// You can notify signal received.
			case <-c.Recv():
				signal, err := c.Signal()
				if err != nil {
					c.Println(err.Error())
					return err
				}
				switch signal {
				case syscall.SIGTERM, syscall.SIGHUP, syscall.SIGINT:
					c.Println(signal.String())
					return nil
				}
			// To catch context cancel
			case <-ctx.Done():
				c.Println("context cancel")
				return nil
			// panic for ListenAndServe
			case p := <-panicChan:
				return fmt.Errorf("%#v", p)
			}
		}
	}
}
<commit_msg>Updated example<commit_after>package main

import (
	"context"
	"fmt"
	"net/http"
	"strings"
	"syscall"
	"time"

	"github.com/Code-Hex/golet"
)

func main() {
	cctx, cancel := context.WithCancel(context.Background())
	go func() {
		<-time.After(time.Second * 10)
		cancel()
	}()

	p := golet.New(cctx)
	p.EnableColor()

	// Execution interval
	p.SetInterval(time.Second * 1)

	// Send TERM signal when context cancel
	p.SetCtxCancelSignal(syscall.SIGTERM)

	p.Env(map[string]string{
		"NAME":  "codehex",
		"VALUE": "121",
	})

	p.Add(
		golet.Service{
			Exec: "plackup --port $PORT",
			Tag:  "plack",
		},
		golet.Service{
			Exec:   "echo 'This is cron!!'",
			Every:  "30 * * * * *",
			Worker: 2,
			Tag:    "cron",
		},
		golet.Service{
			Exec: `perl -E 'sleep 2; say "THIS IS DIE PROGRAM"; die;'`,
			Tag:  "DIE-Perl",
		},
	)

	p.Add(golet.Service{
		Code:   serveCode(),
		Worker: 3,
	})

	p.Run()
}

func serveCode() func(context.Context) error {
	return func(ctx context.Context) error {
		c := ctx.(*golet.Context)
		c.Println("Hello golet!! Port:", c.Port())
		mux := http.NewServeMux()
		mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprintf(w, "Hello, World")
			buf := strings.NewReader("This is log string\nNew line1\nNew line2\nNew line3\n")
			c.Copy(buf)
		})

		panicChan := make(chan interface{}, 1)
		srv := &http.Server{Addr: c.ServePort(), Handler: mux}

		// for ListenAndServe's error
		go func() {
			defer func() {
				if p := recover(); p != nil {
					panicChan <- p
				}
			}()
			if err := srv.ListenAndServe(); err != nil {
				panic(err)
			}
		}()

		// Wait channels
		for {
			select {
			// You can notify signal received.
			case <-c.Recv():
				signal, err := c.Signal()
				if err != nil {
					c.Println(err.Error())
					return err
				}
				switch signal {
				// If you send TERM or HUP, restart this callback immediately.
				case syscall.SIGTERM, syscall.SIGHUP:
					c.Println(signal.String())
					if err := srv.Shutdown(ctx); err != nil {
						return err
					}
					return fmt.Errorf("signal recieved SIGTERM, SIGHUP as error")
				// End of run
				case syscall.SIGINT:
					c.Println(signal.String())
					return nil
				}
			// To catch context cancel
			case <-ctx.Done():
				c.Println("context cancel")
				return srv.Shutdown(ctx)
			// panic for ListenAndServe
			case p := <-panicChan:
				return p.(error)
			}
		}
	}
}
<|endoftext|>


<commit_before>package elb

import (
	"fmt"

	"errors"

	log "github.com/Sirupsen/logrus"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/ec2metadata"
	"github.com/aws/aws-sdk-go/aws/session"
	aws_elb "github.com/aws/aws-sdk-go/service/elb"
	"github.com/sky-uk/feed/controller"
	"github.com/sky-uk/feed/util"
)

// ElbTag is the tag key used for identifying ELBs to attach to.
const ElbTag = "sky.uk/KubernetesClusterFrontend"

// New  creates a new ELB frontend
func New(region string, labelValue string, expectedNumber int) controller.Updater {
	initMetrics()
	log.Infof("ELB Front end region: %s cluster: %s expected frontends: %d", region, labelValue, expectedNumber)
	metadata := ec2metadata.New(session.New())
	return &elb{
		metadata:       metadata,
		awsElb:         aws_elb.New(session.New(&aws.Config{Region: &region})),
		labelValue:     labelValue,
		region:         region,
		expectedNumber: expectedNumber,
	}
}

// LoadBalancerDetails stores all the elb information we use.
type LoadBalancerDetails struct {
	Name         string
	DNSName      string
	HostedZoneID string
	Scheme       string
}

type elb struct {
	awsElb              ELB
	metadata            EC2Metadata
	labelValue          string
	region              string
	expectedNumber      int
	instanceID          string
	elbs                map[string]LoadBalancerDetails
	registeredFrontends int
}

// ELB interface to allow mocking of real calls to AWS as well as cutting down the methods from the real
// interface to only the ones we use
type ELB interface {
	DescribeLoadBalancers(input *aws_elb.DescribeLoadBalancersInput) (*aws_elb.DescribeLoadBalancersOutput, error)
	DescribeTags(input *aws_elb.DescribeTagsInput) (*aws_elb.DescribeTagsOutput, error)
	RegisterInstancesWithLoadBalancer(input *aws_elb.RegisterInstancesWithLoadBalancerInput) (*aws_elb.RegisterInstancesWithLoadBalancerOutput, error)
	DeregisterInstancesFromLoadBalancer(input *aws_elb.DeregisterInstancesFromLoadBalancerInput) (*aws_elb.DeregisterInstancesFromLoadBalancerOutput, error)
}

// EC2Metadata interface to allow mocking of the real calls to AWS
type EC2Metadata interface {
	Available() bool
	Region() (string, error)
	GetInstanceIdentityDocument() (ec2metadata.EC2InstanceIdentityDocument, error)
}

func (e *elb) Start() error {
	if e.labelValue == "" {
		return nil
	}

	id, err := e.metadata.GetInstanceIdentityDocument()
	if err != nil {
		return fmt.Errorf("unable to query ec2 metadata service for InstanceId: %v", err)
	}

	instance := id.InstanceID
	log.Infof("Attaching to ELBs from instance %s", instance)
	clusterFrontEnds, err := FindFrontEndElbs(e.awsElb, e.labelValue)

	if err != nil {
		return err
	}

	log.Infof("Found %d front ends", len(clusterFrontEnds))

	// Save these now so we can always know what we might have done
	// up until this point we have only read data
	e.elbs = clusterFrontEnds
	e.instanceID = instance
	registered := 0

	for _, frontend := range clusterFrontEnds {
		log.Infof("Registering instance %s with elb %s", instance, frontend.Name)
		_, err = e.awsElb.RegisterInstancesWithLoadBalancer(&aws_elb.RegisterInstancesWithLoadBalancerInput{
			Instances: []*aws_elb.Instance{
				{
					InstanceId: aws.String(instance),
				}},
			LoadBalancerName: aws.String(frontend.Name),
		})

		if err != nil {
			return fmt.Errorf("unable to register instance %s with elb %s: %v", instance, frontend.Name, err)
		}
		registered++

	}

	attachedFrontendGauge.Set(float64(registered))
	e.registeredFrontends = registered

	if e.expectedNumber > 0 && registered != e.expectedNumber {
		return fmt.Errorf("expected ELBs: %d actual: %d", e.expectedNumber, registered)
	}

	return nil
}

// FindFrontEndElbs finds all elbs tagged with 'sky.uk/KubernetesClusterFrontend=<labelValue>'
func FindFrontEndElbs(awsElb ELB, labelValue string) (map[string]LoadBalancerDetails, error) {
	maxTagQuery := 20
	// Find the load balancers that are tagged with this cluster name
	request := &aws_elb.DescribeLoadBalancersInput{}
	var lbNames []*string
	allLbs := make(map[string]LoadBalancerDetails)

	for {
		resp, err := awsElb.DescribeLoadBalancers(request)

		if err != nil {
			return nil, fmt.Errorf("unable to describe load balancers: %v", err)
		}

		for _, entry := range resp.LoadBalancerDescriptions {
			allLbs[*entry.LoadBalancerName] = LoadBalancerDetails{
				Name:         aws.StringValue(entry.LoadBalancerName),
				DNSName:      aws.StringValue(entry.DNSName),
				HostedZoneID: aws.StringValue(entry.CanonicalHostedZoneNameID),
				Scheme:       aws.StringValue(entry.Scheme),
			}
			lbNames = append(lbNames, entry.LoadBalancerName)
		}

		if resp.NextMarker == nil {
			break
		}

		// Set the next marker
		request = &aws_elb.DescribeLoadBalancersInput{
			Marker: resp.NextMarker,
		}
	}

	log.Infof("Found %d loadbalancers. Checking for %s tag set to %s", len(lbNames), ElbTag, labelValue)
	clusterFrontEnds := make(map[string]LoadBalancerDetails)
	partitions := util.Partition(len(lbNames), maxTagQuery)
	for _, partition := range partitions {
		names := lbNames[partition.Low:partition.High]
		output, err := awsElb.DescribeTags(&aws_elb.DescribeTagsInput{
			LoadBalancerNames: names,
		})

		if err != nil {
			return nil, fmt.Errorf("unable to describe tags: %v", err)
		}

		// todo cb error out if we already have an internal or public facing elb
		for _, description := range output.TagDescriptions {
			for _, tag := range description.Tags {
				if *tag.Key == ElbTag && *tag.Value == labelValue {
					log.Infof("Found frontend elb %s", *description.LoadBalancerName)
					lb := allLbs[*description.LoadBalancerName]
					clusterFrontEnds[lb.Scheme] = lb
				}
			}
		}
	}
	return clusterFrontEnds, nil
}

// Stop removes this instance from all the front end ELBs
func (e *elb) Stop() error {
	var failed = false
	for _, elb := range e.elbs {
		log.Infof("Deregistering instance %s with elb %s", e.instanceID, elb.Name)
		_, err := e.awsElb.DeregisterInstancesFromLoadBalancer(&aws_elb.DeregisterInstancesFromLoadBalancerInput{
			Instances:        []*aws_elb.Instance{{InstanceId: aws.String(e.instanceID)}},
			LoadBalancerName: aws.String(elb.Name),
		})

		if err != nil {
			log.Warnf("unable to deregister instance %s with elb %s: %v", e.instanceID, elb.Name, err)
			failed = true
		}
	}
	if failed {
		return errors.New("at least one ELB failed to detach")
	}
	return nil
}

// Health is a no-op atm. Could be updated in the future to check all the ELBs are still attached
func (e *elb) Health() error {
	return nil
}

func (e *elb) Update(controller.IngressUpdate) error {
	return nil
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func (e *elb) String() string {
	return "ELB frontend"
}
<commit_msg>Add elb package documentation<commit_after>/*
Package elb provides an updater for an ELB frontend to attach nginx to.
*/
package elb

import (
	"fmt"

	"errors"

	log "github.com/Sirupsen/logrus"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/ec2metadata"
	"github.com/aws/aws-sdk-go/aws/session"
	aws_elb "github.com/aws/aws-sdk-go/service/elb"
	"github.com/sky-uk/feed/controller"
	"github.com/sky-uk/feed/util"
)

// ElbTag is the tag key used for identifying ELBs to attach to.
const ElbTag = "sky.uk/KubernetesClusterFrontend"

// New  creates a new ELB frontend
func New(region string, labelValue string, expectedNumber int) controller.Updater {
	initMetrics()
	log.Infof("ELB Front end region: %s cluster: %s expected frontends: %d", region, labelValue, expectedNumber)
	metadata := ec2metadata.New(session.New())
	return &elb{
		metadata:       metadata,
		awsElb:         aws_elb.New(session.New(&aws.Config{Region: &region})),
		labelValue:     labelValue,
		region:         region,
		expectedNumber: expectedNumber,
	}
}

// LoadBalancerDetails stores all the elb information we use.
type LoadBalancerDetails struct {
	Name         string
	DNSName      string
	HostedZoneID string
	Scheme       string
}

type elb struct {
	awsElb              ELB
	metadata            EC2Metadata
	labelValue          string
	region              string
	expectedNumber      int
	instanceID          string
	elbs                map[string]LoadBalancerDetails
	registeredFrontends int
}

// ELB interface to allow mocking of real calls to AWS as well as cutting down the methods from the real
// interface to only the ones we use
type ELB interface {
	DescribeLoadBalancers(input *aws_elb.DescribeLoadBalancersInput) (*aws_elb.DescribeLoadBalancersOutput, error)
	DescribeTags(input *aws_elb.DescribeTagsInput) (*aws_elb.DescribeTagsOutput, error)
	RegisterInstancesWithLoadBalancer(input *aws_elb.RegisterInstancesWithLoadBalancerInput) (*aws_elb.RegisterInstancesWithLoadBalancerOutput, error)
	DeregisterInstancesFromLoadBalancer(input *aws_elb.DeregisterInstancesFromLoadBalancerInput) (*aws_elb.DeregisterInstancesFromLoadBalancerOutput, error)
}

// EC2Metadata interface to allow mocking of the real calls to AWS
type EC2Metadata interface {
	Available() bool
	Region() (string, error)
	GetInstanceIdentityDocument() (ec2metadata.EC2InstanceIdentityDocument, error)
}

func (e *elb) Start() error {
	if e.labelValue == "" {
		return nil
	}

	id, err := e.metadata.GetInstanceIdentityDocument()
	if err != nil {
		return fmt.Errorf("unable to query ec2 metadata service for InstanceId: %v", err)
	}

	instance := id.InstanceID
	log.Infof("Attaching to ELBs from instance %s", instance)
	clusterFrontEnds, err := FindFrontEndElbs(e.awsElb, e.labelValue)

	if err != nil {
		return err
	}

	log.Infof("Found %d front ends", len(clusterFrontEnds))

	// Save these now so we can always know what we might have done
	// up until this point we have only read data
	e.elbs = clusterFrontEnds
	e.instanceID = instance
	registered := 0

	for _, frontend := range clusterFrontEnds {
		log.Infof("Registering instance %s with elb %s", instance, frontend.Name)
		_, err = e.awsElb.RegisterInstancesWithLoadBalancer(&aws_elb.RegisterInstancesWithLoadBalancerInput{
			Instances: []*aws_elb.Instance{
				{
					InstanceId: aws.String(instance),
				}},
			LoadBalancerName: aws.String(frontend.Name),
		})

		if err != nil {
			return fmt.Errorf("unable to register instance %s with elb %s: %v", instance, frontend.Name, err)
		}
		registered++

	}

	attachedFrontendGauge.Set(float64(registered))
	e.registeredFrontends = registered

	if e.expectedNumber > 0 && registered != e.expectedNumber {
		return fmt.Errorf("expected ELBs: %d actual: %d", e.expectedNumber, registered)
	}

	return nil
}

// FindFrontEndElbs finds all elbs tagged with 'sky.uk/KubernetesClusterFrontend=<labelValue>'
func FindFrontEndElbs(awsElb ELB, labelValue string) (map[string]LoadBalancerDetails, error) {
	maxTagQuery := 20
	// Find the load balancers that are tagged with this cluster name
	request := &aws_elb.DescribeLoadBalancersInput{}
	var lbNames []*string
	allLbs := make(map[string]LoadBalancerDetails)

	for {
		resp, err := awsElb.DescribeLoadBalancers(request)

		if err != nil {
			return nil, fmt.Errorf("unable to describe load balancers: %v", err)
		}

		for _, entry := range resp.LoadBalancerDescriptions {
			allLbs[*entry.LoadBalancerName] = LoadBalancerDetails{
				Name:         aws.StringValue(entry.LoadBalancerName),
				DNSName:      aws.StringValue(entry.DNSName),
				HostedZoneID: aws.StringValue(entry.CanonicalHostedZoneNameID),
				Scheme:       aws.StringValue(entry.Scheme),
			}
			lbNames = append(lbNames, entry.LoadBalancerName)
		}

		if resp.NextMarker == nil {
			break
		}

		// Set the next marker
		request = &aws_elb.DescribeLoadBalancersInput{
			Marker: resp.NextMarker,
		}
	}

	log.Infof("Found %d loadbalancers. Checking for %s tag set to %s", len(lbNames), ElbTag, labelValue)
	clusterFrontEnds := make(map[string]LoadBalancerDetails)
	partitions := util.Partition(len(lbNames), maxTagQuery)
	for _, partition := range partitions {
		names := lbNames[partition.Low:partition.High]
		output, err := awsElb.DescribeTags(&aws_elb.DescribeTagsInput{
			LoadBalancerNames: names,
		})

		if err != nil {
			return nil, fmt.Errorf("unable to describe tags: %v", err)
		}

		// todo cb error out if we already have an internal or public facing elb
		for _, description := range output.TagDescriptions {
			for _, tag := range description.Tags {
				if *tag.Key == ElbTag && *tag.Value == labelValue {
					log.Infof("Found frontend elb %s", *description.LoadBalancerName)
					lb := allLbs[*description.LoadBalancerName]
					clusterFrontEnds[lb.Scheme] = lb
				}
			}
		}
	}
	return clusterFrontEnds, nil
}

// Stop removes this instance from all the front end ELBs
func (e *elb) Stop() error {
	var failed = false
	for _, elb := range e.elbs {
		log.Infof("Deregistering instance %s with elb %s", e.instanceID, elb.Name)
		_, err := e.awsElb.DeregisterInstancesFromLoadBalancer(&aws_elb.DeregisterInstancesFromLoadBalancerInput{
			Instances:        []*aws_elb.Instance{{InstanceId: aws.String(e.instanceID)}},
			LoadBalancerName: aws.String(elb.Name),
		})

		if err != nil {
			log.Warnf("unable to deregister instance %s with elb %s: %v", e.instanceID, elb.Name, err)
			failed = true
		}
	}
	if failed {
		return errors.New("at least one ELB failed to detach")
	}
	return nil
}

// Health is a no-op atm. Could be updated in the future to check all the ELBs are still attached
func (e *elb) Health() error {
	return nil
}

func (e *elb) Update(controller.IngressUpdate) error {
	return nil
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func (e *elb) String() string {
	return "ELB frontend"
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"net/mail"
	"net/smtp"
	"os"
	"strings"
	"text/template"

	"code.google.com/p/go.crypto/openpgp"
	"code.google.com/p/go.crypto/openpgp/armor"
	"code.google.com/p/goconf/conf"
)

var cmdEncrypt = &Command{
	Run: runEncrypt,

	Name:  "encrypt",
	Short: "encrypts mails from stdin with PGP/MIME",
	Long: `
Usage: postcrypt encrypt <sender> <receivers>

Help:
Encrypts mails from stdin with PGP/MIME. The mails will be forwarded to
<sender>. This address is best specified by postfix via the $sender variable.

The mails will be encrypted for each receiver in <receivers> if a key is
known to postcrypt. Receivers without a known key are ignored and may not
be able to read the mails later!

If no receiver has a key associated with them, the mail will be forwarded
as is and no encryption takes place.

To add keys, see 'postcrypt help add-key'.
`,
}

// template for mail header Content-Type.
var MailHeaderTpl = template.Must(template.New("content type").Parse(
	"multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"----postcrypt-{{ .Boundary }}\""))

// template for pgp/mime formated mail
var MailBodyTpl = template.Must(template.New("mail body").Parse(`
This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)
----postcrypt-{{ .Boundary }}
Content-Type: application/pgp-encrypted
Content-Description: PGP/MIME version identification

Version: 1

----postcrypt-{{ .Boundary }}
Content-Type: application/octet-stream; name="encrypted.asc"
Content-Description: OpenPGP encrypted message
Content-Disposition: inline; filename="encrypted.asc"

{{ .Message }}

----postcrypt-{{ .Boundary }}--
`))

type Envelope struct {
	Id         string
	Mail       *mail.Message
	Sender     string
	Recipients []string
}

type TemplateData struct {
	Message  *bytes.Buffer
	Boundary string
}

func runEncrypt(cmd *Command, args []string) {
	var err error
	var e Envelope
	var keys openpgp.EntityList
	var msg *mail.Message
	var sender string
	var recipients []string
	var log *Tee

	// generate 'unique' id for message
	e.Id = generateRandomString()[:8]

	log = NewTee("postcrypt")
	log.Info("encrypting message with id " + e.Id)

	if len(args) < 2 {
		return
	}

	sender = args[0]
	recipients = args[1:]
	msg, err = readMail()
	if err != nil {
		log.Crit(e.Id + " could not parse mail: " + err.Error())
		return
	}

	if !isEncrypted(e) {
		for _, rcpt := range recipients {
			e.Sender = sender
			e.Recipients = []string{rcpt}
			e.Mail = msg

			keys = getKeys(cmd.Config, e)
			if len(keys) > 0 {
				for _, k := range keys {
					log.Info(e.Id + " encrypting with key " + getKeyId(k) + " for " + rcpt)
				}

				var encrypted *bytes.Buffer
				encrypted, err = encryptMail(e, keys)
				if err != nil {
					log.Err(e.Id + "error encrypting mail. " + err.Error())
					sendMail(cmd.Config, e)
				}

				e = packMail(e, encrypted)
			} else {
				log.Info(e.Id + " no keys found, sending unmodified")
			}

			err = sendMail(cmd.Config, e)
			if err != nil {
				log.Crit(e.Id + " sending mail failed. " + err.Error())
			}
		}
	} else {
		log.Info(e.Id + " already encrypted, sending unmodified")
	}

}

func readMail() (*mail.Message, error) {
	var buffer *bytes.Buffer

	buffer = bytes.NewBuffer(nil)
	io.Copy(buffer, os.Stdin)
	return mail.ReadMessage(buffer)
}

func isEncrypted(e Envelope) bool {
	contenttype := e.Mail.Header.Get("Content-Type")
	return strings.Contains(contenttype, "multipart/encrypted")
}

func getKeys(c *conf.ConfigFile, e Envelope) openpgp.EntityList {
	var ids []string
	var path string
	var fh *os.File
	var err error
	var k openpgp.EntityList

	path, _ = c.GetString("main", "keyring")

	fh, err = os.Open(path)
	if err != nil {
		panic(err)
	}

	k, err = openpgp.ReadKeyRing(fh)
	if err != nil {
		panic(err)
	}

	ids = getIdsByEmails(c, k, e.Recipients)
	return getKeysByIds(k, ids)
}

func encryptMail(e Envelope, keys openpgp.EntityList) (*bytes.Buffer, error) {
	var err error
	var contenttype string
	var buffer *bytes.Buffer
	var armored io.WriteCloser
	var crypter io.WriteCloser

	buffer = bytes.NewBuffer(nil)

	armored, err = armor.Encode(buffer, "PGP MESSAGE", nil)
	if err != nil {
		return buffer, err
	}

	crypter, err = openpgp.Encrypt(armored, keys, nil, nil, nil)
	if err != nil {
		return buffer, err
	}

	contenttype = e.Mail.Header.Get("Content-Type")
	if contenttype == "" {
		contenttype = "text/plain"
	}
	fmt.Fprintf(crypter, "Content-Type: %s\n\n", contenttype)

	io.Copy(crypter, e.Mail.Body)
	crypter.Close()
	armored.Close()

	return buffer, nil
}

func packMail(e Envelope, encrypted *bytes.Buffer) Envelope {
	var data *TemplateData
	var body *bytes.Buffer
	var contenttype *bytes.Buffer

	body = bytes.NewBuffer(nil)
	contenttype = bytes.NewBuffer(nil)

	data = &TemplateData{
		Message:  encrypted,
		Boundary: generateRandomString()[:10],
	}

	MailBodyTpl.Execute(body, data)
	MailHeaderTpl.Execute(contenttype, data)

	e.Mail.Header["Content-Type"] = []string{contenttype.String()}
	e.Mail.Body = body
	return e
}

func serializeMail(e Envelope) *bytes.Buffer {
	var buffer *bytes.Buffer
	buffer = bytes.NewBuffer(nil)

	// header
	for key, values := range e.Mail.Header {
		for _, value := range values {
			fmt.Fprintf(buffer, "%s: %s\n", key, value)
		}
	}

	fmt.Fprintln(buffer, "")

	// body
	io.Copy(buffer, e.Mail.Body)
	//fmt.Fprintf(buffer, "%s", e.Mail.Body.String())

	return buffer
}

func sendMail(c *conf.ConfigFile, e Envelope) error {
	var addr string
	var err error
	var conn *smtp.Client

	addr, _ = c.GetString("main", "smtp")

	conn, err = smtp.Dial(addr)
	if err != nil {
		return err
	}

	if err = conn.Mail(e.Sender); err != nil {
		return err
	}

	for _, addr := range e.Recipients {
		if err = conn.Rcpt(addr); err != nil {
			return err
		}
	}

	w, err := conn.Data()
	if err != nil {
		return err
	}

	io.Copy(w, serializeMail(e))
	conn.Quit()
	return nil
}
<commit_msg>should fix #11<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"net/mail"
	"net/smtp"
	"os"
	"strings"
	"text/template"

	"code.google.com/p/go.crypto/openpgp"
	"code.google.com/p/go.crypto/openpgp/armor"
	"code.google.com/p/goconf/conf"
)

var cmdEncrypt = &Command{
	Run: runEncrypt,

	Name:  "encrypt",
	Short: "encrypts mails from stdin with PGP/MIME",
	Long: `
Usage: postcrypt encrypt <sender> <receivers>

Help:
Encrypts mails from stdin with PGP/MIME. The mails will be forwarded to
<sender>. This address is best specified by postfix via the $sender variable.

The mails will be encrypted for each receiver in <receivers> if a key is
known to postcrypt. Receivers without a known key are ignored and may not
be able to read the mails later!

If no receiver has a key associated with them, the mail will be forwarded
as is and no encryption takes place.

To add keys, see 'postcrypt help add-key'.
`,
}

// template for mail header Content-Type.
var MailHeaderTpl = template.Must(template.New("content type").Parse(
	"multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"----postcrypt-{{ .Boundary }}\""))

// template for pgp/mime formated mail
var MailBodyTpl = template.Must(template.New("mail body").Parse(`
This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)
----postcrypt-{{ .Boundary }}
Content-Type: application/pgp-encrypted
Content-Description: PGP/MIME version identification

Version: 1

----postcrypt-{{ .Boundary }}
Content-Type: application/octet-stream; name="encrypted.asc"
Content-Description: OpenPGP encrypted message
Content-Disposition: inline; filename="encrypted.asc"

{{ .Message }}

----postcrypt-{{ .Boundary }}--
`))

type Envelope struct {
	Id         string
	Mail       *mail.Message
	Sender     string
	Recipients []string
}

type TemplateData struct {
	Message  *bytes.Buffer
	Boundary string
}

func runEncrypt(cmd *Command, args []string) {
	var err error
	var e Envelope
	var keys openpgp.EntityList
	var msg *mail.Message
	var sender string
	var recipients []string
	var log *Tee

	// generate 'unique' id for message
	e.Id = generateRandomString()[:8]

	log = NewTee("postcrypt")
	log.Info("encrypting message with id " + e.Id)

	if len(args) < 2 {
		return
	}

	sender = args[0]
	recipients = args[1:]
	msg, err = readMail()
	if err != nil {
		log.Crit(e.Id + " could not parse mail: " + err.Error())
		return
	}

	e.Sender = sender
	e.Mail = msg

	if !isEncrypted(e) {
		for _, rcpt := range recipients {
			e.Recipients = []string{rcpt}

			keys = getKeys(cmd.Config, e)
			if len(keys) > 0 {
				for _, k := range keys {
					log.Info(e.Id + " encrypting with key " + getKeyId(k) + " for " + rcpt)
				}

				var encrypted *bytes.Buffer
				encrypted, err = encryptMail(e, keys)
				if err != nil {
					log.Err(e.Id + "error encrypting mail. " + err.Error())
					sendMail(cmd.Config, e)
				}

				e = packMail(e, encrypted)
			} else {
				log.Info(e.Id + " no keys found, sending unmodified")
			}

			err = sendMail(cmd.Config, e)
			if err != nil {
				log.Crit(e.Id + " sending mail failed. " + err.Error())
			}
		}
	} else {
		log.Info(e.Id + " already encrypted, sending unmodified")
	}

}

func readMail() (*mail.Message, error) {
	var buffer *bytes.Buffer

	buffer = bytes.NewBuffer(nil)
	io.Copy(buffer, os.Stdin)
	return mail.ReadMessage(buffer)
}

func isEncrypted(e Envelope) bool {
	contenttype := e.Mail.Header.Get("Content-Type")
	return strings.Contains(contenttype, "multipart/encrypted")
}

func getKeys(c *conf.ConfigFile, e Envelope) openpgp.EntityList {
	var ids []string
	var path string
	var fh *os.File
	var err error
	var k openpgp.EntityList

	path, _ = c.GetString("main", "keyring")

	fh, err = os.Open(path)
	if err != nil {
		panic(err)
	}

	k, err = openpgp.ReadKeyRing(fh)
	if err != nil {
		panic(err)
	}

	ids = getIdsByEmails(c, k, e.Recipients)
	return getKeysByIds(k, ids)
}

func encryptMail(e Envelope, keys openpgp.EntityList) (*bytes.Buffer, error) {
	var err error
	var contenttype string
	var buffer *bytes.Buffer
	var armored io.WriteCloser
	var crypter io.WriteCloser

	buffer = bytes.NewBuffer(nil)

	armored, err = armor.Encode(buffer, "PGP MESSAGE", nil)
	if err != nil {
		return buffer, err
	}

	crypter, err = openpgp.Encrypt(armored, keys, nil, nil, nil)
	if err != nil {
		return buffer, err
	}

	contenttype = e.Mail.Header.Get("Content-Type")
	if contenttype == "" {
		contenttype = "text/plain"
	}
	fmt.Fprintf(crypter, "Content-Type: %s\n\n", contenttype)

	io.Copy(crypter, e.Mail.Body)
	crypter.Close()
	armored.Close()

	return buffer, nil
}

func packMail(e Envelope, encrypted *bytes.Buffer) Envelope {
	var data *TemplateData
	var body *bytes.Buffer
	var contenttype *bytes.Buffer

	body = bytes.NewBuffer(nil)
	contenttype = bytes.NewBuffer(nil)

	data = &TemplateData{
		Message:  encrypted,
		Boundary: generateRandomString()[:10],
	}

	MailBodyTpl.Execute(body, data)
	MailHeaderTpl.Execute(contenttype, data)

	e.Mail.Header["Content-Type"] = []string{contenttype.String()}
	e.Mail.Body = body
	return e
}

func serializeMail(e Envelope) *bytes.Buffer {
	var buffer *bytes.Buffer
	buffer = bytes.NewBuffer(nil)

	// header
	for key, values := range e.Mail.Header {
		for _, value := range values {
			fmt.Fprintf(buffer, "%s: %s\n", key, value)
		}
	}

	fmt.Fprintln(buffer, "")

	// body
	io.Copy(buffer, e.Mail.Body)
	//fmt.Fprintf(buffer, "%s", e.Mail.Body.String())

	return buffer
}

func sendMail(c *conf.ConfigFile, e Envelope) error {
	var addr string
	var err error
	var conn *smtp.Client

	addr, _ = c.GetString("main", "smtp")

	conn, err = smtp.Dial(addr)
	if err != nil {
		return err
	}

	if err = conn.Mail(e.Sender); err != nil {
		return err
	}

	for _, addr := range e.Recipients {
		if err = conn.Rcpt(addr); err != nil {
			return err
		}
	}

	w, err := conn.Data()
	if err != nil {
		return err
	}

	io.Copy(w, serializeMail(e))
	conn.Quit()
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/nlopes/slack"
	"github.com/smarx/go-cowsay"
)

const maxRemainingCount = 240

type Item struct {
	Actions        map[string]bool
	RemainingCount int
	Text           string
	Channel        string
	Timestamp      string
}

func Process(item *Item, api *slack.Client) {
	text := item.Text
	if item.Actions["marquee"] {
		text += "     "
		runes := []rune(text)
		howMuch := (maxRemainingCount - item.RemainingCount) % len(runes)
		text = string(runes[howMuch:]) + string(runes[:howMuch])
	}
	if item.Actions["blink"] {
		if item.RemainingCount%2 == 0 {
			text = strings.Repeat(" ", len(text))
		}
	}
	if item.Actions["cow"] {
		text = "```\n" + cowsay.Format(text) + "\n```"
	} else if item.Actions["blink"] || item.Actions["marquee"] {
		text = "```" + text + "```"
	}
	item.RemainingCount -= 1
	go api.UpdateMessage(item.Channel, item.Timestamp, text)
}

func ProcessForever(incoming chan *Item, api *slack.Client) {
	ticker := time.Tick(250 * time.Millisecond)
	items := make([]*Item, 0, 10)
	for {
		select {
		case <-ticker:
			newItems := make([]*Item, 0, len(items))
			for i := range items {
				Process(items[i], api)
				if items[i].RemainingCount > 0 {
					newItems = append(newItems, items[i])
				}
			}
			items = newItems
		case item := <-incoming:
			items = append(items, item)
		}
	}
}

func FindTags(text string) (tags map[string]bool, stripped string) {
	tags = make(map[string]bool)
	stripped = text
	var possible = []string{"blink", "marquee", "cow"}

	for i := range possible {
		var tag = possible[i]
		var re = regexp.MustCompile(fmt.Sprintf("<%[1]s>(.*)</%[1]s>", tag))
		var newtext = re.ReplaceAllString(stripped, "$1")
		if newtext != stripped {
			tags[tag] = true
			stripped = newtext
		}
	}
	return
}

func main() {
	token := os.Getenv("TOKEN")

	if len(token) == 0 {
		fmt.Println("Missing auth token. Please visit https://api.slack.com/docs/oauth-test-tokens and get a token for your account. Then set the TOKEN environment variable to that value.")
		return
	}

	api := slack.New(token)

	itemc := make(chan *Item)
	go ProcessForever(itemc, api)

	response, err := api.AuthTest()
	if err != nil {
		log.Fatal(err)
	}

	UserID := response.UserID

	rtm := api.NewRTM()
	go rtm.ManageConnection()

Loop:
	for {
		select {
		case msg := <-rtm.IncomingEvents:
			switch ev := msg.Data.(type) {
			case *slack.ConnectedEvent:
				fmt.Println("Enhanced! You can now use <blink>, <marquee>, and <cow> to annoy your coworkers.")
			case *slack.MessageEvent:
				if len(ev.SubType) > 0 || ev.ReplyTo > 0 {
					continue
				}
				if ev.User != UserID {
					continue
				}
				tags, text := FindTags(ev.Text)
				if len(tags) > 0 {
					item := Item{
						Actions:        tags,
						RemainingCount: maxRemainingCount,
						Text:           text,
						Channel:        ev.Channel,
						Timestamp:      ev.Timestamp}
					if len(item.Actions) > 0 {
						itemc <- &item
					}
				}
			case *slack.InvalidAuthEvent:
				fmt.Println("Invalid credentials")
				break Loop
			default:
				// ignore everything else
			}
		}
	}
}
<commit_msg>Work with rune length rather than character length (important for blink+cow)<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/nlopes/slack"
	"github.com/smarx/go-cowsay"
)

const maxRemainingCount = 240

type Item struct {
	Actions        map[string]bool
	RemainingCount int
	Text           string
	Channel        string
	Timestamp      string
}

func Process(item *Item, api *slack.Client) {
	text := item.Text
	if item.Actions["marquee"] {
		text += "     "
		runes := []rune(text)
		howMuch := (maxRemainingCount - item.RemainingCount) % len(runes)
		text = string(runes[howMuch:]) + string(runes[:howMuch])
	}
	if item.Actions["blink"] {
		if item.RemainingCount%2 == 0 {
			text = strings.Repeat(" ", len([]rune(text)))
		}
	}
	if item.Actions["cow"] {
		text = "```\n" + cowsay.Format(text) + "\n```"
	} else if item.Actions["blink"] || item.Actions["marquee"] {
		text = "```" + text + "```"
	}
	item.RemainingCount -= 1
	go api.UpdateMessage(item.Channel, item.Timestamp, text)
}

func ProcessForever(incoming chan *Item, api *slack.Client) {
	ticker := time.Tick(250 * time.Millisecond)
	items := make([]*Item, 0, 10)
	for {
		select {
		case <-ticker:
			newItems := make([]*Item, 0, len(items))
			for i := range items {
				Process(items[i], api)
				if items[i].RemainingCount > 0 {
					newItems = append(newItems, items[i])
				}
			}
			items = newItems
		case item := <-incoming:
			items = append(items, item)
		}
	}
}

func FindTags(text string) (tags map[string]bool, stripped string) {
	tags = make(map[string]bool)
	stripped = text
	var possible = []string{"blink", "marquee", "cow"}

	for i := range possible {
		var tag = possible[i]
		var re = regexp.MustCompile(fmt.Sprintf("<%[1]s>(.*)</%[1]s>", tag))
		var newtext = re.ReplaceAllString(stripped, "$1")
		if newtext != stripped {
			tags[tag] = true
			stripped = newtext
		}
	}
	return
}

func main() {
	token := os.Getenv("TOKEN")

	if len(token) == 0 {
		fmt.Println("Missing auth token. Please visit https://api.slack.com/docs/oauth-test-tokens and get a token for your account. Then set the TOKEN environment variable to that value.")
		return
	}

	api := slack.New(token)

	itemc := make(chan *Item)
	go ProcessForever(itemc, api)

	response, err := api.AuthTest()
	if err != nil {
		log.Fatal(err)
	}

	UserID := response.UserID

	rtm := api.NewRTM()
	go rtm.ManageConnection()

Loop:
	for {
		select {
		case msg := <-rtm.IncomingEvents:
			switch ev := msg.Data.(type) {
			case *slack.ConnectedEvent:
				fmt.Println("Enhanced! You can now use <blink>, <marquee>, and <cow> to annoy your coworkers.")
			case *slack.MessageEvent:
				if len(ev.SubType) > 0 || ev.ReplyTo > 0 {
					continue
				}
				if ev.User != UserID {
					continue
				}
				tags, text := FindTags(ev.Text)
				if len(tags) > 0 {
					item := Item{
						Actions:        tags,
						RemainingCount: maxRemainingCount,
						Text:           text,
						Channel:        ev.Channel,
						Timestamp:      ev.Timestamp}
					if len(item.Actions) > 0 {
						itemc <- &item
					}
				}
			case *slack.InvalidAuthEvent:
				fmt.Println("Invalid credentials")
				break Loop
			default:
				// ignore everything else
			}
		}
	}
}
<|endoftext|>


<commit_before>package netsync

import (
	log "github.com/sirupsen/logrus"
	"gopkg.in/karalabe/cookiejar.v2/collections/prque"

	"github.com/bytom/protocol/bc"
)

const (
	maxBlockDistance = 64
	maxMsgSetSize    = 128
	newBlockChSize   = 64
)

// blockFetcher is responsible for accumulating block announcements from various peers
// and scheduling them for retrieval.
type blockFetcher struct {
	chain Chain
	peers *peerSet

	newBlockCh chan *blockMsg
	queue      *prque.Prque
	msgSet     map[bc.Hash]*blockMsg
}

//NewBlockFetcher creates a block fetcher to retrieve blocks of the new mined.
func newBlockFetcher(chain Chain, peers *peerSet) *blockFetcher {
	f := &blockFetcher{
		chain:      chain,
		peers:      peers,
		newBlockCh: make(chan *blockMsg, newBlockChSize),
		queue:      prque.New(),
		msgSet:     make(map[bc.Hash]*blockMsg),
	}
	go f.blockProcessor()
	return f
}

func (f *blockFetcher) blockProcessor() {
	for {
		height := f.chain.BestBlockHeight()
		for !f.queue.Empty() {
			msg := f.queue.PopItem().(*blockMsg)
			if msg.block.Height > height+1 {
				f.queue.Push(msg, -float32(msg.block.Height))
				break
			}

			f.insert(msg)
			delete(f.msgSet, msg.block.Hash())
		}
		f.add(<-f.newBlockCh)
	}
}

func (f *blockFetcher) add(msg *blockMsg) {
	bestHeight := f.chain.BestBlockHeight()
	if len(f.msgSet) > maxMsgSetSize || bestHeight > msg.block.Height || msg.block.Height-bestHeight > maxBlockDistance {
		return
	}

	blockHash := msg.block.Hash()
	if _, ok := f.msgSet[blockHash]; !ok {
		f.msgSet[blockHash] = msg
		f.queue.Push(msg, -float32(msg.block.Height))
		log.WithFields(log.Fields{
			"module":       logModule,
			"block height": msg.block.Height,
			"block hash":   blockHash.String(),
		}).Debug("blockFetcher receive mine block")
	}
}

func (f *blockFetcher) insert(msg *blockMsg) {
	if _, err := f.chain.ProcessBlock(msg.block); err != nil {
		peer := f.peers.getPeer(msg.peerID)
		if peer == nil {
			return
		}

		f.peers.addBanScore(msg.peerID, 20, 0, err.Error())
		return
	}

	if err := f.peers.broadcastMinedBlock(msg.block); err != nil {
		log.WithFields(log.Fields{"module": logModule, "err": err}).Error("blockFetcher fail on broadcast new block")
		return
	}
}

func (f *blockFetcher) processNewBlock(msg *blockMsg) {
	f.newBlockCh <- msg
}
<commit_msg>Fix new mined orphan block broadcast bug (#1592)<commit_after>package netsync

import (
	log "github.com/sirupsen/logrus"
	"gopkg.in/karalabe/cookiejar.v2/collections/prque"

	"github.com/bytom/protocol/bc"
)

const (
	maxBlockDistance = 64
	maxMsgSetSize    = 128
	newBlockChSize   = 64
)

// blockFetcher is responsible for accumulating block announcements from various peers
// and scheduling them for retrieval.
type blockFetcher struct {
	chain Chain
	peers *peerSet

	newBlockCh chan *blockMsg
	queue      *prque.Prque
	msgSet     map[bc.Hash]*blockMsg
}

//NewBlockFetcher creates a block fetcher to retrieve blocks of the new mined.
func newBlockFetcher(chain Chain, peers *peerSet) *blockFetcher {
	f := &blockFetcher{
		chain:      chain,
		peers:      peers,
		newBlockCh: make(chan *blockMsg, newBlockChSize),
		queue:      prque.New(),
		msgSet:     make(map[bc.Hash]*blockMsg),
	}
	go f.blockProcessor()
	return f
}

func (f *blockFetcher) blockProcessor() {
	for {
		height := f.chain.BestBlockHeight()
		for !f.queue.Empty() {
			msg := f.queue.PopItem().(*blockMsg)
			if msg.block.Height > height+1 {
				f.queue.Push(msg, -float32(msg.block.Height))
				break
			}

			f.insert(msg)
			delete(f.msgSet, msg.block.Hash())
		}
		f.add(<-f.newBlockCh)
	}
}

func (f *blockFetcher) add(msg *blockMsg) {
	bestHeight := f.chain.BestBlockHeight()
	if len(f.msgSet) > maxMsgSetSize || bestHeight > msg.block.Height || msg.block.Height-bestHeight > maxBlockDistance {
		return
	}

	blockHash := msg.block.Hash()
	if _, ok := f.msgSet[blockHash]; !ok {
		f.msgSet[blockHash] = msg
		f.queue.Push(msg, -float32(msg.block.Height))
		log.WithFields(log.Fields{
			"module":       logModule,
			"block height": msg.block.Height,
			"block hash":   blockHash.String(),
		}).Debug("blockFetcher receive mine block")
	}
}

func (f *blockFetcher) insert(msg *blockMsg) {
	isOrphan, err := f.chain.ProcessBlock(msg.block)
	if err != nil {
		peer := f.peers.getPeer(msg.peerID)
		if peer == nil {
			return
		}

		f.peers.addBanScore(msg.peerID, 20, 0, err.Error())
		return
	}

	if isOrphan {
		return
	}

	if err := f.peers.broadcastMinedBlock(msg.block); err != nil {
		log.WithFields(log.Fields{"module": logModule, "err": err}).Error("blockFetcher fail on broadcast new block")
		return
	}
}

func (f *blockFetcher) processNewBlock(msg *blockMsg) {
	f.newBlockCh <- msg
}
<|endoftext|>


<commit_before>package core

import (
	data "github.com/tendermint/go-wire/data"
	rpc "github.com/tendermint/tendermint/rpc/server"
	"github.com/tendermint/tendermint/rpc/types"
	ctypes "github.com/tendermint/tendermint/rpc/tendermint/core/types"
	"github.com/tendermint/tendermint/types"
)

// TODO: better system than "unsafe" prefix
var Routes = map[string]*rpc.RPCFunc{
	// subscribe/unsubscribe are reserved for websocket events.
	"subscribe":   rpc.NewWSRPCFunc(SubscribeResult, "event"),
	"unsubscribe": rpc.NewWSRPCFunc(UnsubscribeResult, "event"),

	// info API
	"status":               rpc.NewRPCFunc(StatusResult, ""),
	"net_info":             rpc.NewRPCFunc(NetInfoResult, ""),
	"blockchain":           rpc.NewRPCFunc(BlockchainInfoResult, "minHeight,maxHeight"),
	"genesis":              rpc.NewRPCFunc(GenesisResult, ""),
	"block":                rpc.NewRPCFunc(BlockResult, "height"),
	"commit":               rpc.NewRPCFunc(CommitResult, "height"),
	"tx":                   rpc.NewRPCFunc(TxResult, "hash,prove"),
	"validators":           rpc.NewRPCFunc(ValidatorsResult, ""),
	"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusStateResult, ""),
	"unconfirmed_txs":      rpc.NewRPCFunc(UnconfirmedTxsResult, ""),
	"num_unconfirmed_txs":  rpc.NewRPCFunc(NumUnconfirmedTxsResult, ""),

	// broadcast API
	"broadcast_tx_commit": rpc.NewRPCFunc(BroadcastTxCommitResult, "tx"),
	"broadcast_tx_sync":   rpc.NewRPCFunc(BroadcastTxSyncResult, "tx"),
	"broadcast_tx_async":  rpc.NewRPCFunc(BroadcastTxAsyncResult, "tx"),

	// abci API
	"abci_query": rpc.NewRPCFunc(ABCIQueryResult, "path,data,prove"),
	"abci_info":  rpc.NewRPCFunc(ABCIInfoResult, ""),

	// control API
	"dial_seeds":           rpc.NewRPCFunc(UnsafeDialSeedsResult, "seeds"),
	"unsafe_flush_mempool": rpc.NewRPCFunc(UnsafeFlushMempool, ""),
	"unsafe_set_config":    rpc.NewRPCFunc(UnsafeSetConfigResult, "type,key,value"),

	// profiler API
	"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfilerResult, "filename"),
	"unsafe_stop_cpu_profiler":  rpc.NewRPCFunc(UnsafeStopCPUProfilerResult, ""),
	"unsafe_write_heap_profile": rpc.NewRPCFunc(UnsafeWriteHeapProfileResult, "filename"),
}

func SubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
	return Subscribe(wsCtx, event)
}

func UnsubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
	return Unsubscribe(wsCtx, event)
}

func StatusResult() (ctypes.TMResult, error) {
	return Status()
}

func NetInfoResult() (ctypes.TMResult, error) {
	return NetInfo()
}

func UnsafeDialSeedsResult(seeds []string) (ctypes.TMResult, error) {
	return UnsafeDialSeeds(seeds)
}

func BlockchainInfoResult(min, max int) (ctypes.TMResult, error) {
	return BlockchainInfo(min, max)
}

func GenesisResult() (ctypes.TMResult, error) {
	return Genesis()
}

func BlockResult(height int) (ctypes.TMResult, error) {
	return Block(height)
}

func CommitResult(height int) (ctypes.TMResult, error) {
	return Commit(height)
}

func ValidatorsResult() (ctypes.TMResult, error) {
	return Validators()
}

func DumpConsensusStateResult() (ctypes.TMResult, error) {
	return DumpConsensusState()
}

func UnconfirmedTxsResult() (ctypes.TMResult, error) {
	return UnconfirmedTxs()
}

func NumUnconfirmedTxsResult() (ctypes.TMResult, error) {
	return NumUnconfirmedTxs()
}

// Tx allow user to query the transaction results. `nil` could mean the
// transaction is in the mempool, invalidated, or was not send in the first
// place.
func TxResult(hash []byte, prove bool) (ctypes.TMResult, error) {
	return Tx(hash, prove)
}

func BroadcastTxCommitResult(tx types.Tx) (ctypes.TMResult, error) {
	return BroadcastTxCommit(tx)
}

func BroadcastTxSyncResult(tx types.Tx) (ctypes.TMResult, error) {
	return BroadcastTxSync(tx)
}

func BroadcastTxAsyncResult(tx types.Tx) (ctypes.TMResult, error) {
	return BroadcastTxAsync(tx)
}

func ABCIQueryResult(path string, data data.Bytes, prove bool) (ctypes.TMResult, error) {
	return ABCIQuery(path, data, prove)
}

func ABCIInfoResult() (ctypes.TMResult, error) {
	return ABCIInfo()
}

func UnsafeFlushMempoolResult() (ctypes.TMResult, error) {
	return UnsafeFlushMempool()
}

func UnsafeSetConfigResult(typ, key, value string) (ctypes.TMResult, error) {
	return UnsafeSetConfig(typ, key, value)
}

func UnsafeStartCPUProfilerResult(filename string) (ctypes.TMResult, error) {
	return UnsafeStartCPUProfiler(filename)
}

func UnsafeStopCPUProfilerResult() (ctypes.TMResult, error) {
	return UnsafeStopCPUProfiler()
}

func UnsafeWriteHeapProfileResult(filename string) (ctypes.TMResult, error) {
	return UnsafeWriteHeapProfile(filename)
}
<commit_msg>remove unsafe_set_config<commit_after>package core

import (
	data "github.com/tendermint/go-wire/data"
	rpc "github.com/tendermint/tendermint/rpc/server"
	ctypes "github.com/tendermint/tendermint/rpc/tendermint/core/types"
	"github.com/tendermint/tendermint/rpc/types"
	"github.com/tendermint/tendermint/types"
)

// TODO: better system than "unsafe" prefix
var Routes = map[string]*rpc.RPCFunc{
	// subscribe/unsubscribe are reserved for websocket events.
	"subscribe":   rpc.NewWSRPCFunc(SubscribeResult, "event"),
	"unsubscribe": rpc.NewWSRPCFunc(UnsubscribeResult, "event"),

	// info API
	"status":               rpc.NewRPCFunc(StatusResult, ""),
	"net_info":             rpc.NewRPCFunc(NetInfoResult, ""),
	"blockchain":           rpc.NewRPCFunc(BlockchainInfoResult, "minHeight,maxHeight"),
	"genesis":              rpc.NewRPCFunc(GenesisResult, ""),
	"block":                rpc.NewRPCFunc(BlockResult, "height"),
	"commit":               rpc.NewRPCFunc(CommitResult, "height"),
	"tx":                   rpc.NewRPCFunc(TxResult, "hash,prove"),
	"validators":           rpc.NewRPCFunc(ValidatorsResult, ""),
	"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusStateResult, ""),
	"unconfirmed_txs":      rpc.NewRPCFunc(UnconfirmedTxsResult, ""),
	"num_unconfirmed_txs":  rpc.NewRPCFunc(NumUnconfirmedTxsResult, ""),

	// broadcast API
	"broadcast_tx_commit": rpc.NewRPCFunc(BroadcastTxCommitResult, "tx"),
	"broadcast_tx_sync":   rpc.NewRPCFunc(BroadcastTxSyncResult, "tx"),
	"broadcast_tx_async":  rpc.NewRPCFunc(BroadcastTxAsyncResult, "tx"),

	// abci API
	"abci_query": rpc.NewRPCFunc(ABCIQueryResult, "path,data,prove"),
	"abci_info":  rpc.NewRPCFunc(ABCIInfoResult, ""),

	// control API
	"dial_seeds":           rpc.NewRPCFunc(UnsafeDialSeedsResult, "seeds"),
	"unsafe_flush_mempool": rpc.NewRPCFunc(UnsafeFlushMempool, ""),

	// config is not in general thread safe. expose specifics if you need em
	// "unsafe_set_config":    rpc.NewRPCFunc(UnsafeSetConfigResult, "type,key,value"),

	// profiler API
	"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfilerResult, "filename"),
	"unsafe_stop_cpu_profiler":  rpc.NewRPCFunc(UnsafeStopCPUProfilerResult, ""),
	"unsafe_write_heap_profile": rpc.NewRPCFunc(UnsafeWriteHeapProfileResult, "filename"),
}

func SubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
	return Subscribe(wsCtx, event)
}

func UnsubscribeResult(wsCtx rpctypes.WSRPCContext, event string) (ctypes.TMResult, error) {
	return Unsubscribe(wsCtx, event)
}

func StatusResult() (ctypes.TMResult, error) {
	return Status()
}

func NetInfoResult() (ctypes.TMResult, error) {
	return NetInfo()
}

func UnsafeDialSeedsResult(seeds []string) (ctypes.TMResult, error) {
	return UnsafeDialSeeds(seeds)
}

func BlockchainInfoResult(min, max int) (ctypes.TMResult, error) {
	return BlockchainInfo(min, max)
}

func GenesisResult() (ctypes.TMResult, error) {
	return Genesis()
}

func BlockResult(height int) (ctypes.TMResult, error) {
	return Block(height)
}

func CommitResult(height int) (ctypes.TMResult, error) {
	return Commit(height)
}

func ValidatorsResult() (ctypes.TMResult, error) {
	return Validators()
}

func DumpConsensusStateResult() (ctypes.TMResult, error) {
	return DumpConsensusState()
}

func UnconfirmedTxsResult() (ctypes.TMResult, error) {
	return UnconfirmedTxs()
}

func NumUnconfirmedTxsResult() (ctypes.TMResult, error) {
	return NumUnconfirmedTxs()
}

// Tx allow user to query the transaction results. `nil` could mean the
// transaction is in the mempool, invalidated, or was not send in the first
// place.
func TxResult(hash []byte, prove bool) (ctypes.TMResult, error) {
	return Tx(hash, prove)
}

func BroadcastTxCommitResult(tx types.Tx) (ctypes.TMResult, error) {
	return BroadcastTxCommit(tx)
}

func BroadcastTxSyncResult(tx types.Tx) (ctypes.TMResult, error) {
	return BroadcastTxSync(tx)
}

func BroadcastTxAsyncResult(tx types.Tx) (ctypes.TMResult, error) {
	return BroadcastTxAsync(tx)
}

func ABCIQueryResult(path string, data data.Bytes, prove bool) (ctypes.TMResult, error) {
	return ABCIQuery(path, data, prove)
}

func ABCIInfoResult() (ctypes.TMResult, error) {
	return ABCIInfo()
}

func UnsafeFlushMempoolResult() (ctypes.TMResult, error) {
	return UnsafeFlushMempool()
}

func UnsafeSetConfigResult(typ, key, value string) (ctypes.TMResult, error) {
	return UnsafeSetConfig(typ, key, value)
}

func UnsafeStartCPUProfilerResult(filename string) (ctypes.TMResult, error) {
	return UnsafeStartCPUProfiler(filename)
}

func UnsafeStopCPUProfilerResult() (ctypes.TMResult, error) {
	return UnsafeStopCPUProfiler()
}

func UnsafeWriteHeapProfileResult(filename string) (ctypes.TMResult, error) {
	return UnsafeWriteHeapProfile(filename)
}
<|endoftext|>


<commit_before>package envflag

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
)

// Config provides configuration for this package
type Config struct {
	// DebugEnabled enables debug mode
	DebugEnabled bool
	// MinLength defines min length of flag key, in order to support shortcut
	MinLength int
	// EnvFlagDict is a user-defined env-flag map
	EnvFlagDict map[string]string
}

// DefaultConfig is the default configuration of envflag
var DefaultConfig = &Config{
	DebugEnabled: false,
	MinLength:    3,
	EnvFlagDict:  map[string]string{},
}

// config is the configuration of envflag package
var config = &Config{}

// Setup sets up this package with customized config
func Setup(c *Config) {
	if c.DebugEnabled {
		config.DebugEnabled = c.DebugEnabled
	} else {
		config.DebugEnabled = DefaultConfig.DebugEnabled
	}

	if c.MinLength != 0 {
		config.MinLength = c.MinLength
	} else {
		config.MinLength = DefaultConfig.MinLength
	}

	if c.EnvFlagDict != nil {
		config.EnvFlagDict = c.EnvFlagDict
	} else {
		config.EnvFlagDict = DefaultConfig.EnvFlagDict
	}
}

// envToFlag converts THIS_FORMAT to this-format
func envToFlag(e string) string {
	return strings.Replace(strings.ToLower(e), "_", "-", -1)
}

// flagToEnv converts this-format to THIS_FORMAT
func flagToEnv(f string) string {
	return strings.Replace(strings.ToUpper(f), "-", "_", -1)
}

// Parse parses the command-line flags from env and os.Args[1:].
// Value from env can be overrided by os.Args[1:].
// This function also add ENVIRONMENT VARIABLE to usage.
// It is extremely recommended to call this function in main()
// after all flags are defined and before flags are accessed by the program.
// NOTICE: flag.Parse() will be called by this function.
func Parse() error {
	if err := ProcessFlagWithEnv(); err != nil {
		return err
	}
	flag.Parse()
	return nil
}

// ProcessFlagWithEnv parses the command-line flags from env and os.Args[1:].
// Value from env can be overrided by os.Args[1:].
// This function also add ENVIRONMENT VARIABLE to usage.
// It is extremely recommended to call this function in main()
// after all flags are defined and before flags are accessed by the program.
// NOTICE: flag.Parse() will not be called by this function.
func ProcessFlagWithEnv() error {
	if flag.Parsed() {
		return errors.New("flag has already been parsed.")
	}
	flagEnvMap := map[string]string{}
	for k, v := range config.EnvFlagDict {
		flagEnvMap[v] = k
	}
	// Rewrite flag.Useage
	flag.VisitAll(func(f *flag.Flag) {
		if len(f.Name) < config.MinLength {
			return
		}
		envKey, ok := flagEnvMap[f.Name]
		if !ok {
			envKey = flagToEnv(f.Name)
		}
		envPrefix := fmt.Sprintf("[%s]", envKey)
		if strings.HasPrefix(f.Usage, envPrefix) {
			return
		}
		f.Usage = fmt.Sprintf("%s %s", envPrefix, f.Usage)
	})

	for _, envLine := range os.Environ() {
		debug("Find a new line of environment variable, ", envLine)
		envKV := strings.SplitN(envLine, "=", 2)
		var key, value string
		key = envKV[0]
		if len(key) < config.MinLength {
			continue
		}
		if len(envKV) > 1 {
			value = envKV[1]
		} else {
			value = ""
		}

		var flagKey string
		if userFlag, ok := config.EnvFlagDict[key]; ok {
			flagKey = userFlag
		} else {
			flagKey = envToFlag(key)
		}
		debug("ENV ", key, " is converted to ", flagKey)
		if flag.Lookup(flagKey) == nil {
			debug(flagKey, " is not defined in flag, skip!")
			continue
		}

		debug("Set  [", flagKey, ",", value, "] to flag")
		if err := flag.Set(flagKey, value); err != nil {
			return fmt.Errorf("error when set [%s,%s] into flag\n", flagKey, value)
		}
	}
	return nil
}

func debug(v ...interface{}) {
	if !config.DebugEnabled {
		return
	}
	log.Println(v)
}
<commit_msg>refactoring envflag<commit_after>package envflag

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
)

var (
	debugEnabled = false
)

// EnvFlag represents a envflag object that contains several settings.
type EnvFlag struct {
	flagSet     *flag.FlagSet     // the flagSet to process
	minLength   int               // minLength defines min length of flag key, in order to support shortcut
	envFlagDict map[string]string // envFlagDict is a user-defined env-flag map
}

// ProcessFlagWithEnv parses flag from env.
// This function also add ENVIRONMENT VARIABLE to usage.
// NOTICE: flag.Parse() will not be called by this function.
func (ef EnvFlag) ProcessFlagWithEnv() error {
	if ef.flagSet.Parsed() {
		return errors.New("flag has already been parsed")
	}
	flagEnvMap := map[string]string{}
	for k, v := range ef.envFlagDict {
		flagEnvMap[v] = k
	}
	// Rewrite flag.Useage
	ef.flagSet.VisitAll(func(f *flag.Flag) {
		if len(f.Name) < ef.minLength {
			return
		}
		envKey, ok := flagEnvMap[f.Name]
		if !ok {
			envKey = flagToEnv(f.Name)
		}
		envPrefix := fmt.Sprintf("[%s]", envKey)
		if strings.HasPrefix(f.Usage, envPrefix) {
			return
		}
		f.Usage = fmt.Sprintf("%s %s", envPrefix, f.Usage)
	})

	for _, envLine := range os.Environ() {
		debug("Find a new line of environment variable, ", envLine)
		envKV := strings.SplitN(envLine, "=", 2)
		var key, value string
		key = envKV[0]
		if len(key) < ef.minLength {
			continue
		}
		if len(envKV) > 1 {
			value = envKV[1]
		} else {
			value = ""
		}

		var flagKey string
		if userFlag, ok := ef.envFlagDict[key]; ok {
			flagKey = userFlag
		} else {
			flagKey = envToFlag(key)
		}
		debug("ENV ", key, " is converted to ", flagKey)
		if ef.flagSet.Lookup(flagKey) == nil {
			debug(flagKey, " is not defined in flag, skip!")
			continue
		}

		debug("Set  [", flagKey, ",", value, "] to flag")
		if err := ef.flagSet.Set(flagKey, value); err != nil {
			return fmt.Errorf("error when set [%s,%s] into flag\n", flagKey, value)
		}
	}
	return nil
}

// ProcessFlagWithEnv parses flag from env.
// This function also add ENVIRONMENT VARIABLE to usage.
// NOTICE: flag.Parse() will not be called by this function.
func ProcessFlagWithEnv() error {
	return std.ProcessFlagWithEnv()
}

// Parse parses flag definitions from env and the argument list.
// Value from env can be overrided by the argument list.
// This function also add ENVIRONMENT VARIABLE to usage.
// It is extremely recommended to call this function in main()
// after all flags are defined and before flags are accessed by the program.
// NOTICE: flag.Parse() will be called by this function.
func (ef EnvFlag) Parse(arguments []string) error {
	if err := ef.ProcessFlagWithEnv(); err != nil {
		return err
	}
	return ef.flagSet.Parse(arguments)
}

// Parse parses the command-line flags from env and os.Args[1:].
// Value from env can be overrided by os.Args[1:].
// This function also add ENVIRONMENT VARIABLE to usage.
// It is extremely recommended to call this function in main()
// after all flags are defined and before flags are accessed by the program.
// NOTICE: flag.Parse() will be called by this function.
func Parse() error {
	return std.Parse(os.Args[1:])
}

// SetMinLength sets the min length.
// EnvFlag only parses the environment variables that is longer than min length
// and modify usage that is longer than min length.
func (ef *EnvFlag) SetMinLength(minLength int) {
	ef.minLength = minLength
}

// SetMinLength sets the min length for standard envflag.
// EnvFlag only parses the environment variables that is longer than min length
// and modify usage that is longer than min length.
func SetMinLength(minLength int) {
	std.SetMinLength(minLength)
}

// SetEnvFlagDict sets a user-defined env-flag map.
func (ef *EnvFlag) SetEnvFlagDict(envFlagDict map[string]string) {
	ef.envFlagDict = envFlagDict
}

// SetEnvFlagDict sets a user-defined env-flag map for standard envflag.
func SetEnvFlagDict(envFlagDict map[string]string) {
	std.SetEnvFlagDict(envFlagDict)
}

var std = NewEnvFlag(flag.CommandLine, 3, map[string]string{})

// NewEnvFlag returns a new EnvFlag.
func NewEnvFlag(
	flagSet *flag.FlagSet,
	minLength int,
	envFlagDict map[string]string) *EnvFlag {
	return &EnvFlag{
		flagSet:     flagSet,
		minLength:   minLength,
		envFlagDict: envFlagDict,
	}
}

// DebugEnabled returns whether the debug is enabled or not
func DebugEnabled() bool {
	return debugEnabled
}

// SetDebugEnabled enables debug info
func SetDebugEnabled(enabled bool) {
	debugEnabled = enabled
}

// envToFlag converts THIS_FORMAT to this-format
func envToFlag(e string) string {
	return strings.Replace(strings.ToLower(e), "_", "-", -1)
}

// flagToEnv converts this-format to THIS_FORMAT
func flagToEnv(f string) string {
	return strings.Replace(strings.ToUpper(f), "-", "_", -1)
}

func debug(v ...interface{}) {
	if !debugEnabled {
		return
	}
	log.Println(v)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

type queuesNames struct {
	names []string
}

func (qn *queuesNames) String() string {
	return strings.Join(qn.names, ",")
}

func (qn *queuesNames) Set(val string) error {
	if len(val) == 0 {
		return errors.New("value cannot be empty")
	}

	qn.names = strings.Split(val, ",")
	return nil
}

func main() {
	qNames := &queuesNames{}
	endPoint := flag.String("endpoint", "", "IP:PORT of SQS service")
	region := flag.String("region", "", "SQS AWS region")
	ssl := flag.Bool("ssl", false, "Use SSL, false by default")
	flag.Var(qNames, "queues", "The queues' names to create")

	flag.Parse()

	if len(*endPoint) == 0 {
		log.Fatal("-endpoint parameters is required")
	}

	if len(*region) == 0 {
		log.Fatal("-region parameters is required")
	}

	if qNames == nil {
		log.Fatal("-queues parameter is required")
	}

	svc := sqs.New(session.New(aws.NewConfig().WithDisableSSL(!*ssl).WithEndpoint(*endPoint).WithRegion(*region)))

	for _, qn := range qNames.names {
		log.Println("Creating queue", qn)
		createQueue(svc, qn)
	}
}

func createQueue(svc *sqs.SQS, queueName string) {
	params := &sqs.CreateQueueInput{
		QueueName: &queueName,
	}
	_, err := svc.CreateQueue(params)
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Improved help message for `-queues` flag<commit_after>package main

import (
	"errors"
	"flag"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)

type queuesNames struct {
	names []string
}

func (qn *queuesNames) String() string {
	return strings.Join(qn.names, ",")
}

func (qn *queuesNames) Set(val string) error {
	if len(val) == 0 {
		return errors.New("value cannot be empty")
	}

	qn.names = strings.Split(val, ",")
	return nil
}

func main() {
	qNames := &queuesNames{}
	endPoint := flag.String("endpoint", "", "IP:PORT of SQS service")
	region := flag.String("region", "", "SQS AWS region")
	ssl := flag.Bool("ssl", false, "Use SSL, false by default")
	flag.Var(qNames, "queues", "The queues' names to create, provide one or a comma separated list of them")

	flag.Parse()

	if len(*endPoint) == 0 {
		log.Fatal("-endpoint parameters is required")
	}

	if len(*region) == 0 {
		log.Fatal("-region parameters is required")
	}

	if qNames == nil {
		log.Fatal("-queues parameter is required")
	}

	svc := sqs.New(session.New(aws.NewConfig().WithDisableSSL(!*ssl).WithEndpoint(*endPoint).WithRegion(*region)))

	for _, qn := range qNames.names {
		log.Println("Creating queue", qn)
		createQueue(svc, qn)
	}
}

func createQueue(svc *sqs.SQS, queueName string) {
	params := &sqs.CreateQueueInput{
		QueueName: &queueName,
	}
	_, err := svc.CreateQueue(params)
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package parser

import (
	"strings"

	"github.com/cznic/cc"
)

type TargetArch string

const (
	Arch32    TargetArch = "i386"
	Arch48    TargetArch = "x86_48"
	Arch64    TargetArch = "x86_64"
	ArchArm32 TargetArch = "arm"
	ArchArm64 TargetArch = "aarch64"
)

var builtinBase = `
#define __builtin_va_list void *
#define __asm(x)
#define __inline inline
#define __inline__ inline
#define __signed
#define __signed__
#define __extension__
#define __attribute__(x)
#define __restrict
#define __volatile__

#define __builtin_inff() (0)
#define __builtin_infl() (0)
#define __builtin_inf() (0)
#define __builtin_fabsf(x) (0)
#define __builtin_fabsl(x) (0)
#define __builtin_fabs(x) (0)

#define __INTRINSIC_PROLOG(name)
`

var builtinBaseUndef = `
#undef __llvm__
#undef __BLOCKS__
`

var basePredefines = `
#define __STDC_HOSTED__ 1
#define __STDC_VERSION__ 199901L
#define __STDC__ 1
#define __GNUC__ 4
#define __POSIX_C_DEPRECATED(ver)

#define __FLT_MIN__ 0
#define __DBL_MIN__ 0
#define __LDBL_MIN__ 0

void __GO__(char*, ...);
`

var archPredefines = map[TargetArch]string{
	Arch32: `#define __i386__ 1`,
	Arch48: `#define __x86_64__ 1`,
	Arch64: `#define __x86_64__ 1`,
	ArchArm32: strings.Join([]string{
		`#define __ARM_EABI__ 1`,
		`#define __arm__ 1`,
	}, "\n"),
	ArchArm64: strings.Join([]string{
		`#define __ARM_EABI__ 1`,
		`#define __aarch64__ 1`,
	}, "\n"),
	// TODO(xlab): https://sourceforge.net/p/predef/wiki/Architectures/
}

var models = map[TargetArch]*cc.Model{
	Arch32:    model32,
	Arch48:    model48,
	Arch64:    model64,
	ArchArm32: model32,
	ArchArm64: model64,
}

var arches = map[string]TargetArch{
	"386":         Arch32,
	"arm":         ArchArm32,
	"aarch64":     ArchArm64,
	"armv7a":      ArchArm32,
	"armv8a":      ArchArm64,
	"armeabi-v7a": ArchArm32,
	"armeabi-v8a": ArchArm64,
	"armbe":       ArchArm32,
	"mips":        Arch32,
	"mipsle":      Arch32,
	"sparc":       Arch32,
	"amd64":       Arch64,
	"amd64p32":    ArchArm32,
	"arm64":       ArchArm64,
	"arm64be":     ArchArm64,
	"ppc64":       Arch64,
	"ppc64le":     Arch64,
	"mips64":      Arch64,
	"mips64le":    Arch64,
	"mips64p32":   Arch48,
	"mips64p32le": Arch48,
	"sparc64":     Arch64,
}

var model32 = &cc.Model{
	Items: map[cc.Kind]cc.ModelItem{
		cc.Ptr:               {4, 4, 4, "__TODO_PTR"},
		cc.UintPtr:           {4, 4, 4, "uintptr"},
		cc.Void:              {0, 1, 1, "__TODO_VOID"},
		cc.Char:              {1, 1, 1, "int8"},
		cc.SChar:             {1, 1, 1, "int8"},
		cc.UChar:             {1, 1, 1, "byte"},
		cc.Short:             {2, 2, 2, "int16"},
		cc.UShort:            {2, 2, 2, "uint16"},
		cc.Int:               {4, 4, 4, "int32"},
		cc.UInt:              {4, 4, 4, "uint32"},
		cc.Long:              {4, 4, 4, "int32"},
		cc.ULong:             {4, 4, 4, "uint32"},
		cc.LongLong:          {8, 8, 8, "int64"},
		cc.ULongLong:         {8, 8, 8, "uint64"},
		cc.Float:             {4, 4, 4, "float32"},
		cc.Double:            {8, 8, 4, "float64"},
		cc.LongDouble:        {8, 8, 4, "float64"},
		cc.Bool:              {1, 1, 1, "bool"},
		cc.FloatComplex:      {8, 8, 8, "complex64"},
		cc.DoubleComplex:     {16, 16, 16, "complex128"},
		cc.LongDoubleComplex: {16, 16, 16, "complex128"},
	},
}

var model48 = &cc.Model{
	Items: map[cc.Kind]cc.ModelItem{
		cc.Ptr:               {4, 4, 4, "__TODO_PTR"},
		cc.UintPtr:           {4, 4, 4, "uintptr"},
		cc.Void:              {0, 1, 1, "__TODO_VOID"},
		cc.Char:              {1, 1, 1, "int8"},
		cc.SChar:             {1, 1, 1, "int8"},
		cc.UChar:             {1, 1, 1, "byte"},
		cc.Short:             {2, 2, 2, "int16"},
		cc.UShort:            {2, 2, 2, "uint16"},
		cc.Int:               {4, 4, 4, "int32"},
		cc.UInt:              {4, 4, 4, "uint32"},
		cc.Long:              {8, 8, 8, "int64"},
		cc.ULong:             {8, 8, 8, "uint64"},
		cc.LongLong:          {8, 8, 8, "int64"},
		cc.ULongLong:         {8, 8, 8, "uint64"},
		cc.Float:             {4, 4, 4, "float32"},
		cc.Double:            {8, 8, 4, "float64"},
		cc.LongDouble:        {8, 8, 4, "float64"},
		cc.Bool:              {1, 1, 1, "bool"},
		cc.FloatComplex:      {8, 8, 8, "complex64"},
		cc.DoubleComplex:     {16, 16, 16, "complex128"},
		cc.LongDoubleComplex: {16, 16, 16, "complex128"},
	},
}

var model64 = &cc.Model{
	Items: map[cc.Kind]cc.ModelItem{
		cc.Ptr:               {8, 8, 8, "__TODO_PTR"},
		cc.UintPtr:           {8, 8, 8, "uintptr"},
		cc.Void:              {0, 1, 1, "__TODO_VOID"},
		cc.Char:              {1, 1, 1, "int8"},
		cc.SChar:             {1, 1, 1, "int8"},
		cc.UChar:             {1, 1, 1, "byte"},
		cc.Short:             {2, 2, 2, "int16"},
		cc.UShort:            {2, 2, 2, "uint16"},
		cc.Int:               {4, 4, 4, "int32"},
		cc.UInt:              {4, 4, 4, "uint32"},
		cc.Long:              {8, 8, 8, "int64"},
		cc.ULong:             {8, 8, 8, "uint64"},
		cc.LongLong:          {8, 8, 8, "int64"},
		cc.ULongLong:         {8, 8, 8, "uint64"},
		cc.Float:             {4, 4, 4, "float32"},
		cc.Double:            {8, 8, 4, "float64"},
		cc.LongDouble:        {8, 8, 4, "float64"},
		cc.Bool:              {1, 1, 1, "bool"},
		cc.FloatComplex:      {8, 8, 8, "complex64"},
		cc.DoubleComplex:     {16, 16, 16, "complex128"},
		cc.LongDoubleComplex: {16, 16, 16, "complex128"},
	},
}
<commit_msg>__const -> const.<commit_after>package parser

import (
	"strings"

	"github.com/cznic/cc"
)

type TargetArch string

const (
	Arch32    TargetArch = "i386"
	Arch48    TargetArch = "x86_48"
	Arch64    TargetArch = "x86_64"
	ArchArm32 TargetArch = "arm"
	ArchArm64 TargetArch = "aarch64"
)

var builtinBase = `
#define __builtin_va_list void *
#define __asm(x)
#define __inline inline
#define __inline__ inline
#define __signed
#define __signed__
#define __const const
#define __extension__
#define __attribute__(x)
#define __restrict
#define __volatile__

#define __builtin_inff() (0)
#define __builtin_infl() (0)
#define __builtin_inf() (0)
#define __builtin_fabsf(x) (0)
#define __builtin_fabsl(x) (0)
#define __builtin_fabs(x) (0)

#define __INTRINSIC_PROLOG(name)
`

var builtinBaseUndef = `
#undef __llvm__
#undef __BLOCKS__
`

var basePredefines = `
#define __STDC_HOSTED__ 1
#define __STDC_VERSION__ 199901L
#define __STDC__ 1
#define __GNUC__ 4
#define __POSIX_C_DEPRECATED(ver)

#define __FLT_MIN__ 0
#define __DBL_MIN__ 0
#define __LDBL_MIN__ 0

void __GO__(char*, ...);
`

var archPredefines = map[TargetArch]string{
	Arch32: `#define __i386__ 1`,
	Arch48: `#define __x86_64__ 1`,
	Arch64: `#define __x86_64__ 1`,
	ArchArm32: strings.Join([]string{
		`#define __ARM_EABI__ 1`,
		`#define __arm__ 1`,
	}, "\n"),
	ArchArm64: strings.Join([]string{
		`#define __ARM_EABI__ 1`,
		`#define __aarch64__ 1`,
	}, "\n"),
	// TODO(xlab): https://sourceforge.net/p/predef/wiki/Architectures/
}

var models = map[TargetArch]*cc.Model{
	Arch32:    model32,
	Arch48:    model48,
	Arch64:    model64,
	ArchArm32: model32,
	ArchArm64: model64,
}

var arches = map[string]TargetArch{
	"386":         Arch32,
	"arm":         ArchArm32,
	"aarch64":     ArchArm64,
	"armv7a":      ArchArm32,
	"armv8a":      ArchArm64,
	"armeabi-v7a": ArchArm32,
	"armeabi-v8a": ArchArm64,
	"armbe":       ArchArm32,
	"mips":        Arch32,
	"mipsle":      Arch32,
	"sparc":       Arch32,
	"amd64":       Arch64,
	"amd64p32":    ArchArm32,
	"arm64":       ArchArm64,
	"arm64be":     ArchArm64,
	"ppc64":       Arch64,
	"ppc64le":     Arch64,
	"mips64":      Arch64,
	"mips64le":    Arch64,
	"mips64p32":   Arch48,
	"mips64p32le": Arch48,
	"sparc64":     Arch64,
}

var model32 = &cc.Model{
	Items: map[cc.Kind]cc.ModelItem{
		cc.Ptr:               {4, 4, 4, "__TODO_PTR"},
		cc.UintPtr:           {4, 4, 4, "uintptr"},
		cc.Void:              {0, 1, 1, "__TODO_VOID"},
		cc.Char:              {1, 1, 1, "int8"},
		cc.SChar:             {1, 1, 1, "int8"},
		cc.UChar:             {1, 1, 1, "byte"},
		cc.Short:             {2, 2, 2, "int16"},
		cc.UShort:            {2, 2, 2, "uint16"},
		cc.Int:               {4, 4, 4, "int32"},
		cc.UInt:              {4, 4, 4, "uint32"},
		cc.Long:              {4, 4, 4, "int32"},
		cc.ULong:             {4, 4, 4, "uint32"},
		cc.LongLong:          {8, 8, 8, "int64"},
		cc.ULongLong:         {8, 8, 8, "uint64"},
		cc.Float:             {4, 4, 4, "float32"},
		cc.Double:            {8, 8, 4, "float64"},
		cc.LongDouble:        {8, 8, 4, "float64"},
		cc.Bool:              {1, 1, 1, "bool"},
		cc.FloatComplex:      {8, 8, 8, "complex64"},
		cc.DoubleComplex:     {16, 16, 16, "complex128"},
		cc.LongDoubleComplex: {16, 16, 16, "complex128"},
	},
}

var model48 = &cc.Model{
	Items: map[cc.Kind]cc.ModelItem{
		cc.Ptr:               {4, 4, 4, "__TODO_PTR"},
		cc.UintPtr:           {4, 4, 4, "uintptr"},
		cc.Void:              {0, 1, 1, "__TODO_VOID"},
		cc.Char:              {1, 1, 1, "int8"},
		cc.SChar:             {1, 1, 1, "int8"},
		cc.UChar:             {1, 1, 1, "byte"},
		cc.Short:             {2, 2, 2, "int16"},
		cc.UShort:            {2, 2, 2, "uint16"},
		cc.Int:               {4, 4, 4, "int32"},
		cc.UInt:              {4, 4, 4, "uint32"},
		cc.Long:              {8, 8, 8, "int64"},
		cc.ULong:             {8, 8, 8, "uint64"},
		cc.LongLong:          {8, 8, 8, "int64"},
		cc.ULongLong:         {8, 8, 8, "uint64"},
		cc.Float:             {4, 4, 4, "float32"},
		cc.Double:            {8, 8, 4, "float64"},
		cc.LongDouble:        {8, 8, 4, "float64"},
		cc.Bool:              {1, 1, 1, "bool"},
		cc.FloatComplex:      {8, 8, 8, "complex64"},
		cc.DoubleComplex:     {16, 16, 16, "complex128"},
		cc.LongDoubleComplex: {16, 16, 16, "complex128"},
	},
}

var model64 = &cc.Model{
	Items: map[cc.Kind]cc.ModelItem{
		cc.Ptr:               {8, 8, 8, "__TODO_PTR"},
		cc.UintPtr:           {8, 8, 8, "uintptr"},
		cc.Void:              {0, 1, 1, "__TODO_VOID"},
		cc.Char:              {1, 1, 1, "int8"},
		cc.SChar:             {1, 1, 1, "int8"},
		cc.UChar:             {1, 1, 1, "byte"},
		cc.Short:             {2, 2, 2, "int16"},
		cc.UShort:            {2, 2, 2, "uint16"},
		cc.Int:               {4, 4, 4, "int32"},
		cc.UInt:              {4, 4, 4, "uint32"},
		cc.Long:              {8, 8, 8, "int64"},
		cc.ULong:             {8, 8, 8, "uint64"},
		cc.LongLong:          {8, 8, 8, "int64"},
		cc.ULongLong:         {8, 8, 8, "uint64"},
		cc.Float:             {4, 4, 4, "float32"},
		cc.Double:            {8, 8, 4, "float64"},
		cc.LongDouble:        {8, 8, 4, "float64"},
		cc.Bool:              {1, 1, 1, "bool"},
		cc.FloatComplex:      {8, 8, 8, "complex64"},
		cc.DoubleComplex:     {16, 16, 16, "complex128"},
		cc.LongDoubleComplex: {16, 16, 16, "complex128"},
	},
}
<|endoftext|>


<commit_before>package s

import (
	"os"
	"testing"

	"github.com/asp2insp/go-misc/testutils"
)

var testData = []byte("0123456789ABCDEF")

func TestInit(t *testing.T) {
	defer cleanup()
	store := NewFileStorage("")
	store.Init("id")
	defer store.Close()

	testutils.CheckString("id", store.fileId, t)
	testutils.CheckString("", store.rootPath, t)

	if store.file == nil {
		t.Errorf("No main file opened for %s", fname("id", ""))
	}
	if store.headerFile == nil {
		t.Errorf("No header file opened for %s", fheader("id", ""))
	}
	if store.Header() == nil {
		t.Error("No stream header available")
	}

	testutils.CheckUint64(0, store.Header().Tail, t)
	testutils.CheckUint64(0, store.Header().LastMessage, t)
	testutils.CheckUint64(uint64(os.Getpagesize()), store.Header().FileSize, t)
	testutils.CheckUint64(0, store.Header().EntryCount, t)
}

func TestPersistence(t *testing.T) {
	defer cleanup()
	store := NewFileStorage("").Init("id")
	copy(store.GetBytes(0, uint64(len(testData))), testData)
	store.Close()

	store = NewFileStorage("").Init("id")
	defer store.Close()
	if store.GetBytes(0, store.Capacity())[15] != 'F' {
		t.Errorf("Expected %b got %b", 'F', store.GetBytes(0, store.Capacity())[15])
	}
}

func TestUtilization(t *testing.T) {
	defer cleanup()
	store := NewFileStorage("")
	store.Init("id")
	defer store.Close()

	store.Header().Tail = 2048
	testutils.CheckInt(50, store.Utilization(), t)
}

func cleanup() {
	os.Remove(fname("id", ""))
	os.Remove(fheader("id", ""))
}
<commit_msg>Moved clean up to beginning of tests<commit_after>package s

import (
	"os"
	"testing"

	"github.com/asp2insp/go-misc/testutils"
)

var testData = []byte("0123456789ABCDEF")

func TestInit(t *testing.T) {
	cleanup()
	store := NewFileStorage("")
	store.Init("id")
	defer store.Close()

	testutils.CheckString("id", store.fileId, t)
	testutils.CheckString("", store.rootPath, t)

	if store.file == nil {
		t.Errorf("No main file opened for %s", fname("id", ""))
	}
	if store.headerFile == nil {
		t.Errorf("No header file opened for %s", fheader("id", ""))
	}
	if store.Header() == nil {
		t.Error("No stream header available")
	}

	testutils.CheckUint64(0, store.Header().Tail, t)
	testutils.CheckUint64(0, store.Header().LastMessage, t)
	testutils.CheckUint64(uint64(os.Getpagesize()), store.Header().FileSize, t)
	testutils.CheckUint64(0, store.Header().EntryCount, t)
}

func TestPersistence(t *testing.T) {
	cleanup()
	store := NewFileStorage("").Init("id")
	copy(store.GetBytes(0, uint64(len(testData))), testData)
	store.Close()

	store = NewFileStorage("").Init("id")
	defer store.Close()
	if store.GetBytes(0, store.Capacity())[15] != 'F' {
		t.Errorf("Expected %b got %b", 'F', store.GetBytes(0, store.Capacity())[15])
	}
}

func TestUtilization(t *testing.T) {
	cleanup()
	store := NewFileStorage("")
	store.Init("id")
	defer store.Close()

	store.Header().Tail = 2048
	testutils.CheckInt(50, store.Utilization(), t)
}

func cleanup() {
	os.Remove(fname("id", ""))
	os.Remove(fheader("id", ""))
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package cli

import (
	"os"
	"sort"
	"strings"

	"github.com/spf13/cobra"
	"mynewt.apache.org/newt/newt/downloader"
	"mynewt.apache.org/newt/newt/interfaces"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/project"
	"mynewt.apache.org/newt/newt/repo"
	"mynewt.apache.org/newt/util"
)

var infoRemote bool

func newRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify "+
			"a project directory to newt new"))
	}

	newDir := args[0]

	if util.NodeExist(newDir) {
		NewtUsage(cmd, util.NewNewtError("Cannot create new project, "+
			"directory already exists"))
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT, "Downloading "+
		"project skeleton from apache/mynewt-blinky...\n")
	dl := downloader.NewGithubDownloader()
	dl.User = "apache"
	dl.Repo = "mynewt-blinky"

	tmpdir, err := newtutil.MakeTempRepoDir()
	if err != nil {
		NewtUsage(nil, err)
	}
	defer os.RemoveAll(tmpdir)

	if err := dl.Clone(newtutil.NewtBlinkyTag, tmpdir); err != nil {
		NewtUsage(nil, err)
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT, "Installing "+
		"skeleton in %s...\n", newDir)

	if err := util.CopyDir(tmpdir, newDir); err != nil {
		NewtUsage(cmd, err)
	}

	if err := os.RemoveAll(newDir + "/" + "/.git/"); err != nil {
		NewtUsage(cmd, err)
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Project %s successfully created.\n", newDir)
}

// Builds a repo selection predicate based on the specified names.  If no names
// are specified, the resulting function selects all non-local repos.
// Otherwise, the function selects each non-local repo whose name is specified.
func makeRepoPredicate(repoNames []string) func(r *repo.Repo) bool {
	// If the user didn't specify any repo names, apply the operation to all
	// repos in `project.yml`.
	if len(repoNames) == 0 {
		proj := project.GetProject()
		return func(r *repo.Repo) bool { return proj.RepoIsRoot(r.Name()) }
	}

	return func(r *repo.Repo) bool {
		if !r.IsLocal() {
			for _, arg := range repoNames {
				if strings.TrimPrefix(r.Name(), "@") == arg {
					return true
				}
			}
		}
		return false
	}
}

func upgradeRunCmd(cmd *cobra.Command, args []string) {
	proj := TryGetOrDownloadProject()
	interfaces.SetProject(proj)

	pred := makeRepoPredicate(args)
	if err := proj.UpgradeIf(
		newtutil.NewtForce, newtutil.NewtAsk, pred); err != nil {

		NewtUsage(nil, err)
	}
}

func infoRunCmd(cmd *cobra.Command, args []string) {
	newtutil.PrintNewtVersion()

	proj := TryGetProject()

	// If no arguments specified, print status of all installed repos.
	if len(args) == 0 {
		pred := func(r *repo.Repo) bool { return true }
		if err := proj.InfoIf(pred, infoRemote); err != nil {
			NewtUsage(nil, err)
		}

		return
	}

	// Otherwise, list packages specified repo contains.
	reqRepoName := strings.TrimPrefix(args[0], "@")

	repoNames := []string{}
	for repoName, _ := range proj.PackageList() {
		repoNames = append(repoNames, repoName)
	}
	sort.Strings(repoNames)

	firstRepo := true
	for _, repoName := range repoNames {
		if reqRepoName == "all" || reqRepoName == repoName {
			packNames := []string{}
			for _, pack := range *proj.PackageList()[repoName] {
				// Don't display the special unittest target; this is used
				// internally by newt, so the user doesn't need to know about
				// it.
				// XXX: This is a hack; come up with a better solution for
				// unit testing.
				if !strings.HasSuffix(pack.Name(), "/unittest") {
					packNames = append(packNames, pack.Name())
				}
			}

			sort.Strings(packNames)
			if !firstRepo {
				util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
			} else {
				firstRepo = false
			}
			util.StatusMessage(util.VERBOSITY_DEFAULT, "Packages in @%s:\n",
				repoName)
			for _, pkgName := range packNames {
				util.StatusMessage(util.VERBOSITY_DEFAULT, "    * %s\n",
					pkgName)
			}
		}
	}
}

func AddProjectCommands(cmd *cobra.Command) {
	upgradeHelpText := ""
	upgradeHelpEx := "  newt upgrade\n"
	upgradeHelpEx += "    Upgrades all repositories specified in project.yml.\n\n"
	upgradeHelpEx += "  newt upgrade apache-mynewt-core\n"
	upgradeHelpEx += "    Upgrades the apache-mynewt-core repository."
	upgradeCmd := &cobra.Command{
		Use:     "upgrade [repo-1] [repo-2] [...]",
		Short:   "Upgrade project dependencies",
		Long:    upgradeHelpText,
		Example: upgradeHelpEx,
		Run:     upgradeRunCmd,
	}
	upgradeCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
		"force", "f", false,
		"Force upgrade of the repositories to latest state in project.yml")
	upgradeCmd.PersistentFlags().BoolVarP(&newtutil.NewtAsk,
		"ask", "a", false, "Prompt user before upgrading any repos")

	cmd.AddCommand(upgradeCmd)

	newHelpText := ""
	newHelpEx := ""
	newCmd := &cobra.Command{
		Use:     "new <project-dir>",
		Short:   "Create a new project",
		Long:    newHelpText,
		Example: newHelpEx,
		Run:     newRunCmd,
	}

	cmd.AddCommand(newCmd)

	infoHelpText := "Show information about the current project."
	infoHelpEx := "  newt info\n"

	infoCmd := &cobra.Command{
		Use:     "info",
		Short:   "Show project info",
		Long:    infoHelpText,
		Example: infoHelpEx,
		Run:     infoRunCmd,
	}
	infoCmd.PersistentFlags().BoolVarP(&infoRemote,
		"remote", "r", false,
		"Fetch latest repos to determine if upgrades are required")

	cmd.AddCommand(infoCmd)
}
<commit_msg>newt new: Infer latest "rc" tag for blinky<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package cli

import (
	"os"
	"sort"
	"strings"

	"github.com/spf13/cobra"
	"mynewt.apache.org/newt/newt/downloader"
	"mynewt.apache.org/newt/newt/interfaces"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/project"
	"mynewt.apache.org/newt/newt/repo"
	"mynewt.apache.org/newt/util"
)

var infoRemote bool

func newRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify "+
			"a project directory to newt new"))
	}

	newDir := args[0]

	if util.NodeExist(newDir) {
		NewtUsage(cmd, util.NewNewtError("Cannot create new project, "+
			"directory already exists"))
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT, "Downloading "+
		"project skeleton from apache/mynewt-blinky...\n")
	dl := downloader.NewGithubDownloader()
	dl.User = "apache"
	dl.Repo = "mynewt-blinky"

	tmpdir, err := newtutil.MakeTempRepoDir()
	if err != nil {
		NewtUsage(nil, err)
	}
	defer os.RemoveAll(tmpdir)

	if err := dl.Clone("master", tmpdir); err != nil {
		NewtUsage(nil, err)
	}

	commit, err := dl.LatestRc(tmpdir, newtutil.NewtBlinkyTag)
	if err != nil {
		NewtUsage(nil, err)
	}

	err = dl.Checkout(tmpdir, commit)
	if err != nil {
		NewtUsage(nil, err)
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT, "Installing "+
		"skeleton in %s (commit: %s)\n", newDir, commit)

	if err := util.CopyDir(tmpdir, newDir); err != nil {
		NewtUsage(cmd, err)
	}

	if err := os.RemoveAll(newDir + "/" + "/.git/"); err != nil {
		NewtUsage(cmd, err)
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Project %s successfully created.\n", newDir)
}

// Builds a repo selection predicate based on the specified names.  If no names
// are specified, the resulting function selects all non-local repos.
// Otherwise, the function selects each non-local repo whose name is specified.
func makeRepoPredicate(repoNames []string) func(r *repo.Repo) bool {
	// If the user didn't specify any repo names, apply the operation to all
	// repos in `project.yml`.
	if len(repoNames) == 0 {
		proj := project.GetProject()
		return func(r *repo.Repo) bool { return proj.RepoIsRoot(r.Name()) }
	}

	return func(r *repo.Repo) bool {
		if !r.IsLocal() {
			for _, arg := range repoNames {
				if strings.TrimPrefix(r.Name(), "@") == arg {
					return true
				}
			}
		}
		return false
	}
}

func upgradeRunCmd(cmd *cobra.Command, args []string) {
	proj := TryGetOrDownloadProject()
	interfaces.SetProject(proj)

	pred := makeRepoPredicate(args)
	if err := proj.UpgradeIf(
		newtutil.NewtForce, newtutil.NewtAsk, pred); err != nil {

		NewtUsage(nil, err)
	}
}

func infoRunCmd(cmd *cobra.Command, args []string) {
	newtutil.PrintNewtVersion()

	proj := TryGetProject()

	// If no arguments specified, print status of all installed repos.
	if len(args) == 0 {
		pred := func(r *repo.Repo) bool { return true }
		if err := proj.InfoIf(pred, infoRemote); err != nil {
			NewtUsage(nil, err)
		}

		return
	}

	// Otherwise, list packages specified repo contains.
	reqRepoName := strings.TrimPrefix(args[0], "@")

	repoNames := []string{}
	for repoName, _ := range proj.PackageList() {
		repoNames = append(repoNames, repoName)
	}
	sort.Strings(repoNames)

	firstRepo := true
	for _, repoName := range repoNames {
		if reqRepoName == "all" || reqRepoName == repoName {
			packNames := []string{}
			for _, pack := range *proj.PackageList()[repoName] {
				// Don't display the special unittest target; this is used
				// internally by newt, so the user doesn't need to know about
				// it.
				// XXX: This is a hack; come up with a better solution for
				// unit testing.
				if !strings.HasSuffix(pack.Name(), "/unittest") {
					packNames = append(packNames, pack.Name())
				}
			}

			sort.Strings(packNames)
			if !firstRepo {
				util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
			} else {
				firstRepo = false
			}
			util.StatusMessage(util.VERBOSITY_DEFAULT, "Packages in @%s:\n",
				repoName)
			for _, pkgName := range packNames {
				util.StatusMessage(util.VERBOSITY_DEFAULT, "    * %s\n",
					pkgName)
			}
		}
	}
}

func AddProjectCommands(cmd *cobra.Command) {
	upgradeHelpText := ""
	upgradeHelpEx := "  newt upgrade\n"
	upgradeHelpEx += "    Upgrades all repositories specified in project.yml.\n\n"
	upgradeHelpEx += "  newt upgrade apache-mynewt-core\n"
	upgradeHelpEx += "    Upgrades the apache-mynewt-core repository."
	upgradeCmd := &cobra.Command{
		Use:     "upgrade [repo-1] [repo-2] [...]",
		Short:   "Upgrade project dependencies",
		Long:    upgradeHelpText,
		Example: upgradeHelpEx,
		Run:     upgradeRunCmd,
	}
	upgradeCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce,
		"force", "f", false,
		"Force upgrade of the repositories to latest state in project.yml")
	upgradeCmd.PersistentFlags().BoolVarP(&newtutil.NewtAsk,
		"ask", "a", false, "Prompt user before upgrading any repos")

	cmd.AddCommand(upgradeCmd)

	newHelpText := ""
	newHelpEx := ""
	newCmd := &cobra.Command{
		Use:     "new <project-dir>",
		Short:   "Create a new project",
		Long:    newHelpText,
		Example: newHelpEx,
		Run:     newRunCmd,
	}

	cmd.AddCommand(newCmd)

	infoHelpText := "Show information about the current project."
	infoHelpEx := "  newt info\n"

	infoCmd := &cobra.Command{
		Use:     "info",
		Short:   "Show project info",
		Long:    infoHelpText,
		Example: infoHelpEx,
		Run:     infoRunCmd,
	}
	infoCmd.PersistentFlags().BoolVarP(&infoRemote,
		"remote", "r", false,
		"Fetch latest repos to determine if upgrades are required")

	cmd.AddCommand(infoCmd)
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

// Package csrand implements the math/rand interface over crypto/rand, along
// with some utility functions for common random number/byte related tasks.
//
// Not all of the convinience routines are replicated, only those that are
// useful for obfs4.  The CsRand variable provides access to the full math/rand
// API.
package csrand

import (
	cryptRand "crypto/rand"
	"fmt"
	"math/big"
	"math/rand"
)

var (
	csRandSourceInstance csRandSource

	// CsRand is a math/rand instance backed by crypto/rand CSPRNG.
	CsRand       = rand.New(csRandSourceInstance)
)

type csRandSource struct {
	// This does not keep any state as it is backed by crypto/rand.
}

func (r csRandSource) Int63() int64 {
	ret, err := cryptRand.Int(cryptRand.Reader, big.NewInt(int64((1<<63)-1)))
	if err != nil {
		panic(err)
	}

	return ret.Int64()
}

func (r csRandSource) Seed(seed int64) {
	// No-op.
}

// Float64 returns, as a float 64, a pesudo random number in [0.0,1.0).
func Float64() float64 {
	return CsRand.Float64()
}

// IntRange returns a uniformly distributed int [min, max].
func IntRange(min, max int) int {
	if max < min {
		panic(fmt.Sprintf("IntRange: min > max (%d, %d)", min, max))
	}

	r := (max + 1) - min
	ret := CsRand.Intn(r)
	return ret + min
}

// Bytes fills the slice with random data.
func Bytes(buf []byte) error {
	n, err := cryptRand.Read(buf)
	if err != nil {
		// Yes, the go idiom is to check the length, but we panic() when it
		// does not match because the system is screwed at that point.
		return err
	} else if n != len(buf) {
		panic(fmt.Sprintf("Bytes: truncated rand.Read (%d, %d)", n, len(buf)))
	}

	return nil
}

/* vim :set ts=4 sw=4 sts=4 noet : */
<commit_msg>Don't use math/big when generating random numbers.<commit_after>/*
 * Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

// Package csrand implements the math/rand interface over crypto/rand, along
// with some utility functions for common random number/byte related tasks.
//
// Not all of the convinience routines are replicated, only those that are
// useful for obfs4.  The CsRand variable provides access to the full math/rand
// API.
package csrand

import (
	cryptRand "crypto/rand"
	"encoding/binary"
	"fmt"
	"math/rand"
)

var (
	csRandSourceInstance csRandSource

	// CsRand is a math/rand instance backed by crypto/rand CSPRNG.
	CsRand       = rand.New(csRandSourceInstance)
)

type csRandSource struct {
	// This does not keep any state as it is backed by crypto/rand.
}

func (r csRandSource) Int63() int64 {
	var src [8]byte
	err := Bytes(src[:])
	if err != nil {
		panic(err)
	}
	val := binary.BigEndian.Uint64(src[:])
	val &= (1<<63 - 1)

	return int64(val)
}

func (r csRandSource) Seed(seed int64) {
	// No-op.
}

// Float64 returns, as a float 64, a pesudo random number in [0.0,1.0).
func Float64() float64 {
	return CsRand.Float64()
}

// IntRange returns a uniformly distributed int [min, max].
func IntRange(min, max int) int {
	if max < min {
		panic(fmt.Sprintf("IntRange: min > max (%d, %d)", min, max))
	}

	r := (max + 1) - min
	ret := CsRand.Intn(r)
	return ret + min
}

// Bytes fills the slice with random data.
func Bytes(buf []byte) error {
	n, err := cryptRand.Read(buf)
	if err != nil {
		// Yes, the go idiom is to check the length, but we panic() when it
		// does not match because the system is screwed at that point.
		return err
	} else if n != len(buf) {
		panic(fmt.Sprintf("Bytes: truncated rand.Read (%d, %d)", n, len(buf)))
	}

	return nil
}

/* vim :set ts=4 sw=4 sts=4 noet : */
<|endoftext|>