<commit_before>package stepman

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-pathutil"
)

const (
	// StepmanDirname ...
	StepmanDirname string = ".stepman"
	// RoutingFilename ...
	RoutingFilename string = "routing.json"
	// CollectionsDirname ...
	CollectionsDirname string = "step_collections"
)

var (
	stepManDirPath  string
	routingFilePath string

	// CollectionURI ...
	CollectionURI string

	// CollectionsDirPath ...
	CollectionsDirPath string
)

// RouteMap ...
type RouteMap map[string]string

func (route RouteMap) getSingleKey() string {
	for key := range route {
		return key
	}
	return ""
}

func (route RouteMap) getSingleValue() string {
	for _, value := range route {
		return value
	}
	return ""
}

func getRoute(source string) (RouteMap, error) {
	routeMap, err := readRouteMap()
	if err != nil {
		return RouteMap{}, err
	}

	if routeMap[source] == "" {
		return RouteMap{}, errors.New("No route found for source")
	}

	r := RouteMap{
		source: routeMap[source],
	}

	return r, nil
}

func addRoute(route RouteMap) error {
	RouteMap, err := readRouteMap()
	if err != nil {
		return err
	}

	if RouteMap[route.getSingleKey()] != "" {
		return errors.New("Route already exist for source")
	}

	RouteMap[route.getSingleKey()] = route[route.getSingleKey()]

	if err := writeRouteMapToFile(RouteMap); err != nil {
		return err
	}

	return nil
}

func generateRoute(source string) RouteMap {
	timeStamp := fmt.Sprintf("%v", time.Now().Unix())
	return RouteMap{
		source: timeStamp,
	}
}

func writeRouteMapToFile(RouteMap RouteMap) error {

	if exist, err := pathutil.IsPathExists(stepManDirPath); err != nil {
		return err
	} else if exist == false {
		if err := os.MkdirAll(stepManDirPath, 0777); err != nil {
			return err
		}
	}

	file, err := os.OpenFile(routingFilePath, os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		return err
	}
	defer func() {
		if err := file.Close(); err != nil {
			log.Error("[STEPMAN] - Failed to close file:", err)
		}
	}()

	bytes, err := json.MarshalIndent(RouteMap, "", "\t")
	if err != nil {
		log.Error("[STEPMAN] - Failed to parse json:", err)
		return err
	}

	if _, err := file.Write(bytes); err != nil {
		return err
	}
	return nil
}

func readRouteMap() (RouteMap, error) {
	if exist, err := pathutil.IsPathExists(routingFilePath); err != nil {
		return RouteMap{}, err
	} else if exist == false {
		return RouteMap{}, nil
	}

	file, e := os.Open(routingFilePath)
	if e != nil {
		return RouteMap{}, e
	}

	var routeMap RouteMap
	parser := json.NewDecoder(file)
	if err := parser.Decode(&routeMap); err != nil {
		return RouteMap{}, err
	}
	return routeMap, nil
}

// CreateStepManDirIfNeeded ...
func CreateStepManDirIfNeeded() error {
	if exist, err := pathutil.IsPathExists(stepManDirPath); err != nil {
		return err
	} else if exist == false {
		if err := os.MkdirAll(stepManDirPath, 0777); err != nil {
			return err
		}
	}
	return nil
}

// SetupCurrentRouting ...
func SetupCurrentRouting() error {
	if CollectionURI == "" {
		return errors.New("No collection path defined")
	}

	route := generateRoute(CollectionURI)
	return addRoute(route)
}

// GetCurrentStepSpecPath ...
func GetCurrentStepSpecPath() string {
	route, err := getRoute(CollectionURI)
	if err != nil {
		log.Error("[STEPMAN] - Failed to generate current step spec path:", err)
		return ""
	}
	return CollectionsDirPath + route.getSingleValue() + "/spec/spec.json"
}

// GetCurrentStepCacheDir ...
func GetCurrentStepCacheDir() string {
	route, err := getRoute(CollectionURI)
	if err != nil {
		log.Error("[STEPMAN] - Failed to generate current step spec path:", err)
		return ""
	}
	return CollectionsDirPath + route.getSingleValue() + "/cache/"
}

// GetCurrentStepCollectionPath ...
func GetCurrentStepCollectionPath() string {
	route, err := getRoute(CollectionURI)
	if err != nil {
		log.Error("[STEPMAN] - Failed to generate current step spec path:", err)
		return ""
	}
	return CollectionsDirPath + route.getSingleValue() + "/collection/"
}

// Life cycle
func init() {
	stepManDirPath = pathutil.UserHomeDir() + "/" + StepmanDirname + "/"
	routingFilePath = stepManDirPath + RoutingFilename
	CollectionsDirPath = stepManDirPath + CollectionsDirname + "/"
}
<commit_msg>generate route fixes<commit_after>package stepman

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/bitrise-io/go-pathutil"
)

const (
	// StepmanDirname ...
	StepmanDirname string = ".stepman"
	// RoutingFilename ...
	RoutingFilename string = "routing.json"
	// CollectionsDirname ...
	CollectionsDirname string = "step_collections"
)

var (
	stepManDirPath  string
	routingFilePath string

	// CollectionURI ...
	CollectionURI string

	// CollectionsDirPath ...
	CollectionsDirPath string
)

// RouteMap ...
type RouteMap map[string]string

func getAlias(source string) (string, error) {
	routeMap, err := readRouteMap()
	if err != nil {
		return "", err
	}

	if routeMap[source] == "" {
		return "", errors.New("No route found for source")
	}

	return routeMap[source], nil
}

func addRoute(source, alias string) error {
	RouteMap, err := readRouteMap()
	if err != nil {
		return err
	}

	if RouteMap[source] != "" {
		return errors.New("Route already exist for source")
	}

	RouteMap[source] = alias

	if err := writeRouteMapToFile(RouteMap); err != nil {
		return err
	}

	return nil
}

func generateFolderAlias(source string) string {
	return fmt.Sprintf("%v", time.Now().Unix())
}

func writeRouteMapToFile(RouteMap RouteMap) error {
	if exist, err := pathutil.IsPathExists(stepManDirPath); err != nil {
		return err
	} else if exist == false {
		if err := os.MkdirAll(stepManDirPath, 0777); err != nil {
			return err
		}
	}

	file, err := os.OpenFile(routingFilePath, os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		return err
	}
	defer func() {
		if err := file.Close(); err != nil {
			log.Error("[STEPMAN] - Failed to close file:", err)
		}
	}()

	bytes, err := json.MarshalIndent(RouteMap, "", "\t")
	if err != nil {
		log.Error("[STEPMAN] - Failed to parse json:", err)
		return err
	}

	if _, err := file.Write(bytes); err != nil {
		return err
	}
	return nil
}

func readRouteMap() (RouteMap, error) {
	if exist, err := pathutil.IsPathExists(routingFilePath); err != nil {
		return RouteMap{}, err
	} else if exist == false {
		return RouteMap{}, nil
	}

	file, e := os.Open(routingFilePath)
	if e != nil {
		return RouteMap{}, e
	}

	var routeMap RouteMap
	parser := json.NewDecoder(file)
	if err := parser.Decode(&routeMap); err != nil {
		return RouteMap{}, err
	}
	return routeMap, nil
}

// CreateStepManDirIfNeeded ...
func CreateStepManDirIfNeeded() error {
	if exist, err := pathutil.IsPathExists(stepManDirPath); err != nil {
		return err
	} else if exist == false {
		if err := os.MkdirAll(stepManDirPath, 0777); err != nil {
			return err
		}
	}
	return nil
}

// SetupCurrentRouting ...
func SetupCurrentRouting() error {
	if CollectionURI == "" {
		return errors.New("No collection path defined")
	}

	alias := generateFolderAlias(CollectionURI)
	return addRoute(CollectionURI, alias)
}

// GetCurrentStepSpecPath ...
func GetCurrentStepSpecPath() string {
	alias, err := getAlias(CollectionURI)
	if err != nil {
		log.Error("[STEPMAN] - Failed to generate current step spec path:", err)
		return ""
	}
	return CollectionsDirPath + alias + "/spec/spec.json"
}

// GetCurrentStepCacheDir ...
func GetCurrentStepCacheDir() string {
	alias, err := getAlias(CollectionURI)
	if err != nil {
		log.Error("[STEPMAN] - Failed to generate current step spec path:", err)
		return ""
	}
	return CollectionsDirPath + alias + "/cache/"
}

// GetCurrentStepCollectionPath ...
func GetCurrentStepCollectionPath() string {
	alias, err := getAlias(CollectionURI)
	if err != nil {
		log.Error("[STEPMAN] - Failed to generate current step spec path:", err)
		return ""
	}
	return CollectionsDirPath + alias + "/collection/"
}

// Life cycle
func init() {
	stepManDirPath = pathutil.UserHomeDir() + "/" + StepmanDirname + "/"
	routingFilePath = stepManDirPath + RoutingFilename
	CollectionsDirPath = stepManDirPath + CollectionsDirname + "/"
}
<|endoftext|>


<commit_before>package mail

import (
	"crypto/rand"
	"encoding/binary"
	"errors"
	"fmt"
	"net/mail"
	"os"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/emersion/go-message"
)

const dateLayout = "Mon, 02 Jan 2006 15:04:05 -0700"

type headerParser struct {
	s string
}

func (p *headerParser) len() int {
	return len(p.s)
}

func (p *headerParser) empty() bool {
	return p.len() == 0
}

func (p *headerParser) peek() byte {
	return p.s[0]
}

func (p *headerParser) consume(c byte) bool {
	if p.empty() || p.peek() != c {
		return false
	}
	p.s = p.s[1:]
	return true
}

// skipSpace skips the leading space and tab characters.
func (p *headerParser) skipSpace() {
	p.s = strings.TrimLeft(p.s, " \t")
}

// skipCFWS skips CFWS as defined in RFC5322. It returns false if the CFWS is
// malformed.
func (p *headerParser) skipCFWS() bool {
	p.skipSpace()

	for {
		if !p.consume('(') {
			break
		}

		if _, ok := p.consumeComment(); !ok {
			return false
		}

		p.skipSpace()
	}

	return true
}

func (p *headerParser) consumeComment() (string, bool) {
	// '(' already consumed.
	depth := 1

	var comment string
	for {
		if p.empty() || depth == 0 {
			break
		}

		if p.peek() == '\\' && p.len() > 1 {
			p.s = p.s[1:]
		} else if p.peek() == '(' {
			depth++
		} else if p.peek() == ')' {
			depth--
		}

		if depth > 0 {
			comment += p.s[:1]
		}

		p.s = p.s[1:]
	}

	return comment, depth == 0
}

func (p *headerParser) parseAtomText(dot bool) (string, error) {
	i := 0
	for {
		r, size := utf8.DecodeRuneInString(p.s[i:])
		if size == 1 && r == utf8.RuneError {
			return "", fmt.Errorf("mail: invalid UTF-8 in atom-text: %q", p.s)
		} else if size == 0 || !isAtext(r, dot) {
			break
		}
		i += size
	}
	if i == 0 {
		return "", errors.New("mail: invalid string")
	}

	var atom string
	atom, p.s = p.s[:i], p.s[i:]
	return atom, nil
}

func isAtext(r rune, dot bool) bool {
	switch r {
	case '.':
		return dot
	// RFC 5322 3.2.3 specials
	case '(', ')', '[', ']', ';', '@', '\\', ',':
		return false
	case '<', '>', '"', ':':
		return false
	}
	return isVchar(r)
}

// isVchar reports whether r is an RFC 5322 VCHAR character.
func isVchar(r rune) bool {
	// Visible (printing) characters
	return '!' <= r && r <= '~' || isMultibyte(r)
}

// isMultibyte reports whether r is a multi-byte UTF-8 character
// as supported by RFC 6532
func isMultibyte(r rune) bool {
	return r >= utf8.RuneSelf
}

func (p *headerParser) parseNoFoldLiteral() (string, error) {
	if !p.consume('[') {
		return "", errors.New("mail: missing '[' in no-fold-literal")
	}

	i := 0
	for {
		r, size := utf8.DecodeRuneInString(p.s[i:])
		if size == 1 && r == utf8.RuneError {
			return "", fmt.Errorf("mail: invalid UTF-8 in no-fold-literal: %q", p.s)
		} else if size == 0 || !isDtext(r) {
			break
		}
		i += size
	}
	var lit string
	lit, p.s = p.s[:i], p.s[i:]

	if !p.consume(']') {
		return "", errors.New("mail: missing ']' in no-fold-literal")
	}
	return "[" + lit + "]", nil
}

func isDtext(r rune) bool {
	switch r {
	case '[', ']', '\\':
		return false
	}
	return isVchar(r)
}

func (p *headerParser) parseMsgID() (string, error) {
	if !p.skipCFWS() {
		return "", errors.New("mail: malformed parenthetical comment")
	}

	if !p.consume('<') {
		return "", errors.New("mail: missing '<' in msg-id")
	}

	left, err := p.parseAtomText(true)
	if err != nil {
		return "", err
	}

	if !p.consume('@') {
		return "", errors.New("mail: missing '@' in msg-id")
	}

	var right string
	if !p.empty() && p.peek() == '[' {
		// no-fold-literal
		right, err = p.parseNoFoldLiteral()
	} else {
		right, err = p.parseAtomText(true)
		if err != nil {
			return "", err
		}
	}

	if !p.consume('>') {
		return "", errors.New("mail: missing '>' in msg-id")
	}

	if !p.skipCFWS() {
		return "", errors.New("mail: malformed parenthetical comment")
	}

	return left + "@" + right, nil
}

// A Header is a mail header.
type Header struct {
	message.Header
}

// HeaderFromMap creates a header from a map of header fields.
//
// This function is provided for interoperability with the standard library.
// If possible, ReadHeader should be used instead to avoid loosing information.
// The map representation looses the ordering of the fields, the capitalization
// of the header keys, and the whitespace of the original header.
func HeaderFromMap(m map[string][]string) Header {
	return Header{message.HeaderFromMap(m)}
}

// AddressList parses the named header field as a list of addresses. If the
// header field is missing, it returns nil.
//
// This can be used on From, Sender, Reply-To, To, Cc and Bcc header fields.
func (h *Header) AddressList(key string) ([]*Address, error) {
	v := h.Get(key)
	if v == "" {
		return nil, nil
	}
	return ParseAddressList(v)
}

// SetAddressList formats the named header field to the provided list of
// addresses.
//
// This can be used on From, Sender, Reply-To, To, Cc and Bcc header fields.
func (h *Header) SetAddressList(key string, addrs []*Address) {
	if len(addrs) > 0 {
		h.Set(key, formatAddressList(addrs))
	} else {
		h.Del(key)
	}
}

// Date parses the Date header field.
func (h *Header) Date() (time.Time, error) {
	return mail.ParseDate(h.Get("Date"))
}

// SetDate formats the Date header field.
func (h *Header) SetDate(t time.Time) {
	h.Set("Date", t.Format(dateLayout))
}

// Subject parses the Subject header field. If there is an error, the raw field
// value is returned alongside the error.
func (h *Header) Subject() (string, error) {
	return h.Text("Subject")
}

// SetSubject formats the Subject header field.
func (h *Header) SetSubject(s string) {
	h.SetText("Subject", s)
}

// MessageID parses the Message-ID field. It returns the message identifier,
// without the angle brackets. If the message doesn't have a Message-ID header
// field, it returns an empty string.
func (h *Header) MessageID() (string, error) {
	v := h.Get("Message-Id")
	if v == "" {
		return "", nil
	}

	p := headerParser{v}
	return p.parseMsgID()
}

// MsgIDList parses a list of message identifiers. It returns message
// identifiers without angle brackets. If the header field is missing, it
// returns nil.
//
// This can be used on In-Reply-To and References header fields.
func (h *Header) MsgIDList(key string) ([]string, error) {
	v := h.Get(key)
	if v == "" {
		return nil, nil
	}

	p := headerParser{v}
	var l []string
	for !p.empty() {
		msgID, err := p.parseMsgID()
		if err != nil {
			return l, err
		}
		l = append(l, msgID)
	}

	return l, nil
}

// GenerateMessageID generates an RFC 2822-compliant Message-Id based on the
// informational draft "Recommendations for generating Message IDs", for lack
// of a better authoritative source.
func (h *Header) GenerateMessageID() error {
	now := uint64(time.Now().UnixNano())

	nonceByte := make([]byte, 8)
	if _, err := rand.Read(nonceByte); err != nil {
		return err
	}
	nonce := binary.BigEndian.Uint64(nonceByte)

	hostname, err := os.Hostname()
	if err != nil {
		return err
	}

	msgID := fmt.Sprintf("%s.%s@%s", base36(now), base36(nonce), hostname)
	h.SetMessageID(msgID)
	return nil
}

func base36(input uint64) string {
	return strings.ToUpper(strconv.FormatUint(input, 36))
}

// SetMessageID sets the Message-ID field. id is the message identifier,
// without the angle brackets.
func (h *Header) SetMessageID(id string) {
	h.Set("Message-Id", "<"+id+">")
}

// SetMsgIDList formats a list of message identifiers. Message identifiers
// don't include angle brackets.
//
// This can be used on In-Reply-To and References header fields.
func (h *Header) SetMsgIDList(key string, l []string) {
	var v string
	if len(l) > 0 {
		v = "<" + strings.Join(l, "> <") + ">"
	}
	h.Set(key, v)
}

// Copy creates a stand-alone copy of the header.
func (h *Header) Copy() Header {
	return Header{h.Header.Copy()}
}
<commit_msg>mail: don't set an empty header field in SetMsgIDList<commit_after>package mail

import (
	"crypto/rand"
	"encoding/binary"
	"errors"
	"fmt"
	"net/mail"
	"os"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/emersion/go-message"
)

const dateLayout = "Mon, 02 Jan 2006 15:04:05 -0700"

type headerParser struct {
	s string
}

func (p *headerParser) len() int {
	return len(p.s)
}

func (p *headerParser) empty() bool {
	return p.len() == 0
}

func (p *headerParser) peek() byte {
	return p.s[0]
}

func (p *headerParser) consume(c byte) bool {
	if p.empty() || p.peek() != c {
		return false
	}
	p.s = p.s[1:]
	return true
}

// skipSpace skips the leading space and tab characters.
func (p *headerParser) skipSpace() {
	p.s = strings.TrimLeft(p.s, " \t")
}

// skipCFWS skips CFWS as defined in RFC5322. It returns false if the CFWS is
// malformed.
func (p *headerParser) skipCFWS() bool {
	p.skipSpace()

	for {
		if !p.consume('(') {
			break
		}

		if _, ok := p.consumeComment(); !ok {
			return false
		}

		p.skipSpace()
	}

	return true
}

func (p *headerParser) consumeComment() (string, bool) {
	// '(' already consumed.
	depth := 1

	var comment string
	for {
		if p.empty() || depth == 0 {
			break
		}

		if p.peek() == '\\' && p.len() > 1 {
			p.s = p.s[1:]
		} else if p.peek() == '(' {
			depth++
		} else if p.peek() == ')' {
			depth--
		}

		if depth > 0 {
			comment += p.s[:1]
		}

		p.s = p.s[1:]
	}

	return comment, depth == 0
}

func (p *headerParser) parseAtomText(dot bool) (string, error) {
	i := 0
	for {
		r, size := utf8.DecodeRuneInString(p.s[i:])
		if size == 1 && r == utf8.RuneError {
			return "", fmt.Errorf("mail: invalid UTF-8 in atom-text: %q", p.s)
		} else if size == 0 || !isAtext(r, dot) {
			break
		}
		i += size
	}
	if i == 0 {
		return "", errors.New("mail: invalid string")
	}

	var atom string
	atom, p.s = p.s[:i], p.s[i:]
	return atom, nil
}

func isAtext(r rune, dot bool) bool {
	switch r {
	case '.':
		return dot
	// RFC 5322 3.2.3 specials
	case '(', ')', '[', ']', ';', '@', '\\', ',':
		return false
	case '<', '>', '"', ':':
		return false
	}
	return isVchar(r)
}

// isVchar reports whether r is an RFC 5322 VCHAR character.
func isVchar(r rune) bool {
	// Visible (printing) characters
	return '!' <= r && r <= '~' || isMultibyte(r)
}

// isMultibyte reports whether r is a multi-byte UTF-8 character
// as supported by RFC 6532
func isMultibyte(r rune) bool {
	return r >= utf8.RuneSelf
}

func (p *headerParser) parseNoFoldLiteral() (string, error) {
	if !p.consume('[') {
		return "", errors.New("mail: missing '[' in no-fold-literal")
	}

	i := 0
	for {
		r, size := utf8.DecodeRuneInString(p.s[i:])
		if size == 1 && r == utf8.RuneError {
			return "", fmt.Errorf("mail: invalid UTF-8 in no-fold-literal: %q", p.s)
		} else if size == 0 || !isDtext(r) {
			break
		}
		i += size
	}
	var lit string
	lit, p.s = p.s[:i], p.s[i:]

	if !p.consume(']') {
		return "", errors.New("mail: missing ']' in no-fold-literal")
	}
	return "[" + lit + "]", nil
}

func isDtext(r rune) bool {
	switch r {
	case '[', ']', '\\':
		return false
	}
	return isVchar(r)
}

func (p *headerParser) parseMsgID() (string, error) {
	if !p.skipCFWS() {
		return "", errors.New("mail: malformed parenthetical comment")
	}

	if !p.consume('<') {
		return "", errors.New("mail: missing '<' in msg-id")
	}

	left, err := p.parseAtomText(true)
	if err != nil {
		return "", err
	}

	if !p.consume('@') {
		return "", errors.New("mail: missing '@' in msg-id")
	}

	var right string
	if !p.empty() && p.peek() == '[' {
		// no-fold-literal
		right, err = p.parseNoFoldLiteral()
	} else {
		right, err = p.parseAtomText(true)
		if err != nil {
			return "", err
		}
	}

	if !p.consume('>') {
		return "", errors.New("mail: missing '>' in msg-id")
	}

	if !p.skipCFWS() {
		return "", errors.New("mail: malformed parenthetical comment")
	}

	return left + "@" + right, nil
}

// A Header is a mail header.
type Header struct {
	message.Header
}

// HeaderFromMap creates a header from a map of header fields.
//
// This function is provided for interoperability with the standard library.
// If possible, ReadHeader should be used instead to avoid loosing information.
// The map representation looses the ordering of the fields, the capitalization
// of the header keys, and the whitespace of the original header.
func HeaderFromMap(m map[string][]string) Header {
	return Header{message.HeaderFromMap(m)}
}

// AddressList parses the named header field as a list of addresses. If the
// header field is missing, it returns nil.
//
// This can be used on From, Sender, Reply-To, To, Cc and Bcc header fields.
func (h *Header) AddressList(key string) ([]*Address, error) {
	v := h.Get(key)
	if v == "" {
		return nil, nil
	}
	return ParseAddressList(v)
}

// SetAddressList formats the named header field to the provided list of
// addresses.
//
// This can be used on From, Sender, Reply-To, To, Cc and Bcc header fields.
func (h *Header) SetAddressList(key string, addrs []*Address) {
	if len(addrs) > 0 {
		h.Set(key, formatAddressList(addrs))
	} else {
		h.Del(key)
	}
}

// Date parses the Date header field.
func (h *Header) Date() (time.Time, error) {
	return mail.ParseDate(h.Get("Date"))
}

// SetDate formats the Date header field.
func (h *Header) SetDate(t time.Time) {
	h.Set("Date", t.Format(dateLayout))
}

// Subject parses the Subject header field. If there is an error, the raw field
// value is returned alongside the error.
func (h *Header) Subject() (string, error) {
	return h.Text("Subject")
}

// SetSubject formats the Subject header field.
func (h *Header) SetSubject(s string) {
	h.SetText("Subject", s)
}

// MessageID parses the Message-ID field. It returns the message identifier,
// without the angle brackets. If the message doesn't have a Message-ID header
// field, it returns an empty string.
func (h *Header) MessageID() (string, error) {
	v := h.Get("Message-Id")
	if v == "" {
		return "", nil
	}

	p := headerParser{v}
	return p.parseMsgID()
}

// MsgIDList parses a list of message identifiers. It returns message
// identifiers without angle brackets. If the header field is missing, it
// returns nil.
//
// This can be used on In-Reply-To and References header fields.
func (h *Header) MsgIDList(key string) ([]string, error) {
	v := h.Get(key)
	if v == "" {
		return nil, nil
	}

	p := headerParser{v}
	var l []string
	for !p.empty() {
		msgID, err := p.parseMsgID()
		if err != nil {
			return l, err
		}
		l = append(l, msgID)
	}

	return l, nil
}

// GenerateMessageID generates an RFC 2822-compliant Message-Id based on the
// informational draft "Recommendations for generating Message IDs", for lack
// of a better authoritative source.
func (h *Header) GenerateMessageID() error {
	now := uint64(time.Now().UnixNano())

	nonceByte := make([]byte, 8)
	if _, err := rand.Read(nonceByte); err != nil {
		return err
	}
	nonce := binary.BigEndian.Uint64(nonceByte)

	hostname, err := os.Hostname()
	if err != nil {
		return err
	}

	msgID := fmt.Sprintf("%s.%s@%s", base36(now), base36(nonce), hostname)
	h.SetMessageID(msgID)
	return nil
}

func base36(input uint64) string {
	return strings.ToUpper(strconv.FormatUint(input, 36))
}

// SetMessageID sets the Message-ID field. id is the message identifier,
// without the angle brackets.
func (h *Header) SetMessageID(id string) {
	h.Set("Message-Id", "<"+id+">")
}

// SetMsgIDList formats a list of message identifiers. Message identifiers
// don't include angle brackets.
//
// This can be used on In-Reply-To and References header fields.
func (h *Header) SetMsgIDList(key string, l []string) {
	if len(l) > 0 {
		h.Set(key, "<"+strings.Join(l, "> <")+">")
	} else {
		h.Del(key)
	}
}

// Copy creates a stand-alone copy of the header.
func (h *Header) Copy() Header {
	return Header{h.Header.Copy()}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/goamz/goamz/aws"
	"github.com/goamz/goamz/sqs"
	"log"
	"os"
)

func main() {
	var queueName = "dev-mgmt-website-data-cms-jimdo-dev"
	var deadLetterQueueName = queueName + "_dead_letter"

	var auth = aws.Auth{
		AccessKey: os.Getenv("AWS_ACCESS_KEY_ID"),
		SecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
	}

	conn := sqs.New(auth, aws.EUWest)

	deadLetterQueue, err := conn.GetQueue(deadLetterQueueName)
	if err != nil {
		log.Fatalf(err.Error())
		os.Exit(1)
	}

	activeQueue, err := conn.GetQueue(queueName)
	if err != nil {
		log.Fatalf(err.Error())
		os.Exit(1)
	}

	log.Printf("Looking for messages to requeue.")
	for {
		resp, err := deadLetterQueue.ReceiveMessageWithParameters(
			map[string]string{
				"WaitTimeSeconds":     "20",
				"MaxNumberOfMessages": "10",
				"VisibilityTimeout":   "20"})
		if err != nil {
			log.Fatalf(err.Error())
			os.Exit(1)
		}

		messages := resp.Messages
		numberOfMessages := len(messages)
		if numberOfMessages == 0 {
			log.Printf("Requeing messages done.")
			os.Exit(0)
		} else {
			log.Printf("Moving %v message(s)...", numberOfMessages)
		}

		_, err = activeQueue.SendMessageBatch(messages)
		if err != nil {
			log.Fatalf(err.Error())
			os.Exit(1)
		}

		_, err = deadLetterQueue.DeleteMessageBatch(messages)
		if err != nil {
			log.Fatalf(err.Error())
			os.Exit(1)
		}
	}
}
<commit_msg>add queue name as arg<commit_after>package main

import (
	"github.com/goamz/goamz/aws"
	"github.com/goamz/goamz/sqs"
	"gopkg.in/alecthomas/kingpin.v1"
	"log"
	"os"
)

var (
	app       = kingpin.New("dead-letter-requeue", "Requeues messages from a SQS dead-letter queue to the active one.")
	queueName = app.Arg("queue-name", "Name of the SQS queue (e.g. prod-mgmt-website-data-www100-jimdo-com).").Required().String()
)

func main() {
	kingpin.MustParse(app.Parse(os.Args[1:]))

	activeQueueName := *queueName

	var deadLetterQueueName = activeQueueName + "_dead_letter"

	var auth = aws.Auth{
		AccessKey: os.Getenv("AWS_ACCESS_KEY_ID"),
		SecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
	}

	conn := sqs.New(auth, aws.EUWest)

	deadLetterQueue, err := conn.GetQueue(deadLetterQueueName)
	if err != nil {
		log.Fatalf(err.Error())
		os.Exit(1)
	}

	activeQueue, err := conn.GetQueue(activeQueueName)
	if err != nil {
		log.Fatalf(err.Error())
		os.Exit(1)
	}

	log.Printf("Looking for messages to requeue.")
	for {
		resp, err := deadLetterQueue.ReceiveMessageWithParameters(
			map[string]string{
				"WaitTimeSeconds":     "20",
				"MaxNumberOfMessages": "10",
				"VisibilityTimeout":   "20"})
		if err != nil {
			log.Fatalf(err.Error())
			os.Exit(1)
		}

		messages := resp.Messages
		numberOfMessages := len(messages)
		if numberOfMessages == 0 {
			log.Printf("Requeuing messages done.")
			os.Exit(0)
		} else {
			log.Printf("Moving %v message(s)...", numberOfMessages)
		}

		_, err = activeQueue.SendMessageBatch(messages)
		if err != nil {
			log.Fatalf(err.Error())
			os.Exit(1)
		}

		_, err = deadLetterQueue.DeleteMessageBatch(messages)
		if err != nil {
			log.Fatalf(err.Error())
			os.Exit(1)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"logserver/handlers"
    "github.com/tboeglin/go-loggers/rotatingfile"
	"net/http"
)

func main() {
	var (
		portno  int
		backlogsize int
        logfile string
        logsize int
	)
	flag.IntVar(&portno, "port", 8888, "the port to bind to")
	flag.IntVar(&backlogsize, "backlogsize", 1000, "the size of the backlog to keep in memory for fetching over HTTP")
    flag.StringVar(&logfile, "logfile", "STDERR", "the file to log to, by default the console on stderr")
	flag.IntVar(&logsize, "logsize", 10485760, "the maximum size of the log file before it's rotated")

	flag.Parse()
	handlers.MaxLogSize(backlogsize)
    if logfile != "STDERR" {
        log.SetOutput(rotatingfile.Create(logfile, logsize, 10))
    }
	// handlers
	http.HandleFunc("/log", handlers.HandleLogPost)
	http.HandleFunc("/stats", handlers.HandleStats)

    log.Printf("Starting on port %d with backlog size %d\n", portno, backlogsize)

	err := http.ListenAndServe(fmt.Sprintf(":%d", portno), nil)
	if err != nil {
		log.Fatal("while listening:", err)
	}
}
<commit_msg>change import statement to point to github<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"github.com/tboeglin/go-logserver/handlers"
    "github.com/tboeglin/go-loggers/rotatingfile"
	"net/http"
)

func main() {
	var (
		portno  int
		backlogsize int
        logfile string
        logsize int
	)
	flag.IntVar(&portno, "port", 8888, "the port to bind to")
	flag.IntVar(&backlogsize, "backlogsize", 1000, "the size of the backlog to keep in memory for fetching over HTTP")
    flag.StringVar(&logfile, "logfile", "STDERR", "the file to log to, by default the console on stderr")
	flag.IntVar(&logsize, "logsize", 10485760, "the maximum size of the log file before it's rotated")

	flag.Parse()
	handlers.MaxLogSize(backlogsize)
    if logfile != "STDERR" {
        log.SetOutput(rotatingfile.Create(logfile, logsize, 10))
    }
	// handlers
	http.HandleFunc("/log", handlers.HandleLogPost)
	http.HandleFunc("/stats", handlers.HandleStats)

    log.Printf("Starting on port %d with backlog size %d\n", portno, backlogsize)

	err := http.ListenAndServe(fmt.Sprintf(":%d", portno), nil)
	if err != nil {
		log.Fatal("while listening:", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"net/url"
	"os"
	"os/signal"
	"sort"
	"strings"
	"syscall"
	"time"

	"github.com/lxc/lxd/client"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/i18n"
)

// Lists
const (
	listFormatCSV   = "csv"
	listFormatJSON  = "json"
	listFormatTable = "table"
	listFormatYAML  = "yaml"
)

// Progress tracking
type ProgressRenderer struct {
	Format string

	maxLength int
	wait      time.Time
	done      bool
}

func (p *ProgressRenderer) Done(msg string) {
	p.done = true

	if msg != "" {
		msg += "\n"
	}

	if len(msg) > p.maxLength {
		p.maxLength = len(msg)
	} else {
		fmt.Printf("\r%s", strings.Repeat(" ", p.maxLength))
	}

	fmt.Print("\r")
	fmt.Print(msg)
}

func (p *ProgressRenderer) Update(status string) {
	if p.done {
		return
	}

	timeout := p.wait.Sub(time.Now())
	if timeout.Seconds() > 0 {
		time.Sleep(timeout)
	}

	msg := "%s"
	if p.Format != "" {
		msg = p.Format
	}

	msg = fmt.Sprintf("\r"+msg, status)

	if len(msg) > p.maxLength {
		p.maxLength = len(msg)
	} else {
		fmt.Printf("\r%s", strings.Repeat(" ", p.maxLength))
	}

	fmt.Print(msg)
}

func (p *ProgressRenderer) Warn(status string, timeout time.Duration) {
	p.wait = time.Now().Add(timeout)
	msg := fmt.Sprintf("\r%s", status)

	if len(msg) > p.maxLength {
		p.maxLength = len(msg)
	} else {
		fmt.Printf("\r%s", strings.Repeat(" ", p.maxLength))
	}

	fmt.Print(msg)
}

func (p *ProgressRenderer) UpdateProgress(progress lxd.ProgressData) {
	p.Update(progress.Text)
}

func (p *ProgressRenderer) UpdateOp(op api.Operation) {
	if op.Metadata == nil {
		return
	}

	for _, key := range []string{"fs_progress", "download_progress"} {
		value, ok := op.Metadata[key]
		if ok {
			p.Update(value.(string))
			break
		}
	}
}

type StringList [][]string

func (a StringList) Len() int {
	return len(a)
}

func (a StringList) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a StringList) Less(i, j int) bool {
	x := 0
	for x = range a[i] {
		if a[i][x] != a[j][x] {
			break
		}
	}

	if a[i][x] == "" {
		return false
	}

	if a[j][x] == "" {
		return true
	}

	return a[i][x] < a[j][x]
}

// Container name sorting
type byName [][]string

func (a byName) Len() int {
	return len(a)
}

func (a byName) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a byName) Less(i, j int) bool {
	if a[i][0] == "" {
		return false
	}

	if a[j][0] == "" {
		return true
	}

	return a[i][0] < a[j][0]
}

// Storage volume sorting
type byNameAndType [][]string

func (a byNameAndType) Len() int {
	return len(a)
}

func (a byNameAndType) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a byNameAndType) Less(i, j int) bool {
	if a[i][0] != a[j][0] {
		return a[i][0] < a[j][0]
	}

	if a[i][1] == "" {
		return false
	}

	if a[j][1] == "" {
		return true
	}

	return a[i][1] < a[j][1]
}

// Batch operations
type batchResult struct {
	err  error
	name string
}

func runBatch(names []string, action func(name string) error) []batchResult {
	chResult := make(chan batchResult, len(names))

	for _, name := range names {
		go func(name string) {
			chResult <- batchResult{action(name), name}
		}(name)
	}

	results := []batchResult{}
	for range names {
		results = append(results, <-chResult)
	}

	return results
}

// summaryLine returns the first line of the help text. Conventionally, this
// should be a one-line command summary, potentially followed by a longer
// explanation.
func summaryLine(usage string) string {
	for _, line := range strings.Split(usage, "\n") {
		if strings.HasPrefix(line, "Usage:") {
			continue
		}

		if len(line) == 0 {
			continue
		}

		return strings.TrimSuffix(line, ".")
	}

	return i18n.G("Missing summary.")
}

// Used to return a user friendly error
func getLocalErr(err error) error {
	t, ok := err.(*url.Error)
	if !ok {
		return nil
	}

	u, ok := t.Err.(*net.OpError)
	if !ok {
		return nil
	}

	if u.Op == "dial" && u.Net == "unix" {
		var lxdErr error

		sysErr, ok := u.Err.(*os.SyscallError)
		if ok {
			lxdErr = sysErr.Err
		} else {
			// syscall.Errno may be returned on some systems, e.g. CentOS
			lxdErr, ok = u.Err.(syscall.Errno)
			if !ok {
				return nil
			}
		}

		switch lxdErr {
		case syscall.ENOENT, syscall.ECONNREFUSED, syscall.EACCES:
			return lxdErr
		}
	}

	return nil
}

// Add a device to a container
func containerDeviceAdd(client lxd.ContainerServer, name string, devName string, dev map[string]string) error {
	// Get the container entry
	container, etag, err := client.GetContainer(name)
	if err != nil {
		return err
	}

	// Check if the device already exists
	_, ok := container.Devices[devName]
	if ok {
		return fmt.Errorf(i18n.G("Device already exists: %s"), devName)
	}

	container.Devices[devName] = dev

	op, err := client.UpdateContainer(name, container.Writable(), etag)
	if err != nil {
		return err
	}

	return op.Wait()
}

// Add a device to a profile
func profileDeviceAdd(client lxd.ContainerServer, name string, devName string, dev map[string]string) error {
	// Get the profile entry
	profile, profileEtag, err := client.GetProfile(name)
	if err != nil {
		return err
	}

	// Check if the device already exists
	_, ok := profile.Devices[devName]
	if ok {
		return fmt.Errorf(i18n.G("Device already exists: %s"), devName)
	}

	// Add the device to the container
	profile.Devices[devName] = dev

	err = client.UpdateProfile(name, profile.Writable(), profileEtag)
	if err != nil {
		return err
	}

	return nil
}

// Wait for an operation and cancel it on SIGINT/SIGTERM
func cancelableWait(op *lxd.RemoteOperation, progress *ProgressRenderer) error {
	// Signal handling
	chSignal := make(chan os.Signal)
	signal.Notify(chSignal, os.Interrupt)

	// Operation handling
	chOperation := make(chan error)
	go func() {
		chOperation <- op.Wait()
		close(chOperation)
	}()

	count := 0
	for {
		select {
		case err := <-chOperation:
			return err
		case <-chSignal:
			err := op.CancelTarget()
			if err == nil {
				return fmt.Errorf(i18n.G("Remote operation canceled by user"))
			} else {
				count++

				if count == 3 {
					return fmt.Errorf(i18n.G("User signaled us three times, exiting. The remote operation will keep running."))
				}

				if progress != nil {
					progress.Warn(fmt.Sprintf(i18n.G("%v (interrupt two more times to force)"), err), time.Second*5)
				}
			}
		}
	}
}

// Create the specified image alises, updating those that already exist
func ensureImageAliases(client lxd.ContainerServer, aliases []api.ImageAlias, fingerprint string) error {
	if len(aliases) == 0 {
		return nil
	}

	names := make([]string, len(aliases))
	for i, alias := range aliases {
		names[i] = alias.Name
	}
	sort.Strings(names)

	resp, err := client.GetImageAliases()
	if err != nil {
		return err
	}

	// Delete existing aliases that match provided ones
	for _, alias := range GetExistingAliases(names, resp) {
		err := client.DeleteImageAlias(alias.Name)
		if err != nil {
			fmt.Println(i18n.G("Failed to remove alias %s"), alias.Name)
		}
	}
	// Create new aliases
	for _, alias := range aliases {
		aliasPost := api.ImageAliasesPost{}
		aliasPost.Name = alias.Name
		aliasPost.Target = fingerprint
		err := client.CreateImageAlias(aliasPost)
		if err != nil {
			fmt.Println(i18n.G("Failed to create alias %s"), alias.Name)
		}
	}
	return nil
}

// GetExistingAliases returns the intersection between a list of aliases and all the existing ones.
func GetExistingAliases(aliases []string, allAliases []api.ImageAliasesEntry) []api.ImageAliasesEntry {
	existing := []api.ImageAliasesEntry{}
	for _, alias := range allAliases {
		name := alias.Name
		pos := sort.SearchStrings(aliases, name)
		if pos < len(aliases) && aliases[pos] == name {
			existing = append(existing, alias)
		}
	}
	return existing
}
<commit_msg>lxc/utils: Println doesn't do format strings<commit_after>package main

import (
	"fmt"
	"net"
	"net/url"
	"os"
	"os/signal"
	"sort"
	"strings"
	"syscall"
	"time"

	"github.com/lxc/lxd/client"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/i18n"
)

// Lists
const (
	listFormatCSV   = "csv"
	listFormatJSON  = "json"
	listFormatTable = "table"
	listFormatYAML  = "yaml"
)

// Progress tracking
type ProgressRenderer struct {
	Format string

	maxLength int
	wait      time.Time
	done      bool
}

func (p *ProgressRenderer) Done(msg string) {
	p.done = true

	if msg != "" {
		msg += "\n"
	}

	if len(msg) > p.maxLength {
		p.maxLength = len(msg)
	} else {
		fmt.Printf("\r%s", strings.Repeat(" ", p.maxLength))
	}

	fmt.Print("\r")
	fmt.Print(msg)
}

func (p *ProgressRenderer) Update(status string) {
	if p.done {
		return
	}

	timeout := p.wait.Sub(time.Now())
	if timeout.Seconds() > 0 {
		time.Sleep(timeout)
	}

	msg := "%s"
	if p.Format != "" {
		msg = p.Format
	}

	msg = fmt.Sprintf("\r"+msg, status)

	if len(msg) > p.maxLength {
		p.maxLength = len(msg)
	} else {
		fmt.Printf("\r%s", strings.Repeat(" ", p.maxLength))
	}

	fmt.Print(msg)
}

func (p *ProgressRenderer) Warn(status string, timeout time.Duration) {
	p.wait = time.Now().Add(timeout)
	msg := fmt.Sprintf("\r%s", status)

	if len(msg) > p.maxLength {
		p.maxLength = len(msg)
	} else {
		fmt.Printf("\r%s", strings.Repeat(" ", p.maxLength))
	}

	fmt.Print(msg)
}

func (p *ProgressRenderer) UpdateProgress(progress lxd.ProgressData) {
	p.Update(progress.Text)
}

func (p *ProgressRenderer) UpdateOp(op api.Operation) {
	if op.Metadata == nil {
		return
	}

	for _, key := range []string{"fs_progress", "download_progress"} {
		value, ok := op.Metadata[key]
		if ok {
			p.Update(value.(string))
			break
		}
	}
}

type StringList [][]string

func (a StringList) Len() int {
	return len(a)
}

func (a StringList) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a StringList) Less(i, j int) bool {
	x := 0
	for x = range a[i] {
		if a[i][x] != a[j][x] {
			break
		}
	}

	if a[i][x] == "" {
		return false
	}

	if a[j][x] == "" {
		return true
	}

	return a[i][x] < a[j][x]
}

// Container name sorting
type byName [][]string

func (a byName) Len() int {
	return len(a)
}

func (a byName) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a byName) Less(i, j int) bool {
	if a[i][0] == "" {
		return false
	}

	if a[j][0] == "" {
		return true
	}

	return a[i][0] < a[j][0]
}

// Storage volume sorting
type byNameAndType [][]string

func (a byNameAndType) Len() int {
	return len(a)
}

func (a byNameAndType) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a byNameAndType) Less(i, j int) bool {
	if a[i][0] != a[j][0] {
		return a[i][0] < a[j][0]
	}

	if a[i][1] == "" {
		return false
	}

	if a[j][1] == "" {
		return true
	}

	return a[i][1] < a[j][1]
}

// Batch operations
type batchResult struct {
	err  error
	name string
}

func runBatch(names []string, action func(name string) error) []batchResult {
	chResult := make(chan batchResult, len(names))

	for _, name := range names {
		go func(name string) {
			chResult <- batchResult{action(name), name}
		}(name)
	}

	results := []batchResult{}
	for range names {
		results = append(results, <-chResult)
	}

	return results
}

// summaryLine returns the first line of the help text. Conventionally, this
// should be a one-line command summary, potentially followed by a longer
// explanation.
func summaryLine(usage string) string {
	for _, line := range strings.Split(usage, "\n") {
		if strings.HasPrefix(line, "Usage:") {
			continue
		}

		if len(line) == 0 {
			continue
		}

		return strings.TrimSuffix(line, ".")
	}

	return i18n.G("Missing summary.")
}

// Used to return a user friendly error
func getLocalErr(err error) error {
	t, ok := err.(*url.Error)
	if !ok {
		return nil
	}

	u, ok := t.Err.(*net.OpError)
	if !ok {
		return nil
	}

	if u.Op == "dial" && u.Net == "unix" {
		var lxdErr error

		sysErr, ok := u.Err.(*os.SyscallError)
		if ok {
			lxdErr = sysErr.Err
		} else {
			// syscall.Errno may be returned on some systems, e.g. CentOS
			lxdErr, ok = u.Err.(syscall.Errno)
			if !ok {
				return nil
			}
		}

		switch lxdErr {
		case syscall.ENOENT, syscall.ECONNREFUSED, syscall.EACCES:
			return lxdErr
		}
	}

	return nil
}

// Add a device to a container
func containerDeviceAdd(client lxd.ContainerServer, name string, devName string, dev map[string]string) error {
	// Get the container entry
	container, etag, err := client.GetContainer(name)
	if err != nil {
		return err
	}

	// Check if the device already exists
	_, ok := container.Devices[devName]
	if ok {
		return fmt.Errorf(i18n.G("Device already exists: %s"), devName)
	}

	container.Devices[devName] = dev

	op, err := client.UpdateContainer(name, container.Writable(), etag)
	if err != nil {
		return err
	}

	return op.Wait()
}

// Add a device to a profile
func profileDeviceAdd(client lxd.ContainerServer, name string, devName string, dev map[string]string) error {
	// Get the profile entry
	profile, profileEtag, err := client.GetProfile(name)
	if err != nil {
		return err
	}

	// Check if the device already exists
	_, ok := profile.Devices[devName]
	if ok {
		return fmt.Errorf(i18n.G("Device already exists: %s"), devName)
	}

	// Add the device to the container
	profile.Devices[devName] = dev

	err = client.UpdateProfile(name, profile.Writable(), profileEtag)
	if err != nil {
		return err
	}

	return nil
}

// Wait for an operation and cancel it on SIGINT/SIGTERM
func cancelableWait(op *lxd.RemoteOperation, progress *ProgressRenderer) error {
	// Signal handling
	chSignal := make(chan os.Signal)
	signal.Notify(chSignal, os.Interrupt)

	// Operation handling
	chOperation := make(chan error)
	go func() {
		chOperation <- op.Wait()
		close(chOperation)
	}()

	count := 0
	for {
		select {
		case err := <-chOperation:
			return err
		case <-chSignal:
			err := op.CancelTarget()
			if err == nil {
				return fmt.Errorf(i18n.G("Remote operation canceled by user"))
			} else {
				count++

				if count == 3 {
					return fmt.Errorf(i18n.G("User signaled us three times, exiting. The remote operation will keep running."))
				}

				if progress != nil {
					progress.Warn(fmt.Sprintf(i18n.G("%v (interrupt two more times to force)"), err), time.Second*5)
				}
			}
		}
	}
}

// Create the specified image alises, updating those that already exist
func ensureImageAliases(client lxd.ContainerServer, aliases []api.ImageAlias, fingerprint string) error {
	if len(aliases) == 0 {
		return nil
	}

	names := make([]string, len(aliases))
	for i, alias := range aliases {
		names[i] = alias.Name
	}
	sort.Strings(names)

	resp, err := client.GetImageAliases()
	if err != nil {
		return err
	}

	// Delete existing aliases that match provided ones
	for _, alias := range GetExistingAliases(names, resp) {
		err := client.DeleteImageAlias(alias.Name)
		if err != nil {
			fmt.Println(fmt.Sprintf(i18n.G("Failed to remove alias %s"), alias.Name))
		}
	}
	// Create new aliases
	for _, alias := range aliases {
		aliasPost := api.ImageAliasesPost{}
		aliasPost.Name = alias.Name
		aliasPost.Target = fingerprint
		err := client.CreateImageAlias(aliasPost)
		if err != nil {
			fmt.Println(fmt.Sprintf(i18n.G("Failed to create alias %s"), alias.Name))
		}
	}
	return nil
}

// GetExistingAliases returns the intersection between a list of aliases and all the existing ones.
func GetExistingAliases(aliases []string, allAliases []api.ImageAliasesEntry) []api.ImageAliasesEntry {
	existing := []api.ImageAliasesEntry{}
	for _, alias := range allAliases {
		name := alias.Name
		pos := sort.SearchStrings(aliases, name)
		if pos < len(aliases) && aliases[pos] == name {
			existing = append(existing, alias)
		}
	}
	return existing
}
<|endoftext|>


<commit_before>package leeroy

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/fabioxgn/go-bot"
)

var (
	RepoPrefix string = "docker/"
	BaseUrl    string = "https://leeroy.dockerproject.com/"
)

type PullRequest struct {
	Number  int    `json:"number"`
	Repo    string `json:"repo"`
	Context string `json:"context"`
}

func parsePullRequest(arg string) (pr PullRequest, err error) {
	// parse for the repo
	// split on #
	nameArgs := strings.SplitN(arg, "#", 2)
	if len(nameArgs) <= 1 {
		return pr, fmt.Errorf("%s did not include #", arg)
	}

	pr.Repo = nameArgs[0]

	// parse the second arguement for a /
	// for if its a custom build
	buildArgs := strings.SplitN(nameArgs[1], "/", 2)
	if len(buildArgs) == 2 {
		pr.Context = buildArgs[1]
	}

	// parse as int
	pr.Number, err = strconv.Atoi(buildArgs[0])
	if err != nil {
		return pr, err
	}

	return pr, nil
}

func sendRequest(pr PullRequest, url string) (err error) {
	data, err := json.Marshal(pr)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	req.SetBasicAuth(os.Getenv("LEEROY_USERNAME"), os.Getenv("LEEROY_PASS"))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil
	}
	defer resp.Body.Close()

	if resp.StatusCode != 204 {
		return fmt.Errorf("Requesting %s for PR %d for %s returned status code: %d. Make sure the repo allows builds.", url, pr.Number, pr.Repo, resp.StatusCode)
	}
	return nil
}

func rebuild(command *bot.Cmd) (msg string, err error) {
	tryString := "Try !rebuild libcontainer#234."
	if len(command.Args) < 1 {
		return "", fmt.Errorf("Not enough args. %s", tryString)
	}

	pr, err := parsePullRequest(command.Args[0])
	if err != nil {
		return "", fmt.Errorf("Error parsing pull request: %v. %s", err, tryString)
	}

	endpoint := "build/retry"
	if pr.Context != "" {
		endpoint = "build/custom"
	}

	if err := sendRequest(pr, BaseUrl+endpoint); err != nil {
		return "", err
	}

	if pr.Context != "" {
		return fmt.Sprintf("Building PR %d on %s at https://github.com/%s/pull/%d", pr.Number, pr.Context, pr.Repo, pr.Number), nil
	}

	return fmt.Sprintf("Rebuilding PR %d at https://github.com/%s/pull/%d", pr.Number, pr.Repo, pr.Number), nil
}

func init() {
	bot.RegisterCommand(
		"rebuild",
		"Rebuilds a PR number on Jenkins.",
		"libcontainer#9437",
		rebuild)
}
<commit_msg>forgot repo refix<commit_after>package leeroy

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/fabioxgn/go-bot"
)

var (
	RepoPrefix string = "docker/"
	BaseUrl    string = "https://leeroy.dockerproject.com/"
)

type PullRequest struct {
	Number  int    `json:"number"`
	Repo    string `json:"repo"`
	Context string `json:"context"`
}

func parsePullRequest(arg string) (pr PullRequest, err error) {
	// parse for the repo
	// split on #
	nameArgs := strings.SplitN(arg, "#", 2)
	if len(nameArgs) <= 1 {
		return pr, fmt.Errorf("%s did not include #", arg)
	}

	pr.Repo = RepoPrefix + nameArgs[0]

	// parse the second arguement for a /
	// for if its a custom build
	buildArgs := strings.SplitN(nameArgs[1], "/", 2)
	if len(buildArgs) == 2 {
		pr.Context = buildArgs[1]
	}

	// parse as int
	pr.Number, err = strconv.Atoi(buildArgs[0])
	if err != nil {
		return pr, err
	}

	return pr, nil
}

func sendRequest(pr PullRequest, url string) (err error) {
	data, err := json.Marshal(pr)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	req.SetBasicAuth(os.Getenv("LEEROY_USERNAME"), os.Getenv("LEEROY_PASS"))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil
	}
	defer resp.Body.Close()

	if resp.StatusCode != 204 {
		return fmt.Errorf("Requesting %s for PR %d for %s returned status code: %d. Make sure the repo allows builds.", url, pr.Number, pr.Repo, resp.StatusCode)
	}
	return nil
}

func rebuild(command *bot.Cmd) (msg string, err error) {
	tryString := "Try !rebuild libcontainer#234."
	if len(command.Args) < 1 {
		return "", fmt.Errorf("Not enough args. %s", tryString)
	}

	pr, err := parsePullRequest(command.Args[0])
	if err != nil {
		return "", fmt.Errorf("Error parsing pull request: %v. %s", err, tryString)
	}

	endpoint := "build/retry"
	if pr.Context != "" {
		endpoint = "build/custom"
	}

	if err := sendRequest(pr, BaseUrl+endpoint); err != nil {
		return "", err
	}

	if pr.Context != "" {
		return fmt.Sprintf("Building PR %d on %s at https://github.com/%s/pull/%d", pr.Number, pr.Context, pr.Repo, pr.Number), nil
	}

	return fmt.Sprintf("Rebuilding PR %d at https://github.com/%s/pull/%d", pr.Number, pr.Repo, pr.Number), nil
}

func init() {
	bot.RegisterCommand(
		"rebuild",
		"Rebuilds a PR number on Jenkins.",
		"libcontainer#9437",
		rebuild)
}
<|endoftext|>


<commit_before><commit_msg>Adding error messages assertions in execution tests<commit_after><|endoftext|>


<commit_before>/*
Copyright 2016 Tamás Gulácsi

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

package structs

import (
	"bytes"
	"fmt"
	"io"
	"strings"

	"gopkg.in/errgo.v1"
)

//go:generate go get github.com/golang/protobuf/protoc-gen-go
// https://github.com/google/protobuf/releases/download/v3.0.0-beta-2/protoc-3.0.0-beta-2-linux-x86_64.zip

func SaveProtobuf(dst io.Writer, functions []Function, pkg string) error {
	var err error
	w := errWriter{Writer: dst, err: &err}

	io.WriteString(w, `syntax = "proto3";`+"\n\n")

	if pkg != "" {
		fmt.Fprintf(w, "package %s;", pkg)
	}
	types := make(map[string]string, 16)

FunLoop:
	for _, fun := range functions {
		fun.types = types
		for _, dir := range []bool{false, true} {
			if err := fun.SaveProtobuf(w, dir); err != nil {
				if errgo.Cause(err) == ErrMissingTableOf {
					Log.Warn("SKIP function, missing TableOf info", "function", fun.Name())
					continue FunLoop
				}
				return err
			}
		}
		name := dot2D.Replace(fun.Name())
		fmt.Fprintf(w, `
service %s {
	rpc %s (%s) returns (%s) {}
}
`, name, name, strings.ToLower(fun.getStructName(false)), strings.ToLower(fun.getStructName(true)))
	}

	return nil
}

func (f Function) SaveProtobuf(dst io.Writer, out bool) error {
	dirmap, dirname := uint8(DIR_IN), "input"
	if out {
		dirmap, dirname = DIR_OUT, "output"
	}
	args := make([]Argument, 0, len(f.Args)+1)
	for _, arg := range f.Args {
		if arg.Direction&dirmap > 0 {
			args = append(args, arg)
		}
	}
	// return variable for function out structs
	if out && f.Returns != nil {
		args = append(args, *f.Returns)
	}

	return protoWriteMessageTyp(dst, dot2D.Replace(strings.ToLower(f.Name()))+"__"+dirname, f.types, args...)
}

var dot2D = strings.NewReplacer(".", "__")

func protoWriteMessageTyp(dst io.Writer, msgName string, types map[string]string, args ...Argument) error {
	var err error
	w := errWriter{Writer: dst, err: &err}

	fmt.Fprintf(w, "\nmessage %s {\n", msgName)

	seen := make(map[string]struct{}, 16)
	buf := buffers.Get()
	defer buffers.Put(buf)
	for i, arg := range args {
		if strings.HasSuffix(arg.Name, "#") {
			continue
		}
		if arg.Flavor == FLAVOR_TABLE && arg.TableOf == nil {
			return errgo.WithCausef(nil, ErrMissingTableOf, "no table of data for %s.%s (%v)", msgName, arg, arg)
		}
		aName := arg.Name
		got := arg.goType(types, false)
		var rule string
		if strings.HasPrefix(got, "[]") {
			rule = "repeated "
			got = got[2:]
		}
		if strings.HasPrefix(got, "*") {
			got = got[1:]
		}
		typ := protoType(got)
		if arg.Flavor == FLAVOR_SIMPLE || arg.Flavor == FLAVOR_TABLE && arg.TableOf.Flavor == FLAVOR_SIMPLE {
			fmt.Fprintf(w, "\t%s%s %s = %d;\n", rule, typ, aName, i+1)
			continue
		}
		if _, ok := seen[typ]; !ok {
			//lName := strings.ToLower(arg.Name)
			subArgs := make([]Argument, 0, 16)
			if arg.TableOf != nil {
				if arg.TableOf.RecordOf == nil {
					subArgs = append(subArgs, *arg.TableOf)
				} else {
					for _, v := range arg.TableOf.RecordOf {
						subArgs = append(subArgs, v)
					}
				}
			} else {
				for _, v := range arg.RecordOf {
					subArgs = append(subArgs, v)
				}
			}
			buf.Reset()
			if err := protoWriteMessageTyp(buf, typ, types, subArgs...); err != nil {
				return err
			}
			w.Write(bytes.Replace(buf.Bytes(), []byte("\n"), []byte("\n\t"), -1))
			seen[typ] = struct{}{}
		}
		fmt.Fprintf(w, "\n\t%s%s %s = %d;\n", rule, typ, aName, i+1)
	}
	io.WriteString(w, "}")

	return err
}

func protoType(got string) string {
	switch strings.ToLower(got) {
	case "ora.date":
		return "string"
	case "ora.string":
		return "string"
	case "int32":
		return "sint32"
	case "ora.int32":
		return "sint32"
	case "float64":
		return "double"
	case "ora.float64":
		return "double"
	default:
		return strings.ToLower(strings.TrimPrefix(strings.TrimPrefix(got, "[]"), "*"))
	}
}
<commit_msg>produce global message types<commit_after>/*
Copyright 2016 Tamás Gulácsi

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

package structs

import (
	"fmt"
	"io"
	"strings"

	"gopkg.in/errgo.v1"
)

//go:generate go get github.com/golang/protobuf/protoc-gen-go
// https://github.com/google/protobuf/releases/download/v3.0.0-beta-2/protoc-3.0.0-beta-2-linux-x86_64.zip

func SaveProtobuf(dst io.Writer, functions []Function, pkg string) error {
	var err error
	w := errWriter{Writer: dst, err: &err}

	io.WriteString(w, `syntax = "proto3";`+"\n\n")

	if pkg != "" {
		fmt.Fprintf(w, "package %s;\n", pkg)
	}
	types := make(map[string]string, 16)
	seen := make(map[string]struct{}, 16)

FunLoop:
	for _, fun := range functions {
		name := dot2D.Replace(fun.Name())
		fmt.Fprintf(w, `
service %s {
	rpc %s (%s) returns (%s) {}
}
`, name, name, strings.ToLower(fun.getStructName(false)), strings.ToLower(fun.getStructName(true)))
		fun.types = types
		for _, dir := range []bool{false, true} {
			if err := fun.SaveProtobuf(w, seen, dir); err != nil {
				if errgo.Cause(err) == ErrMissingTableOf {
					Log.Warn("SKIP function, missing TableOf info", "function", fun.Name())
					continue FunLoop
				}
				return err
			}
		}
	}

	return nil
}

func (f Function) SaveProtobuf(dst io.Writer, seen map[string]struct{}, out bool) error {
	dirmap, dirname := uint8(DIR_IN), "input"
	if out {
		dirmap, dirname = DIR_OUT, "output"
	}
	args := make([]Argument, 0, len(f.Args)+1)
	for _, arg := range f.Args {
		if arg.Direction&dirmap > 0 {
			args = append(args, arg)
		}
	}
	// return variable for function out structs
	if out && f.Returns != nil {
		args = append(args, *f.Returns)
	}

	return protoWriteMessageTyp(dst, dot2D.Replace(strings.ToLower(f.Name()))+"__"+dirname, f.types, seen, args...)
}

var dot2D = strings.NewReplacer(".", "__")

func protoWriteMessageTyp(dst io.Writer, msgName string, types map[string]string, seen map[string]struct{}, args ...Argument) error {
	var err error
	w := errWriter{Writer: dst, err: &err}

	fmt.Fprintf(w, "\nmessage %s {\n", msgName)

	buf := buffers.Get()
	defer buffers.Put(buf)
	for i, arg := range args {
		if strings.HasSuffix(arg.Name, "#") {
			continue
		}
		if arg.Flavor == FLAVOR_TABLE && arg.TableOf == nil {
			return errgo.WithCausef(nil, ErrMissingTableOf, "no table of data for %s.%s (%v)", msgName, arg, arg)
		}
		aName := arg.Name
		got := arg.goType(types, false)
		var rule string
		if strings.HasPrefix(got, "[]") {
			rule = "repeated "
			got = got[2:]
		}
		if strings.HasPrefix(got, "*") {
			got = got[1:]
		}
		typ := protoType(got)
		if arg.Flavor == FLAVOR_SIMPLE || arg.Flavor == FLAVOR_TABLE && arg.TableOf.Flavor == FLAVOR_SIMPLE {
			fmt.Fprintf(w, "\t%s%s %s = %d;\n", rule, typ, aName, i+1)
			continue
		}
		if _, ok := seen[typ]; !ok {
			//lName := strings.ToLower(arg.Name)
			subArgs := make([]Argument, 0, 16)
			if arg.TableOf != nil {
				if arg.TableOf.RecordOf == nil {
					subArgs = append(subArgs, *arg.TableOf)
				} else {
					for _, v := range arg.TableOf.RecordOf {
						subArgs = append(subArgs, v)
					}
				}
			} else {
				for _, v := range arg.RecordOf {
					subArgs = append(subArgs, v)
				}
			}
			if err := protoWriteMessageTyp(buf, typ, types, seen, subArgs...); err != nil {
				return err
			}
			seen[typ] = struct{}{}
		}
		fmt.Fprintf(w, "\t%s%s %s = %d;\n", rule, typ, aName, i+1)
	}
	io.WriteString(w, "}\n")
	w.Write(buf.Bytes())

	return err
}

func protoType(got string) string {
	switch strings.ToLower(got) {
	case "ora.date":
		return "string"
	case "ora.string":
		return "string"
	case "int32":
		return "sint32"
	case "ora.int32":
		return "sint32"
	case "float64":
		return "double"
	case "ora.float64":
		return "double"
	default:
		return strings.ToLower(strings.TrimPrefix(strings.TrimPrefix(got, "[]"), "*"))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"github.com/Netflix-Skunkworks/go-jira/jira/cli"
	"github.com/coryb/optigo"
	"github.com/op/go-logging"
	"gopkg.in/coryb/yaml.v2"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

var log = logging.MustGetLogger("jira")
var format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}"

func main() {
	logBackend := logging.NewLogBackend(os.Stderr, "", 0)
	logging.SetBackend(
		logging.NewBackendFormatter(
			logBackend,
			logging.MustStringFormatter(format),
		),
	)
	logging.SetLevel(logging.NOTICE, "")

	user := os.Getenv("USER")
	home := os.Getenv("HOME")
	defaultQueryFields := "summary,created,priority,status,reporter,assignee"
	defaultSort := "priority asc, created"
	defaultMaxResults := 500

	usage := func(ok bool) {
		printer := fmt.Printf
		if !ok {
			printer = func(format string, args ...interface{}) (int, error) {
				return fmt.Fprintf(os.Stderr, format, args...)
			}
			defer func() {
				os.Exit(1)
			}()
		} else {
			defer func() {
				os.Exit(0)
			}()
		}
		output := fmt.Sprintf(`
Usage:
  jira (ls|list) ( [-q JQL] | [-p PROJECT] [-c COMPONENT] [-a ASSIGNEE] [-i ISSUETYPE] [-w WATCHER] [-r REPORTER]) [-f FIELDS] [-s ORDER] [--max_results MAX_RESULTS]
  jira view ISSUE
  jira edit ISSUE [--noedit] [-m COMMENT] [-o KEY=VAL]...
  jira create [--noedit] [-p PROJECT] [-i ISSUETYPE] [-o KEY=VAL]...
  jira DUPLICATE dups ISSUE
  jira BLOCKER blocks ISSUE
  jira watch ISSUE [-w WATCHER]
  jira (trans|transition) TRANSITION ISSUE [-m COMMENT] [-o KEY=VAL] [--noedit]
  jira ack ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
  jira close ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
  jira resolve ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
  jira reopen ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
  jira start ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
  jira stop ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
  jira comment ISSUE [-m COMMENT]
  jira take ISSUE
  jira (assign|give) ISSUE ASSIGNEE
  jira fields
  jira issuelinktypes
  jira transmeta ISSUE
  jira editmeta ISSUE
  jira issuetypes [-p PROJECT]
  jira createmeta [-p PROJECT] [-i ISSUETYPE]
  jira transitions ISSUE
  jira export-templates [-d DIR] [-t template]
  jira (b|browse) ISSUE
  jira login
  jira ISSUE

General Options:
  -e --endpoint=URI   URI to use for jira
  -h --help           Show this usage
  -t --template=FILE  Template file to use for output/editing
  -u --user=USER      Username to use for authenticaion (default: %s)
  -v --verbose        Increase output logging

Command Options:
  -a --assignee=USER        Username assigned the issue
  -b --browse               Open your browser to the Jira issue
  -c --component=COMPONENT  Component to Search for
  -d --directory=DIR        Directory to export templates to (default: %s)
  -f --queryfields=FIELDS   Fields that are used in "list" template: (default: %s)
  -i --issuetype=ISSUETYPE  Jira Issue Type (default: Bug)
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs
  -p --project=PROJECT      Project to Search for
  -q --query=JQL            Jira Query Language expression for the search
  -r --reporter=USER        Reporter to search for
  -s --sort=ORDER           For list operations, sort issues (default: %s)
  -w --watcher=USER         Watcher to add to issue (default: %s)
                            or Watcher to search for
  --max_results=VAL         Maximum number of results to return in query (default: %d)
`, user, fmt.Sprintf("%s/.jira.d/templates", home), defaultQueryFields, defaultSort, user, defaultMaxResults)
		printer(output)
	}

	jiraCommands := map[string]string{
		"list":             "list",
		"ls":               "list",
		"view":             "view",
		"edit":             "edit",
		"create":           "create",
		"dups":             "dups",
		"blocks":           "blocks",
		"watch":            "watch",
		"trans":            "transition",
		"transition":       "transition",
		"ack":              "acknowledge",
		"acknowledge":      "acknowledge",
		"close":            "close",
		"resolve":          "resolve",
		"reopen":           "reopen",
		"start":            "start",
		"stop":             "stop",
		"comment":          "comment",
		"take":             "take",
		"assign":           "assign",
		"give":             "assign",
		"fields":           "fields",
		"issuelinktypes":   "issuelinktypes",
		"transmeta":        "transmeta",
		"editmeta":         "editmeta",
		"issuetypes":       "issuetypes",
		"createmeta":       "createmeta",
		"transitions":      "transitions",
		"export-templates": "export-templates",
		"browse":           "browse",
		"login":            "login",
	}

	defaults := map[string]interface{}{
		"user":        user,
		"queryfields": defaultQueryFields,
		"directory":   fmt.Sprintf("%s/.jira.d/templates", home),
		"sort":        defaultSort,
		"max_results": defaultMaxResults,
	}
	opts := make(map[string]interface{})

	overrides := make(map[string]string)

	setopt := func(name string, value interface{}) {
		opts[name] = value
	}

	op := optigo.NewDirectAssignParser(map[string]interface{}{
		"h|help": usage,
		"v|verbose+": func() {
			logging.SetLevel(logging.GetLevel("")+1, "")
		},
		"dryrun":                setopt,
		"b|browse":              setopt,
		"editor=s":              setopt,
		"u|user=s":              setopt,
		"endpoint=s":            setopt,
		"t|template=s":          setopt,
		"q|query=s":             setopt,
		"p|project=s":           setopt,
		"c|component=s":         setopt,
		"a|assignee=s":          setopt,
		"i|issuetype=s":         setopt,
		"w|watcher=s":           setopt,
		"r|reporter=s":          setopt,
		"f|queryfields=s":       setopt,
		"s|sort=s":              setopt,
		"l|limit|max_results=i": setopt,
		"o|override=s%":         &overrides,
		"noedit":                setopt,
		"edit":                  setopt,
		"m|comment=s":           setopt,
		"d|dir|directory=s":     setopt,
	})

	if err := op.ProcessAll(os.Args[1:]); err != nil {
		log.Error("%s", err)
		usage(false)
	}
	args := op.Args
	opts["overrides"] = overrides

	command := "view"
	if len(args) > 0 {
		if alias, ok := jiraCommands[args[0]]; ok {
			command = alias
			args = args[1:]
		} else if len(args) > 1 {
			// look at second arg for "dups" and "blocks" commands
			if alias, ok := jiraCommands[args[1]]; ok {
				command = alias
				args = append(args[:1], args[2:]...)
			}
		}
	}

	os.Setenv("JIRA_OPERATION", command)
	loadConfigs(opts)

	// apply defaults
	for k, v := range defaults {
		if _, ok := opts[k]; !ok {
			log.Debug("Setting %q to %#v from defaults", k, v)
			opts[k] = v
		}
	}

	log.Debug("opts: %v", opts)
	log.Debug("args: %v", args)

	if _, ok := opts["endpoint"]; !ok {
		log.Error("endpoint option required.  Either use --endpoint or set a enpoint option in your ~/.jira.d/config.yml file")
		os.Exit(1)
	}

	c := cli.New(opts)

	log.Debug("opts: %s", opts)

	setEditing := func(dflt bool) {
		log.Debug("Default Editing: %t", dflt)
		if dflt {
			if val, ok := opts["noedit"].(bool); ok && val {
				log.Debug("Setting edit = false")
				opts["edit"] = false
			} else {
				log.Debug("Setting edit = true")
				opts["edit"] = true
			}
		} else {
			if _, ok := opts["edit"].(bool); !ok {
				log.Debug("Setting edit = %t", dflt)
				opts["edit"] = dflt
			}
		}
	}

	var err error
	switch command {
	case "login":
		err = c.CmdLogin()
	case "fields":
		err = c.CmdFields()
	case "list":
		err = c.CmdList()
	case "edit":
		setEditing(true)
		if len(args) > 0 {
			err = c.CmdEdit(args[0])
		} else {
			var data interface{}
			if data, err = c.FindIssues(); err == nil {
				issues := data.(map[string]interface{})["issues"].([]interface{})
				for _, issue := range issues {
					if err = c.CmdEdit(issue.(map[string]interface{})["key"].(string)); err != nil {
						switch err.(type) {
						case cli.NoChangesFound:
							log.Warning("No Changes found: %s", err)
							err = nil
							continue
						}
						break
					}
				}
			}
		}
	case "editmeta":
		err = c.CmdEditMeta(args[0])
	case "transmeta":
		err = c.CmdTransitionMeta(args[0])
	case "issuelinktypes":
		err = c.CmdIssueLinkTypes()
	case "issuetypes":
		err = c.CmdIssueTypes()
	case "createmeta":
		err = c.CmdCreateMeta()
	case "create":
		setEditing(true)
		err = c.CmdCreate()
	case "transitions":
		err = c.CmdTransitions(args[0])
	case "blocks":
		err = c.CmdBlocks(args[0], args[1])
	case "dups":
		if err = c.CmdDups(args[0], args[1]); err == nil {
			opts["resolution"] = "Duplicate"
			err = c.CmdTransition(args[0], "close")
		}
	case "watch":
		err = c.CmdWatch(args[0])
	case "transition":
		setEditing(true)
		err = c.CmdTransition(args[0], args[1])
	case "close":
		setEditing(false)
		err = c.CmdTransition(args[0], "close")
	case "acknowledge":
		setEditing(false)
		err = c.CmdTransition(args[0], "acknowledge")
	case "reopen":
		setEditing(false)
		err = c.CmdTransition(args[0], "reopen")
	case "resolve":
		setEditing(false)
		err = c.CmdTransition(args[0], "resolve")
	case "start":
		setEditing(false)
		err = c.CmdTransition(args[0], "start")
	case "stop":
		setEditing(false)
		err = c.CmdTransition(args[0], "stop")
	case "comment":
		setEditing(true)
		err = c.CmdComment(args[0])
	case "take":
		err = c.CmdAssign(args[0], opts["user"].(string))
	case "browse":
		opts["browse"] = true
		err = c.Browse(args[0])
	case "export-tempaltes":
		err = c.CmdExportTemplates()
	case "assign":
		err = c.CmdAssign(args[0], args[1])
	default:
		err = c.CmdView(args[0])
	}

	if err != nil {
		log.Error("%s", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func parseYaml(file string, opts map[string]interface{}) {
	if fh, err := ioutil.ReadFile(file); err == nil {
		log.Debug("Found Config file: %s", file)
		yaml.Unmarshal(fh, &opts)
	}
}

func populateEnv(opts map[string]interface{}) {
	for k, v := range opts {
		envName := fmt.Sprintf("JIRA_%s", strings.ToUpper(k))
		var val string
		switch t := v.(type) {
		case string:
			val = t
		case int, int8, int16, int32, int64:
			val = fmt.Sprintf("%d", t)
		case float32, float64:
			val = fmt.Sprintf("%f", t)
		case bool:
			val = fmt.Sprintf("%t", t)
		default:
			val = fmt.Sprintf("%v", t)
		}
		os.Setenv(envName, val)
	}
}

func loadConfigs(opts map[string]interface{}) {
	populateEnv(opts)
	paths := cli.FindParentPaths(".jira.d/config.yml")
	// prepend
	paths = append([]string{"/etc/jira-cli.yml"}, paths...)

	// iterate paths in reverse
	for i := len(paths) - 1; i >= 0; i-- {
		file := paths[i]
		if stat, err := os.Stat(file); err == nil {
			tmp := make(map[string]interface{})
			// check to see if config file is exectuable
			if stat.Mode()&0111 == 0 {
				parseYaml(file, tmp)
			} else {
				log.Debug("Found Executable Config file: %s", file)
				// it is executable, so run it and try to parse the output
				cmd := exec.Command(file)
				stdout := bytes.NewBufferString("")
				cmd.Stdout = stdout
				cmd.Stderr = bytes.NewBufferString("")
				if err := cmd.Run(); err != nil {
					log.Error("%s is exectuable, but it failed to execute: %s\n%s", file, err, cmd.Stderr)
					os.Exit(1)
				}
				yaml.Unmarshal(stdout.Bytes(), &tmp)
			}
			for k, v := range tmp {
				if _, ok := opts[k]; !ok {
					log.Debug("Setting %q to %#v from %s", k, v, file)
					opts[k] = v
				}
			}
			populateEnv(opts)
		}
	}
}
<commit_msg>update usage<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/Netflix-Skunkworks/go-jira/jira/cli"
	"github.com/coryb/optigo"
	"github.com/op/go-logging"
	"gopkg.in/coryb/yaml.v2"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

var log = logging.MustGetLogger("jira")
var format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}"

func main() {
	logBackend := logging.NewLogBackend(os.Stderr, "", 0)
	logging.SetBackend(
		logging.NewBackendFormatter(
			logBackend,
			logging.MustStringFormatter(format),
		),
	)
	logging.SetLevel(logging.NOTICE, "")

	user := os.Getenv("USER")
	home := os.Getenv("HOME")
	defaultQueryFields := "summary,created,priority,status,reporter,assignee"
	defaultSort := "priority asc, created"
	defaultMaxResults := 500

	usage := func(ok bool) {
		printer := fmt.Printf
		if !ok {
			printer = func(format string, args ...interface{}) (int, error) {
				return fmt.Fprintf(os.Stderr, format, args...)
			}
			defer func() {
				os.Exit(1)
			}()
		} else {
			defer func() {
				os.Exit(0)
			}()
		}
		output := fmt.Sprintf(`
Usage:
  jira (ls|list) <Query Options>
  jira view ISSUE
  jira edit [--noedit] <Edit Options> [ISSUE | <Query Options>]
  jira create [--noedit] [-p PROJECT] <Create Options>
  jira DUPLICATE dups ISSUE
  jira BLOCKER blocks ISSUE
  jira watch ISSUE [-w WATCHER]
  jira (trans|transition) TRANSITION ISSUE [--noedit] <Edit Options>
  jira ack ISSUE [--edit] <Edit Options>
  jira close ISSUE [--edit] <Edit Options>
  jira resolve ISSUE [--edit] <Edit Options>
  jira reopen ISSUE [--edit] <Edit Options>
  jira start ISSUE [--edit] <Edit Options>
  jira stop ISSUE [--edit] <Edit Options>
  jira comment ISSUE [--noedit] <Edit Options>
  jira take ISSUE
  jira (assign|give) ISSUE ASSIGNEE
  jira fields
  jira issuelinktypes
  jira transmeta ISSUE
  jira editmeta ISSUE
  jira issuetypes [-p PROJECT]
  jira createmeta [-p PROJECT] [-i ISSUETYPE]
  jira transitions ISSUE
  jira export-templates [-d DIR] [-t template]
  jira (b|browse) ISSUE
  jira login
  jira ISSUE

General Options:
  -b --browse         Open your browser to the Jira issue
  -e --endpoint=URI   URI to use for jira
  -h --help           Show this usage
  -t --template=FILE  Template file to use for output/editing
  -u --user=USER      Username to use for authenticaion (default: %s)
  -v --verbose        Increase output logging

Query Options:
  -a --assignee=USER        Username assigned the issue
  -c --component=COMPONENT  Component to Search for
  -f --queryfields=FIELDS   Fields that are used in "list" template: (default: %s)
  -i --issuetype=ISSUETYPE  The Issue Type
  -l --limit=VAL            Maximum number of results to return in query (default: %d)
  -p --project=PROJECT      Project to Search for
  -q --query=JQL            Jira Query Language expression for the search
  -r --reporter=USER        Reporter to search for
  -s --sort=ORDER           For list operations, sort issues (default: %s)
  -w --watcher=USER         Watcher to add to issue (default: %s)
                            or Watcher to search for

Edit Options:
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs

Create Options:
  -i --issuetype=ISSUETYPE  Jira Issue Type (default: Bug)
  -m --comment=COMMENT      Comment message for transition
  -o --override=KEY=VAL     Set custom key/value pairs

Command Options:
  -d --directory=DIR        Directory to export templates to (default: %s)
`, user, defaultQueryFields, defaultMaxResults, defaultSort, user, fmt.Sprintf("%s/.jira.d/templates", home))
		printer(output)
	}

	jiraCommands := map[string]string{
		"list":             "list",
		"ls":               "list",
		"view":             "view",
		"edit":             "edit",
		"create":           "create",
		"dups":             "dups",
		"blocks":           "blocks",
		"watch":            "watch",
		"trans":            "transition",
		"transition":       "transition",
		"ack":              "acknowledge",
		"acknowledge":      "acknowledge",
		"close":            "close",
		"resolve":          "resolve",
		"reopen":           "reopen",
		"start":            "start",
		"stop":             "stop",
		"comment":          "comment",
		"take":             "take",
		"assign":           "assign",
		"give":             "assign",
		"fields":           "fields",
		"issuelinktypes":   "issuelinktypes",
		"transmeta":        "transmeta",
		"editmeta":         "editmeta",
		"issuetypes":       "issuetypes",
		"createmeta":       "createmeta",
		"transitions":      "transitions",
		"export-templates": "export-templates",
		"browse":           "browse",
		"login":            "login",
	}

	defaults := map[string]interface{}{
		"user":        user,
		"queryfields": defaultQueryFields,
		"directory":   fmt.Sprintf("%s/.jira.d/templates", home),
		"sort":        defaultSort,
		"max_results": defaultMaxResults,
	}
	opts := make(map[string]interface{})

	overrides := make(map[string]string)

	setopt := func(name string, value interface{}) {
		opts[name] = value
	}

	op := optigo.NewDirectAssignParser(map[string]interface{}{
		"h|help": usage,
		"v|verbose+": func() {
			logging.SetLevel(logging.GetLevel("")+1, "")
		},
		"dryrun":                setopt,
		"b|browse":              setopt,
		"editor=s":              setopt,
		"u|user=s":              setopt,
		"endpoint=s":            setopt,
		"t|template=s":          setopt,
		"q|query=s":             setopt,
		"p|project=s":           setopt,
		"c|component=s":         setopt,
		"a|assignee=s":          setopt,
		"i|issuetype=s":         setopt,
		"w|watcher=s":           setopt,
		"r|reporter=s":          setopt,
		"f|queryfields=s":       setopt,
		"s|sort=s":              setopt,
		"l|limit|max_results=i": setopt,
		"o|override=s%":         &overrides,
		"noedit":                setopt,
		"edit":                  setopt,
		"m|comment=s":           setopt,
		"d|dir|directory=s":     setopt,
	})

	if err := op.ProcessAll(os.Args[1:]); err != nil {
		log.Error("%s", err)
		usage(false)
	}
	args := op.Args
	opts["overrides"] = overrides

	command := "view"
	if len(args) > 0 {
		if alias, ok := jiraCommands[args[0]]; ok {
			command = alias
			args = args[1:]
		} else if len(args) > 1 {
			// look at second arg for "dups" and "blocks" commands
			if alias, ok := jiraCommands[args[1]]; ok {
				command = alias
				args = append(args[:1], args[2:]...)
			}
		}
	}

	os.Setenv("JIRA_OPERATION", command)
	loadConfigs(opts)

	// apply defaults
	for k, v := range defaults {
		if _, ok := opts[k]; !ok {
			log.Debug("Setting %q to %#v from defaults", k, v)
			opts[k] = v
		}
	}

	log.Debug("opts: %v", opts)
	log.Debug("args: %v", args)

	if _, ok := opts["endpoint"]; !ok {
		log.Error("endpoint option required.  Either use --endpoint or set a enpoint option in your ~/.jira.d/config.yml file")
		os.Exit(1)
	}

	c := cli.New(opts)

	log.Debug("opts: %s", opts)

	setEditing := func(dflt bool) {
		log.Debug("Default Editing: %t", dflt)
		if dflt {
			if val, ok := opts["noedit"].(bool); ok && val {
				log.Debug("Setting edit = false")
				opts["edit"] = false
			} else {
				log.Debug("Setting edit = true")
				opts["edit"] = true
			}
		} else {
			if _, ok := opts["edit"].(bool); !ok {
				log.Debug("Setting edit = %t", dflt)
				opts["edit"] = dflt
			}
		}
	}

	var err error
	switch command {
	case "login":
		err = c.CmdLogin()
	case "fields":
		err = c.CmdFields()
	case "list":
		err = c.CmdList()
	case "edit":
		setEditing(true)
		if len(args) > 0 {
			err = c.CmdEdit(args[0])
		} else {
			var data interface{}
			if data, err = c.FindIssues(); err == nil {
				issues := data.(map[string]interface{})["issues"].([]interface{})
				for _, issue := range issues {
					if err = c.CmdEdit(issue.(map[string]interface{})["key"].(string)); err != nil {
						switch err.(type) {
						case cli.NoChangesFound:
							log.Warning("No Changes found: %s", err)
							err = nil
							continue
						}
						break
					}
				}
			}
		}
	case "editmeta":
		err = c.CmdEditMeta(args[0])
	case "transmeta":
		err = c.CmdTransitionMeta(args[0])
	case "issuelinktypes":
		err = c.CmdIssueLinkTypes()
	case "issuetypes":
		err = c.CmdIssueTypes()
	case "createmeta":
		err = c.CmdCreateMeta()
	case "create":
		setEditing(true)
		err = c.CmdCreate()
	case "transitions":
		err = c.CmdTransitions(args[0])
	case "blocks":
		err = c.CmdBlocks(args[0], args[1])
	case "dups":
		if err = c.CmdDups(args[0], args[1]); err == nil {
			opts["resolution"] = "Duplicate"
			err = c.CmdTransition(args[0], "close")
		}
	case "watch":
		err = c.CmdWatch(args[0])
	case "transition":
		setEditing(true)
		err = c.CmdTransition(args[0], args[1])
	case "close":
		setEditing(false)
		err = c.CmdTransition(args[0], "close")
	case "acknowledge":
		setEditing(false)
		err = c.CmdTransition(args[0], "acknowledge")
	case "reopen":
		setEditing(false)
		err = c.CmdTransition(args[0], "reopen")
	case "resolve":
		setEditing(false)
		err = c.CmdTransition(args[0], "resolve")
	case "start":
		setEditing(false)
		err = c.CmdTransition(args[0], "start")
	case "stop":
		setEditing(false)
		err = c.CmdTransition(args[0], "stop")
	case "comment":
		setEditing(true)
		err = c.CmdComment(args[0])
	case "take":
		err = c.CmdAssign(args[0], opts["user"].(string))
	case "browse":
		opts["browse"] = true
		err = c.Browse(args[0])
	case "export-tempaltes":
		err = c.CmdExportTemplates()
	case "assign":
		err = c.CmdAssign(args[0], args[1])
	default:
		err = c.CmdView(args[0])
	}

	if err != nil {
		log.Error("%s", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func parseYaml(file string, opts map[string]interface{}) {
	if fh, err := ioutil.ReadFile(file); err == nil {
		log.Debug("Found Config file: %s", file)
		yaml.Unmarshal(fh, &opts)
	}
}

func populateEnv(opts map[string]interface{}) {
	for k, v := range opts {
		envName := fmt.Sprintf("JIRA_%s", strings.ToUpper(k))
		var val string
		switch t := v.(type) {
		case string:
			val = t
		case int, int8, int16, int32, int64:
			val = fmt.Sprintf("%d", t)
		case float32, float64:
			val = fmt.Sprintf("%f", t)
		case bool:
			val = fmt.Sprintf("%t", t)
		default:
			val = fmt.Sprintf("%v", t)
		}
		os.Setenv(envName, val)
	}
}

func loadConfigs(opts map[string]interface{}) {
	populateEnv(opts)
	paths := cli.FindParentPaths(".jira.d/config.yml")
	// prepend
	paths = append([]string{"/etc/jira-cli.yml"}, paths...)

	// iterate paths in reverse
	for i := len(paths) - 1; i >= 0; i-- {
		file := paths[i]
		if stat, err := os.Stat(file); err == nil {
			tmp := make(map[string]interface{})
			// check to see if config file is exectuable
			if stat.Mode()&0111 == 0 {
				parseYaml(file, tmp)
			} else {
				log.Debug("Found Executable Config file: %s", file)
				// it is executable, so run it and try to parse the output
				cmd := exec.Command(file)
				stdout := bytes.NewBufferString("")
				cmd.Stdout = stdout
				cmd.Stderr = bytes.NewBufferString("")
				if err := cmd.Run(); err != nil {
					log.Error("%s is exectuable, but it failed to execute: %s\n%s", file, err, cmd.Stderr)
					os.Exit(1)
				}
				yaml.Unmarshal(stdout.Bytes(), &tmp)
			}
			for k, v := range tmp {
				if _, ok := opts[k]; !ok {
					log.Debug("Setting %q to %#v from %s", k, v, file)
					opts[k] = v
				}
			}
			populateEnv(opts)
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>Print the output of `lsof` when failing to delete the grootfs store in gqt<commit_after><|endoftext|>


<commit_before>package main

import ()

func commenterGetByHex(commenterHex string) (commenter, error) {
	if commenterHex == "" {
		return commenter{}, errorMissingField
	}

	statement := `
    SELECT commenterHex, email, name, link, photo, provider, joinDate
    FROM commenters
    WHERE commenterHex = $1;
  `
	row := db.QueryRow(statement, commenterHex)

	c := commenter{}
	if err := row.Scan(&c.CommenterHex, &c.Email, &c.Name, &c.Link, &c.Photo, &c.Provider, &c.JoinDate); err != nil {
		// TODO: is this the only error?
		return commenter{}, errorNoSuchCommenter
	}

	return c, nil
}

func commenterGetByEmail(provider string, email string) (commenter, error) {
	if provider == "" || email == "" {
		return commenter{}, errorMissingField
	}

	statement := `
    SELECT commenterHex, email, name, link, photo, provider, joinDate
    FROM commenters
    WHERE email = $1 AND provider = $2;
  `
	row := db.QueryRow(statement, email, provider)

	c := commenter{}
	if err := row.Scan(&c.CommenterHex, &c.Email, &c.Name, &c.Link, &c.Photo, &c.Provider, &c.JoinDate); err != nil {
		// TODO: is this the only error?
		return commenter{}, errorNoSuchCommenter
	}

	return c, nil
}

func commenterGetByCommenterToken(commenterToken string) (commenter, error) {
	if commenterToken == "" {
		return commenter{}, errorMissingField
	}

	statement := `
    SELECT commenterHex
    FROM commenterSessions
    WHERE commenterToken = $1;
	`
	row := db.QueryRow(statement, commenterToken)

	var commenterHex string
	if err := row.Scan(&commenterHex); err != nil {
		// TODO: is the only error?
		return commenter{}, errorNoSuchToken
	}

	if commenterHex == "none" {
		return commenter{}, errorNoSuchToken
	}

	return commenterGetByHex(commenterHex)
}
<commit_msg>commenter_get.go: add TODO comment<commit_after>package main

import ()

func commenterGetByHex(commenterHex string) (commenter, error) {
	if commenterHex == "" {
		return commenter{}, errorMissingField
	}

	statement := `
    SELECT commenterHex, email, name, link, photo, provider, joinDate
    FROM commenters
    WHERE commenterHex = $1;
  `
	row := db.QueryRow(statement, commenterHex)

	c := commenter{}
	if err := row.Scan(&c.CommenterHex, &c.Email, &c.Name, &c.Link, &c.Photo, &c.Provider, &c.JoinDate); err != nil {
		// TODO: is this the only error?
		return commenter{}, errorNoSuchCommenter
	}

	return c, nil
}

func commenterGetByEmail(provider string, email string) (commenter, error) {
	if provider == "" || email == "" {
		return commenter{}, errorMissingField
	}

	statement := `
    SELECT commenterHex, email, name, link, photo, provider, joinDate
    FROM commenters
    WHERE email = $1 AND provider = $2;
  `
	row := db.QueryRow(statement, email, provider)

	c := commenter{}
	if err := row.Scan(&c.CommenterHex, &c.Email, &c.Name, &c.Link, &c.Photo, &c.Provider, &c.JoinDate); err != nil {
		// TODO: is this the only error?
		return commenter{}, errorNoSuchCommenter
	}

	return c, nil
}

func commenterGetByCommenterToken(commenterToken string) (commenter, error) {
	if commenterToken == "" {
		return commenter{}, errorMissingField
	}

	statement := `
    SELECT commenterHex
    FROM commenterSessions
    WHERE commenterToken = $1;
	`
	row := db.QueryRow(statement, commenterToken)

	var commenterHex string
	if err := row.Scan(&commenterHex); err != nil {
		// TODO: is the only error?
		return commenter{}, errorNoSuchToken
	}

	if commenterHex == "none" {
		return commenter{}, errorNoSuchToken
	}

	// TODO: use a join instead of two queries?
	return commenterGetByHex(commenterHex)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	log "github.com/Sirupsen/logrus"
	"github.com/bamstats"
)

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

var (
	cpu        = flag.Int("cpu", 1, "number of cpus to be used")
	bam        = flag.String("bam", "", "file to read")
	annotation = flag.String("annotation", "", "bgzip compressed and indexed annotation file")
	loglevel   = flag.String("loglevel", "warn", "logging level")
)

func main() {
	flag.Parse()
	level, err := log.ParseLevel(*loglevel)
	check(err)
	log.SetLevel(level)
	if *bam == "" {
		log.Fatal("no file specified")
	}
	stats := bamstats.Coverage(*bam, *annotation, *cpu)
	bamstats.OutputJson(stats)
}
<commit_msg>Update main to use codegangsta/cli<commit_after>package main

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

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

var (
	bam, annotation, loglevel string
	cpu                       int
)

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

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

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


<commit_before>// Copyright (c) 2015, Alexander Zaytsev. All rights reserved.
// Use of this source code is governed by a GPL-style
// license that can be found in the LICENSE file.

// Main package
//
package main

import (
    "fmt"
    "flag"
    "time"
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/z0rr0/go.t34.me/utils"
    "github.com/z0rr0/go.t34.me/handler"
)

const (
    Port uint = 8080
    Name string = "go.t34.me"
    Config string = "config.json"
)
var (
    Version string = "v0.1 git:000000 2015-01-01"
)

func main() {
    defer func() {
        if r := recover(); r != nil {
            utils.LoggerError.Println(r)
            fmt.Printf("Program \"%v\" %v is terminated abnormally.\n", Name, Version)
        }
    }()
    port := flag.Uint("port", Port, "port number")
    debug := flag.Bool("debug", false, "debug mode")
    config := flag.String("config", Config, "configuration file")
    version := flag.Bool("version", false, "version info")
    flag.Parse()
    if (*version) {
        fmt.Printf("%v version: %v\n", Name, Version)
        return
    }
    fmt.Printf("Program \"%v\" %v is starting...\n", Name, Version)

    utils.LoggerInit(*debug)
    cfg := utils.GetConfig(config)
    utils.LoggerDebug.Printf("port=%v, database=%v, debug=%v", *port, cfg.DbDatabase, *debug)

    router := gin.Default()
    if *debug {
        gin.SetMode(gin.DebugMode)
    } else {
        gin.SetMode(gin.ReleaseMode)
    }
    addr := fmt.Sprintf("localhost:%v", *port)
    server := &http.Server{
        Addr:           addr,
        Handler:        router,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    utils.LoggerDebug.Printf("Listen %v", addr)

    router.NoRoute(handler.NotFound)
    router.GET("/test", handler.Test)
    if err := server.ListenAndServe(); err != nil {
        utils.LoggerError.Panicf("Error: %v", err)
    }

    fmt.Printf("Program \"%v\" %v is successfully terminated.\n", Name, Version)
}
<commit_msg>add pid info<commit_after>// Copyright (c) 2015, Alexander Zaytsev. All rights reserved.
// Use of this source code is governed by a GPL-style
// license that can be found in the LICENSE file.

// Main package
//
package main

import (
    "os"
    "fmt"
    "flag"
    "time"
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/z0rr0/go.t34.me/utils"
    "github.com/z0rr0/go.t34.me/handler"
)

const (
    Port uint = 8080
    Name string = "go.t34.me"
    Config string = "config.json"
)
var (
    Version string = "v0.1 git:000000 2015-01-01"
)

func main() {
    defer func() {
        if r := recover(); r != nil {
            utils.LoggerError.Println(r)
            fmt.Printf("Program \"%v\" %v is terminated abnormally.\n", Name, Version)
        }
    }()
    port := flag.Uint("port", Port, "port number")
    debug := flag.Bool("debug", false, "debug mode")
    config := flag.String("config", Config, "configuration file")
    version := flag.Bool("version", false, "version info")
    flag.Parse()
    if (*version) {
        fmt.Printf("%v version: %v\n", Name, Version)
        return
    }
    fmt.Printf("Program (PID=%v %v:%v) \"%v\" %v is starting...\n", os.Getpid(), os.Getuid(), os.Getgid(), Name, Version)

    utils.LoggerInit(*debug)
    cfg := utils.GetConfig(config)
    utils.LoggerDebug.Printf("port=%v, database=%v, debug=%v", *port, cfg.DbDatabase, *debug)

    router := gin.Default()
    if *debug {
        gin.SetMode(gin.DebugMode)
    } else {
        gin.SetMode(gin.ReleaseMode)
    }
    addr := fmt.Sprintf("localhost:%v", *port)
    server := &http.Server{
        Addr:           addr,
        Handler:        router,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    utils.LoggerDebug.Printf("Listen %v", addr)

    router.NoRoute(handler.NotFound)
    router.GET("/test", handler.Test)
    if err := server.ListenAndServe(); err != nil {
        utils.LoggerError.Panicf("Error: %v", err)
    }

    fmt.Printf("Program \"%v\" %v is successfully terminated.\n", Name, Version)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

const HOST = "http://localhost:8765/"

func main() {
	getAlive()
}

func getAlive() {
	response, err := http.Get(HOST)
	if err != nil {
		fmt.Println("The service is not alive")
		return
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	text := string(body[:])
	fmt.Println(text)
}
<commit_msg>add client test<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

const HOST = "http://localhost:8765/"

func main() {
	getAlive()
}

func getAlive() string {
	response, err := http.Get(HOST)
	if err != nil {
		fmt.Println("The service is not alive")
		return ""
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	text := string(body[:])
	fmt.Println(text)
	return text
}
<|endoftext|>