<commit_before>package start

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"

	flag "github.com/ogier/pflag"
)

// CommandMap represents a list of Command objects.
type CommandMap map[string]*Command // TODO: Make struct with Usage command

// Command defines a command or a subcommand.
// Flags is a list of flag names that the command accepts.
// If a flag is passed to the command that the command does not accept,
// then Up() returns an error. If Flags is empty, all flags are allowed.
// ShortHelp contains a short help string that is used in --help.
// LongHelp contains a usage description that is used in --help <command>.
// Function contains the function to execute. It receives the list of
// arguments (without the flags, which are parsed already).
// For commands with child commands, Function is ignored.
type Command struct {
	Name   string
	Parent string
	Flags  []string
	Short  string
	Long   string
	Cmd    func(cmd *Command) error
	Args   []string

	children CommandMap
}

// Commands is the global command list.
var Commands = make(CommandMap)

// Description is a string used by the Usage command. It should be set to a description of the application before calling Up(). If a user runs the application with no arguments, Usage() will print this description string and list the available commands.
var Description string

// Add adds a command to either the global Commands map, or, if the command has a parent value, to its parent command as a subcommand.
func Add(cmd *Command) error {
	return Commands.Add(cmd)
}

// Add for CommandMap adds a command to a list of commands.
func (c *CommandMap) Add(cmd *Command) error {
	if cmd == nil {
		return errors.New("Add: Parameter cmd must not be nil.")
	}
	cmd.init()
	if cmd.Parent == "" {
		// Add a top-level command.
		if _, alreadyExists := (*c)[cmd.Name]; alreadyExists {
			return errors.New("Add: command " + cmd.Name + " already exists.")
		}
		(*c)[cmd.Name] = cmd
		return nil
	}
	// Add a child command.
	if _, ok := Commands[cmd.Parent]; ok == false {
		return errors.New("Add: Parent command not found for subcommand " +
			cmd.Name + ".")
	}
	return Commands[cmd.Parent].Add(cmd)

	return nil
}

// Add for Command adds a subcommand do a command.
func (parent *Command) Add(cmd *Command) error {
	cmd.init()
	parent.init()
	if _, alreadyExists := (*parent).children[cmd.Name]; alreadyExists {
		return errors.New("Add: subcommand " + cmd.Name +
			" already exists for command " + parent.Name + ".")
	}
	(*parent).children[cmd.Name] = cmd
	return nil
}

// Usage prints a description of the application and the short help string
// of every command, when called with a nil argument.
// When called with a command as parameter, Usage prints this command's
// long help string as well as the short help strings of the available
// subcommands.
func Usage(cmd *Command) error {
	if cmd == nil {
		fmt.Println()
		fmt.Println(filepath.Base(os.Args[0]))
		fmt.Println(Description)
		fmt.Println()
		if len(Commands) > 0 {
			fmt.Println("Available commands:")
			fmt.Println()
			for _, c := range Commands {
				fmt.Println(c.Name)
				fmt.Println(c.Short)
			}
		}
	} else {
		fmt.Println(cmd.Name)
		fmt.Println(cmd.Long)
		if len(cmd.Flags) > 0 {
			if err := Parse(); err != nil {
				return err
			}
			fmt.Println("Available flags:")
			for _, flagName := range cmd.Flags {
				fmt.Print("--" + flagName + ", ")
				flg := flag.Lookup(flagName)
				if flg == nil {
					panic("Flag '" + flagName + "' does not exist.")
				}
				fmt.Println(flg.Shorthand + ": ")
				fmt.Println(flg.Usage)
			}
		}
		fmt.Println()
	}
	return nil
}

// initCommand initializes the children map.
func (cmd *Command) init() *Command {
	if len(cmd.children) == 0 {
		cmd.children = make(CommandMap)
	}
	return cmd
}

// globalFlags identifies those flags that none of the commands
// claims as its private flags.
// It returns a slice with the names of the global flags.
func globalFlags() []string {
	return []string{} // TODO
}

// checkFlags verifies if the flags passed on the command line
// are accepted by the given command.
// It returns a list of flags that the command has rejected,
// for preparing a suitable error message.
func checkFlags(c *Command) []string {
	// TODO: find the flags that this command does not use for itself AND
	// that are used by some other command -> These are not global flags,
	// hence are not allowed with this command.
	return []string{} // TODO
}

// readCommand extracts the command (and any subcommand, if applicable) from the
// list of arguments.
// Parameter args is the list of arguments *after* being parsed by flag.Parse().
// The first item of args is expected to be a command name. If that command has
// subcommands defined, the second item must contain the name of a subcommand.
// If the first argument does not contain a valid command name, readCommand
// returns the pre-defined help command.
func readCommand(args []string) (*Command, error) {
	var cmd, subcmd *Command
	var ok bool
	var name = args[0]
	if cmd, ok = Commands[name]; ok {
		// command found. Remove it from the argument list.
		args = args[1:]
		if len(cmd.children) > 0 {
			var subname = args[0]
			subcmd, ok = cmd.children[subname]
			if ok {
				// subcommand found.
				args = args[1:]
				cmd = subcmd
			} else {
				// no subcommand passed in, so cmd should have a Cmd to execute
				if cmd.Cmd == nil {
					errmsg := "Command " + cmd.Name + " requires one of these subcommands: "
					for _, n := range cmd.children {
						errmsg += n.Name + ", "
					}
					return nil, errors.New(errmsg)
				}
			}
		} else {
			cmd = Commands[name]
		}
		cmd.Args = args
		return cmd, nil
	}
	return &Command{
		Cmd: Usage,
	}, nil
}
<commit_msg>Changed: Pimped up the formatting of the usage output.<commit_after>package start

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"

	flag "github.com/ogier/pflag"
)

// CommandMap represents a list of Command objects.
type CommandMap map[string]*Command // TODO: Make struct with Usage command

// Command defines a command or a subcommand.
// Flags is a list of flag names that the command accepts.
// If a flag is passed to the command that the command does not accept,
// and if that flag is not among the global flags available for all commands,
// then Up() returns an error. If Flags is empty, all global flags are allowed.
// ShortHelp contains a short help string that is used in --help.
// LongHelp contains a usage description that is used in --help <command>.
// Cmd contains the function to execute. It receives the list of
// arguments (without the flags, which are parsed already).
// For commands with child commands, Cmd can be left empty.
type Command struct {
	Name   string
	Parent string
	Flags  []string
	Short  string
	Long   string
	Cmd    func(cmd *Command) error
	Args   []string

	children CommandMap
}

// Commands is the global command list.
var Commands = make(CommandMap)

// Description is a string used by the Usage command. It should be set to a description of the application before calling Up(). If a user runs the application with no arguments, Usage() will print this description string and list the available commands.
var Description string

// Add adds a command to either the global Commands map, or, if the command has a parent value, to its parent command as a subcommand.
func Add(cmd *Command) error {
	return Commands.Add(cmd)
}

// Add for CommandMap adds a command to a list of commands.
func (c *CommandMap) Add(cmd *Command) error {
	if cmd == nil {
		return errors.New("Add: Parameter cmd must not be nil.")
	}
	cmd.init()
	if cmd.Parent == "" {
		// Add a top-level command.
		if _, alreadyExists := (*c)[cmd.Name]; alreadyExists {
			return errors.New("Add: command " + cmd.Name + " already exists.")
		}
		(*c)[cmd.Name] = cmd
		return nil
	}
	// Add a child command.
	if _, ok := Commands[cmd.Parent]; ok == false {
		return errors.New("Add: Parent command not found for subcommand " +
			cmd.Name + ".")
	}
	return Commands[cmd.Parent].Add(cmd)

	return nil
}

// Add for Command adds a subcommand do a command.
func (parent *Command) Add(cmd *Command) error {
	cmd.init()
	parent.init()
	if _, alreadyExists := (*parent).children[cmd.Name]; alreadyExists {
		return errors.New("Add: subcommand " + cmd.Name +
			" already exists for command " + parent.Name + ".")
	}
	(*parent).children[cmd.Name] = cmd
	return nil
}

// Usage prints a description of the application and the short help string
// of every command, when called with a nil argument.
// When called with a command as parameter, Usage prints this command's
// long help string as well as the short help strings of the available
// subcommands.
func Usage(cmd *Command) error {
	if cmd == nil {
		fmt.Println()
		fmt.Println(filepath.Base(os.Args[0]))
		fmt.Println(Description)
		fmt.Println()
		if len(Commands) > 0 {
			width := maxCmdNameLen()
			fmt.Println("Available commands:")
			fmt.Println()
			for _, c := range Commands {
				fmt.Printf("%-*s  %s\n", width, c.Name, c.Short)
			}
		}
	} else {
		fmt.Println(cmd.Name)
		fmt.Println(cmd.Long)
		if len(cmd.Flags) > 0 {
			if err := Parse(); err != nil {
				return err
			}
			fmt.Println()
			fmt.Println("Available flags:")
			fmt.Println()
			flagList := [][]string{}
			var flagNamesAndDefault string
			var width int
			for _, flagName := range cmd.Flags {
				flg := flag.Lookup(flagName)
				if flg == nil {
					panic("Flag '" + flagName + "' does not exist.")
				}
				flagNamesAndDefault = fmt.Sprintf("-%s, --%s=%s", flg.Shorthand, flagName, flg.Value)
				if width < len(flagNamesAndDefault) {
					width = len(flagNamesAndDefault)
				}
				flagList = append(flagList, []string{flagNamesAndDefault, flg.Usage})
			}
			for _, flg := range flagList {
				fmt.Printf("%-*s  %s\n", width, flg[0], flg[1])

			}
		}
	}
	fmt.Println()
	return nil
}

// maxCmdNameLen returns the length of the longest command name.
func maxCmdNameLen() int {
	maxLength := 0
	for _, cmd := range Commands {
		length := len(cmd.Name)
		if length > maxLength {
			maxLength = length
		}
	}
	return maxLength
}

// initCommand initializes the children map.
func (cmd *Command) init() *Command {
	if len(cmd.children) == 0 {
		cmd.children = make(CommandMap)
	}
	return cmd
}

// globalFlags identifies those flags that none of the commands
// claims as its private flags.
// It returns a slice with the names of the global flags.
func globalFlags() []string {
	return []string{} // TODO
}

// checkFlags verifies if the flags passed on the command line
// are accepted by the given command.
// It returns a list of flags that the command has rejected,
// for preparing a suitable error message.
func checkFlags(c *Command) []string {
	// TODO: find the flags that this command does not use for itself AND
	// that are used by some other command -> These are not global flags,
	// hence are not allowed with this command.
	return []string{} // TODO
}

// readCommand extracts the command (and any subcommand, if applicable) from the
// list of arguments.
// Parameter args is the list of arguments *after* being parsed by flag.Parse().
// The first item of args is expected to be a command name. If that command has
// subcommands defined, the second item must contain the name of a subcommand.
// If the first argument does not contain a valid command name, readCommand
// returns the pre-defined help command.
func readCommand(args []string) (*Command, error) {
	var cmd, subcmd *Command
	var ok bool
	var name = args[0]
	if cmd, ok = Commands[name]; ok {
		// command found. Remove it from the argument list.
		args = args[1:]
		if len(cmd.children) > 0 {
			var subname = args[0]
			subcmd, ok = cmd.children[subname]
			if ok {
				// subcommand found.
				args = args[1:]
				cmd = subcmd
			} else {
				// no subcommand passed in, so cmd should have a Cmd to execute
				if cmd.Cmd == nil {
					errmsg := "Command " + cmd.Name + " requires one of these subcommands: "
					for _, n := range cmd.children {
						errmsg += n.Name + ", "
					}
					return nil, errors.New(errmsg)
				}
			}
		} else {
			cmd = Commands[name]
		}
		cmd.Args = args
		return cmd, nil
	}
	return &Command{
		Cmd: Usage,
	}, nil
}
<|endoftext|>


<commit_before>package nsq

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"strconv"
	"strings"
)

type Command struct {
	Name   []byte
	Params [][]byte
	Body   []byte
}

func (c *Command) String() string {
	if len(c.Params) > 0 {
		return fmt.Sprintf("%s %s", c.Name, string(bytes.Join(c.Params, []byte(" "))))
	}
	return string(c.Name)
}

func (c *Command) Write(w io.Writer) error {
	_, err := w.Write(c.Name)
	if err != nil {
		return err
	}

	for _, param := range c.Params {
		_, err := w.Write([]byte(" "))
		if err != nil {
			return err
		}
		_, err = w.Write(param)
		if err != nil {
			return err
		}
	}

	_, err = w.Write([]byte("\n"))
	if err != nil {
		return err
	}

	if c.Body != nil {
		bodySize := int32(len(c.Body))
		err := binary.Write(w, binary.BigEndian, &bodySize)
		if err != nil {
			return err
		}
		_, err = w.Write(c.Body)
		if err != nil {
			return err
		}
	}

	return nil
}

// Announce creates a new Command to announce the existence of
// a given topic and/or channel.
// NOTE: if channel == "." then it is considered n/a
func Announce(topic string, channel string, port int, ips []string) *Command {
	var params = [][]byte{[]byte(topic), []byte(channel), []byte(strconv.Itoa(port))}
	return &Command{[]byte("ANNOUNCE"), params, []byte(strings.Join(ips, "\n"))}
}

// Identify is the first message sent to the Lookupd and provides information about the client
func Identify(version string, tcpPort int, httpPort int, address string) *Command {
	body, err := json.Marshal(struct {
		Version  string `json:"version"`
		TcpPort  int    `json:"tcp_port"`
		HttpPort int    `json:"http_port"`
		Address  string `json:"address"`
	}{
		version,
		tcpPort,
		httpPort,
		address,
	})
	if err != nil {
		log.Fatal("failed to create json %s", err.Error())
	}
	return &Command{[]byte("IDENTIFY"), [][]byte{}, body}
}

// REGISTER a topic/channel for this nsqd
func Register(topic string, channel string) *Command {
	params := [][]byte{[]byte(topic)}
	if len(channel) > 0 {
		params = append(params, []byte(channel))
	}
	return &Command{[]byte("REGISTER"), params, nil}
}

// UNREGISTER removes a topic/channel from this nsqd
func UnRegister(topic string, channel string) *Command {
	params := [][]byte{[]byte(topic)}
	if len(channel) > 0 {
		params = append(params, []byte(channel))
	}
	return &Command{[]byte("UNREGISTER"), params, nil}
}

// Ping creates a new Command to keep-alive the state of all the
// announced topic/channels for a given client
func Ping() *Command {
	return &Command{[]byte("PING"), nil, nil}
}

// Publish creates a new Command to write a message to a given topic
func Publish(topic string, body []byte) *Command {
	var params = [][]byte{[]byte(topic)}
	return &Command{[]byte("PUB"), params, body}
}

func MultiPublish(topic string, bodies [][]byte) (*Command, error) {
	var params = [][]byte{[]byte(topic)}

	num := uint32(len(bodies))
	bodySize := 4
	for _, b := range bodies {
		bodySize += len(b) + 4
	}
	body := make([]byte, bodySize)
	buf := bytes.NewBuffer(body)

	err := binary.Write(buf, binary.BigEndian, &num)
	if err != nil {
		return nil, err
	}
	for _, b := range bodies {
		err = binary.Write(buf, binary.BigEndian, int32(len(b)))
		if err != nil {
			return nil, err
		}
		_, err = buf.Write(b)
		if err != nil {
			return nil, err
		}
	}

	return &Command{[]byte("MPUB"), params, body}, nil
}

// Subscribe creates a new Command to subscribe
// to the given topic/channel
func Subscribe(topic string, channel string, shortIdentifier string, longIdentifier string) *Command {
	var params = [][]byte{[]byte(topic), []byte(channel), []byte(shortIdentifier), []byte(longIdentifier)}
	return &Command{[]byte("SUB"), params, nil}
}

// Ready creates a new Command to specify
// the number of messages a client is willing to receive
func Ready(count int) *Command {
	var params = [][]byte{[]byte(strconv.Itoa(count))}
	return &Command{[]byte("RDY"), params, nil}
}

// Finish creates a new Command to indiciate that
// a given message (by id) has been processed successfully
func Finish(id []byte) *Command {
	var params = [][]byte{id}
	return &Command{[]byte("FIN"), params, nil}
}

// Requeue creats a new Command to indicate that
// a given message (by id) should be requeued after the given timeout (in ms)
// NOTE: a timeout of 0 indicates immediate requeue
func Requeue(id []byte, timeoutMs int) *Command {
	var params = [][]byte{id, []byte(strconv.Itoa(timeoutMs))}
	return &Command{[]byte("REQ"), params, nil}
}

// StartClose creates a new Command to indicate that the
// client would like to start a close cycle.  nsqd will no longer
// send messages to a client in this state and the client is expected
// to ACK after which it can finish pending messages and close the connection
func StartClose() *Command {
	return &Command{[]byte("CLS"), nil, nil}
}

func Nop() *Command {
	return &Command{[]byte("NOP"), nil, nil}
}
<commit_msg>nsqd: fix MPUB bugs<commit_after>package nsq

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"strconv"
	"strings"
)

type Command struct {
	Name   []byte
	Params [][]byte
	Body   []byte
}

func (c *Command) String() string {
	if len(c.Params) > 0 {
		return fmt.Sprintf("%s %s", c.Name, string(bytes.Join(c.Params, []byte(" "))))
	}
	return string(c.Name)
}

func (c *Command) Write(w io.Writer) error {
	_, err := w.Write(c.Name)
	if err != nil {
		return err
	}

	for _, param := range c.Params {
		_, err := w.Write([]byte(" "))
		if err != nil {
			return err
		}
		_, err = w.Write(param)
		if err != nil {
			return err
		}
	}

	_, err = w.Write([]byte("\n"))
	if err != nil {
		return err
	}

	if c.Body != nil {
		bodySize := int32(len(c.Body))
		err := binary.Write(w, binary.BigEndian, &bodySize)
		if err != nil {
			return err
		}
		_, err = w.Write(c.Body)
		if err != nil {
			return err
		}
	}

	return nil
}

// Announce creates a new Command to announce the existence of
// a given topic and/or channel.
// NOTE: if channel == "." then it is considered n/a
func Announce(topic string, channel string, port int, ips []string) *Command {
	var params = [][]byte{[]byte(topic), []byte(channel), []byte(strconv.Itoa(port))}
	return &Command{[]byte("ANNOUNCE"), params, []byte(strings.Join(ips, "\n"))}
}

// Identify is the first message sent to the Lookupd and provides information about the client
func Identify(version string, tcpPort int, httpPort int, address string) *Command {
	body, err := json.Marshal(struct {
		Version  string `json:"version"`
		TcpPort  int    `json:"tcp_port"`
		HttpPort int    `json:"http_port"`
		Address  string `json:"address"`
	}{
		version,
		tcpPort,
		httpPort,
		address,
	})
	if err != nil {
		log.Fatal("failed to create json %s", err.Error())
	}
	return &Command{[]byte("IDENTIFY"), [][]byte{}, body}
}

// REGISTER a topic/channel for this nsqd
func Register(topic string, channel string) *Command {
	params := [][]byte{[]byte(topic)}
	if len(channel) > 0 {
		params = append(params, []byte(channel))
	}
	return &Command{[]byte("REGISTER"), params, nil}
}

// UNREGISTER removes a topic/channel from this nsqd
func UnRegister(topic string, channel string) *Command {
	params := [][]byte{[]byte(topic)}
	if len(channel) > 0 {
		params = append(params, []byte(channel))
	}
	return &Command{[]byte("UNREGISTER"), params, nil}
}

// Ping creates a new Command to keep-alive the state of all the
// announced topic/channels for a given client
func Ping() *Command {
	return &Command{[]byte("PING"), nil, nil}
}

// Publish creates a new Command to write a message to a given topic
func Publish(topic string, body []byte) *Command {
	var params = [][]byte{[]byte(topic)}
	return &Command{[]byte("PUB"), params, body}
}

func MultiPublish(topic string, bodies [][]byte) (*Command, error) {
	var params = [][]byte{[]byte(topic)}

	num := uint32(len(bodies))
	bodySize := 4
	for _, b := range bodies {
		bodySize += len(b) + 4
	}
	body := make([]byte, 0, bodySize)
	buf := bytes.NewBuffer(body)

	err := binary.Write(buf, binary.BigEndian, &num)
	if err != nil {
		return nil, err
	}
	for _, b := range bodies {
		err = binary.Write(buf, binary.BigEndian, int32(len(b)))
		if err != nil {
			return nil, err
		}
		_, err = buf.Write(b)
		if err != nil {
			return nil, err
		}
	}

	return &Command{[]byte("MPUB"), params, buf.Bytes()}, nil
}

// Subscribe creates a new Command to subscribe
// to the given topic/channel
func Subscribe(topic string, channel string, shortIdentifier string, longIdentifier string) *Command {
	var params = [][]byte{[]byte(topic), []byte(channel), []byte(shortIdentifier), []byte(longIdentifier)}
	return &Command{[]byte("SUB"), params, nil}
}

// Ready creates a new Command to specify
// the number of messages a client is willing to receive
func Ready(count int) *Command {
	var params = [][]byte{[]byte(strconv.Itoa(count))}
	return &Command{[]byte("RDY"), params, nil}
}

// Finish creates a new Command to indiciate that
// a given message (by id) has been processed successfully
func Finish(id []byte) *Command {
	var params = [][]byte{id}
	return &Command{[]byte("FIN"), params, nil}
}

// Requeue creats a new Command to indicate that
// a given message (by id) should be requeued after the given timeout (in ms)
// NOTE: a timeout of 0 indicates immediate requeue
func Requeue(id []byte, timeoutMs int) *Command {
	var params = [][]byte{id, []byte(strconv.Itoa(timeoutMs))}
	return &Command{[]byte("REQ"), params, nil}
}

// StartClose creates a new Command to indicate that the
// client would like to start a close cycle.  nsqd will no longer
// send messages to a client in this state and the client is expected
// to ACK after which it can finish pending messages and close the connection
func StartClose() *Command {
	return &Command{[]byte("CLS"), nil, nil}
}

func Nop() *Command {
	return &Command{[]byte("NOP"), nil, nil}
}
<|endoftext|>


<commit_before>package hexa

import (
	"context"
	"log"
	"os/exec"
)

func NewCommand(parent context.Context, name string, args ...string) StoppableOne {
	own_ctx := NewDContextToStoppable(parent)
	cmd := exec.CommandContext(own_ctx, name, args...)
	go func() {
		defer own_ctx.InClose()
		err := cmd.Run()
		if err != nil {
			log.Printf("%+v", err)
		}
	}()
	return own_ctx
}
<commit_msg>plumber interface is added to commnad<commit_after>package hexa

import (
	"context"
	"io"
	"log"
	"os/exec"
)

type StdPlumber interface {
	StderrPipe() (io.ReadCloser, error)
	StdinPipe() (io.WriteCloser, error)
	StdoutPipe() (io.ReadCloser, error)
}

func NewCommand(parent context.Context, pipeHandler func(plumber StdPlumber), name string, args ...string) StoppableOne {
	own_ctx := NewDContextToStoppable(parent)
	cmd := exec.CommandContext(own_ctx, name, args...)

	pipeHandler(cmd)

	go func() {
		defer own_ctx.InClose()
		err := cmd.Run()
		if err != nil {
			log.Printf("%+v", err)
		}
	}()
	return own_ctx
}
<|endoftext|>


<commit_before>package irckit

import (
	"errors"
	"fmt"
	"strings"

	"github.com/sorcix/irc"
)

// The error returned when an invalid command is issued.
var ErrUnknownCommand = errors.New("unknown command")

type Handler struct {
	// Command is the IRC command that this is a handler for.
	Command string
	// Handler is a function that takes the server, user who sent the message, and a message to perform some command.
	Call func(s Server, u *User, msg *irc.Message) error
	// MinParams is the minimum number of params required on the message.
	MinParams int
	// TODO: Add mode constraints?
}

type Commands map[string]Handler

func (cmds Commands) Add(h Handler) {
	cmds[h.Command] = h
}

func (cmds Commands) Run(s Server, u *User, msg *irc.Message) error {
	cmd, ok := cmds[msg.Command]
	if !ok {
		return ErrUnknownCommand
	}
	if len(msg.Params) < cmd.MinParams {
		return u.Encode(&irc.Message{
			Prefix:  s.Prefix(),
			Command: irc.ERR_NEEDMOREPARAMS,
			Params:  []string{msg.Command},
		})
	}
	return cmd.Call(s, u, msg)
}

func DefaultCommands() Commands {
	cmds := Commands{}

	cmds.Add(Handler{Command: irc.PART, Call: CmdPart, MinParams: 1})
	cmds.Add(Handler{Command: irc.QUIT, Call: CmdQuit})
	cmds.Add(Handler{Command: irc.PING, Call: CmdPing})
	cmds.Add(Handler{Command: irc.JOIN, Call: CmdJoin, MinParams: 1})
	cmds.Add(Handler{Command: irc.MOTD, Call: CmdMotd})
	cmds.Add(Handler{Command: irc.NAMES, Call: CmdNames, MinParams: 1})
	cmds.Add(Handler{Command: irc.WHO, Call: CmdWho, MinParams: 1})
	cmds.Add(Handler{Command: irc.ISON, Call: CmdIson, MinParams: 1})
	cmds.Add(Handler{Command: irc.PRIVMSG, Call: CmdPrivMsg, MinParams: 1})
	cmds.Add(Handler{Command: irc.NICK, Call: CmdNick, MinParams: 1})

	return cmds
}

func CmdPart(s Server, u *User, msg *irc.Message) error {
	// TODO: Handle 0
	channels := strings.Split(msg.Params[0], ",")
	for _, chName := range channels {
		ch, exists := s.HasChannel(chName)
		if !exists {
			u.Encode(&irc.Message{
				Prefix:   s.Prefix(),
				Command:  irc.ERR_NOSUCHCHANNEL,
				Params:   []string{chName},
				Trailing: "No such channel",
			})
			continue
		}
		ch.Part(u, msg.Trailing)
	}
	return nil
}

func CmdQuit(s Server, u *User, msg *irc.Message) error {
	u.Encode(&irc.Message{
		Prefix:   u.Prefix(),
		Command:  irc.QUIT,
		Trailing: msg.Trailing,
	})
	u.Encode(&irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.ERROR,
		Trailing: "You will be missed.",
	})
	s.Publish(&event{QuitEvent, s, nil, u, msg})
	return nil
}

func CmdPing(s Server, u *User, msg *irc.Message) error {
	return u.Encode(&irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.PONG,
		Params:   []string{s.Name()},
		Trailing: msg.Trailing,
	})
}

func CmdJoin(s Server, u *User, msg *irc.Message) error {
	// TODO: Handle invite-only
	/*
		return u.Encode(&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.ERR_INVITEONLYCHAN,
			Trailing: "Cannot join channel (+i)",
		})
	*/
	channels := strings.Split(msg.Params[0], ",")
	for _, channel := range channels {
		// XXX: Handle no create permission.
		ch := s.Channel(channel)
		err := ch.Join(u)
		if err == nil {
			s.Publish(&event{JoinEvent, s, ch, u, msg})
		}
	}
	return nil
}

func CmdMotd(s Server, u *User, _ *irc.Message) error {
	motd := s.Motd()
	r := make([]*irc.Message, 0, len(motd)+2)
	r = append(r, &irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.RPL_MOTDSTART,
		Params:   []string{u.Nick},
		Trailing: fmt.Sprintf("- %s Message of the Day -", s.Name()),
	})

	for _, line := range motd {
		r = append(r, &irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_MOTD,
			Params:   []string{u.Nick},
			Trailing: fmt.Sprintf("- %s", line),
		})
	}

	r = append(r, &irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.RPL_ENDOFMOTD,
		Params:   []string{u.Nick},
		Trailing: "End of /MOTD command.",
	})

	return u.Encode(r...)
}

func CmdNames(s Server, u *User, msg *irc.Message) error {
	// TODO: Handle multiple channels? Queries?
	channels := msg.Params

	// TODO: Support full list?
	r := []*irc.Message{}
	for _, channel := range channels {
		ch, exists := s.HasChannel(channel)
		if !exists {
			continue
		}
		// FIXME: This needs to be broken up into multiple messages to fit <510 chars
		msg := irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_NAMREPLY,
			Params:   []string{u.Nick, "=", channel},
			Trailing: strings.Join(ch.Names(), " "),
		}
		r = append(r, &msg)
	}
	endParams := []string{u.Nick}
	if len(channels) == 1 {
		endParams = append(endParams, channels[0])
	}
	r = append(r, &irc.Message{
		Prefix:   s.Prefix(),
		Params:   endParams,
		Command:  irc.RPL_ENDOFNAMES,
		Trailing: "End of /NAMES list.",
	})
	return u.Encode(r...)
}

func CmdWho(s Server, u *User, msg *irc.Message) error {
	// TODO: Use opFilter
	//opFilter := len(msg.Params) >= 2 && msg.Params[1] == "o"
	mask := msg.Params[0]

	endMsg := &irc.Message{
		Prefix:   s.Prefix(),
		Params:   []string{u.Nick, mask},
		Command:  irc.RPL_ENDOFWHO,
		Trailing: "End of /WHO list.",
	}

	// TODO: Handle arbitrary masks, not just channels
	ch, exists := s.HasChannel(mask)
	if !exists {
		return u.Encode(endMsg)
	}

	r := make([]*irc.Message, 0, ch.Len()+1)
	for _, other := range ch.Users() {
		// <me> <channel> <user> <host> <server> <nick> [H/G]: 0 <real>
		r = append(r, &irc.Message{
			Prefix:   s.Prefix(),
			Params:   []string{u.Nick, mask, other.User, other.Host, "*", other.Nick, "H"},
			Command:  irc.RPL_WHOREPLY,
			Trailing: "0 " + other.Real,
		})
	}

	r = append(r, endMsg)
	return u.Encode(r...)
}

func CmdIson(s Server, u *User, msg *irc.Message) error {
	nicks := msg.Params
	on := make([]string, 0, len(nicks))
	for _, nick := range nicks {
		if _, ok := s.HasUser(nick); ok {
			on = append(on, nick)
		}
	}

	return u.Encode(
		&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_ISON,
			Params:   []string{u.Nick},
			Trailing: strings.Join(on, " "),
		},
	)
}

func CmdPrivMsg(s Server, u *User, msg *irc.Message) error {
	query := msg.Params[0]
	if toChan, exists := s.HasChannel(query); exists {
		toChan.Message(u, msg.Trailing)
		s.Publish(&event{ChanMsgEvent, s, toChan, u, msg})
	} else if toUser, exists := s.HasUser(query); exists {
		s.Publish(&event{UserMsgEvent, s, nil, u, msg})
		toUser.Encode(&irc.Message{
			Prefix:   u.Prefix(),
			Command:  irc.PRIVMSG,
			Params:   []string{toUser.Nick},
			Trailing: msg.Trailing,
		})
	} else {
		return u.Encode(&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.ERR_NOSUCHNICK,
			Params:   msg.Params,
			Trailing: "No such nick/channel",
		})
	}
	return nil
}

func CmdNick(s Server, u *User, msg *irc.Message) error {
	s.RenameUser(u, msg.Params[0])
	return nil
}
<commit_msg>Comments.<commit_after>package irckit

import (
	"errors"
	"fmt"
	"strings"

	"github.com/sorcix/irc"
)

// The error returned when an invalid command is issued.
var ErrUnknownCommand = errors.New("unknown command")

// Handler is a container for an irc.Message handler.
type Handler struct {
	// Command is the IRC command that Call handles.
	Command string
	// Handler is a function that takes the server, user who sent the message, and a message to perform some command.
	Call func(s Server, u *User, msg *irc.Message) error
	// MinParams is the minimum number of params required on the message.
	MinParams int
	// TODO: Add mode constraints?
}

// Commands is a registry for command handlers
type Commands map[string]Handler

// Add registers a Handler
func (cmds Commands) Add(h Handler) {
	cmds[h.Command] = h
}

// Run executes an Handler to the irc.Message's Command.
func (cmds Commands) Run(s Server, u *User, msg *irc.Message) error {
	cmd, ok := cmds[msg.Command]
	if !ok {
		return ErrUnknownCommand
	}
	if len(msg.Params) < cmd.MinParams {
		return u.Encode(&irc.Message{
			Prefix:  s.Prefix(),
			Command: irc.ERR_NEEDMOREPARAMS,
			Params:  []string{msg.Command},
		})
	}
	return cmd.Call(s, u, msg)
}

func DefaultCommands() Commands {
	cmds := Commands{}

	cmds.Add(Handler{Command: irc.PART, Call: CmdPart, MinParams: 1})
	cmds.Add(Handler{Command: irc.QUIT, Call: CmdQuit})
	cmds.Add(Handler{Command: irc.PING, Call: CmdPing})
	cmds.Add(Handler{Command: irc.JOIN, Call: CmdJoin, MinParams: 1})
	cmds.Add(Handler{Command: irc.MOTD, Call: CmdMotd})
	cmds.Add(Handler{Command: irc.NAMES, Call: CmdNames, MinParams: 1})
	cmds.Add(Handler{Command: irc.WHO, Call: CmdWho, MinParams: 1})
	cmds.Add(Handler{Command: irc.ISON, Call: CmdIson, MinParams: 1})
	cmds.Add(Handler{Command: irc.PRIVMSG, Call: CmdPrivMsg, MinParams: 1})
	cmds.Add(Handler{Command: irc.NICK, Call: CmdNick, MinParams: 1})

	return cmds
}

// CmdPart is a handler for the /PART command.
func CmdPart(s Server, u *User, msg *irc.Message) error {
	// TODO: Handle 0
	channels := strings.Split(msg.Params[0], ",")
	for _, chName := range channels {
		ch, exists := s.HasChannel(chName)
		if !exists {
			u.Encode(&irc.Message{
				Prefix:   s.Prefix(),
				Command:  irc.ERR_NOSUCHCHANNEL,
				Params:   []string{chName},
				Trailing: "No such channel",
			})
			continue
		}
		ch.Part(u, msg.Trailing)
	}
	return nil
}

// CmdQuit is a handler for the /QUIT command.
func CmdQuit(s Server, u *User, msg *irc.Message) error {
	u.Encode(&irc.Message{
		Prefix:   u.Prefix(),
		Command:  irc.QUIT,
		Trailing: msg.Trailing,
	})
	u.Encode(&irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.ERROR,
		Trailing: "You will be missed.",
	})
	s.Publish(&event{QuitEvent, s, nil, u, msg})
	return nil
}

// CmdPing is a handler for the /PING command.
func CmdPing(s Server, u *User, msg *irc.Message) error {
	return u.Encode(&irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.PONG,
		Params:   []string{s.Name()},
		Trailing: msg.Trailing,
	})
}

// CmdJoin is a handler for the /JOIN command.
func CmdJoin(s Server, u *User, msg *irc.Message) error {
	// TODO: Handle invite-only
	/*
		return u.Encode(&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.ERR_INVITEONLYCHAN,
			Trailing: "Cannot join channel (+i)",
		})
	*/
	channels := strings.Split(msg.Params[0], ",")
	for _, channel := range channels {
		// XXX: Handle no create permission.
		ch := s.Channel(channel)
		err := ch.Join(u)
		if err == nil {
			s.Publish(&event{JoinEvent, s, ch, u, msg})
		}
	}
	return nil
}

// CmdMotd is a handler for the /MOTD command.
func CmdMotd(s Server, u *User, _ *irc.Message) error {
	motd := s.Motd()
	r := make([]*irc.Message, 0, len(motd)+2)
	r = append(r, &irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.RPL_MOTDSTART,
		Params:   []string{u.Nick},
		Trailing: fmt.Sprintf("- %s Message of the Day -", s.Name()),
	})

	for _, line := range motd {
		r = append(r, &irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_MOTD,
			Params:   []string{u.Nick},
			Trailing: fmt.Sprintf("- %s", line),
		})
	}

	r = append(r, &irc.Message{
		Prefix:   s.Prefix(),
		Command:  irc.RPL_ENDOFMOTD,
		Params:   []string{u.Nick},
		Trailing: "End of /MOTD command.",
	})

	return u.Encode(r...)
}

// CmdNames is a handler for the /NAMES command.
func CmdNames(s Server, u *User, msg *irc.Message) error {
	// TODO: Handle multiple channels? Queries?
	channels := msg.Params

	// TODO: Support full list?
	r := []*irc.Message{}
	for _, channel := range channels {
		ch, exists := s.HasChannel(channel)
		if !exists {
			continue
		}
		// FIXME: This needs to be broken up into multiple messages to fit <510 chars
		msg := irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_NAMREPLY,
			Params:   []string{u.Nick, "=", channel},
			Trailing: strings.Join(ch.Names(), " "),
		}
		r = append(r, &msg)
	}
	endParams := []string{u.Nick}
	if len(channels) == 1 {
		endParams = append(endParams, channels[0])
	}
	r = append(r, &irc.Message{
		Prefix:   s.Prefix(),
		Params:   endParams,
		Command:  irc.RPL_ENDOFNAMES,
		Trailing: "End of /NAMES list.",
	})
	return u.Encode(r...)
}

// CmdWho is a handler for the /WHO command.
func CmdWho(s Server, u *User, msg *irc.Message) error {
	// TODO: Use opFilter
	//opFilter := len(msg.Params) >= 2 && msg.Params[1] == "o"
	mask := msg.Params[0]

	endMsg := &irc.Message{
		Prefix:   s.Prefix(),
		Params:   []string{u.Nick, mask},
		Command:  irc.RPL_ENDOFWHO,
		Trailing: "End of /WHO list.",
	}

	// TODO: Handle arbitrary masks, not just channels
	ch, exists := s.HasChannel(mask)
	if !exists {
		return u.Encode(endMsg)
	}

	r := make([]*irc.Message, 0, ch.Len()+1)
	for _, other := range ch.Users() {
		// <me> <channel> <user> <host> <server> <nick> [H/G]: 0 <real>
		r = append(r, &irc.Message{
			Prefix:   s.Prefix(),
			Params:   []string{u.Nick, mask, other.User, other.Host, "*", other.Nick, "H"},
			Command:  irc.RPL_WHOREPLY,
			Trailing: "0 " + other.Real,
		})
	}

	r = append(r, endMsg)
	return u.Encode(r...)
}

// CmdIson is a handler for the /ISON command.
func CmdIson(s Server, u *User, msg *irc.Message) error {
	nicks := msg.Params
	on := make([]string, 0, len(nicks))
	for _, nick := range nicks {
		if _, ok := s.HasUser(nick); ok {
			on = append(on, nick)
		}
	}

	return u.Encode(
		&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_ISON,
			Params:   []string{u.Nick},
			Trailing: strings.Join(on, " "),
		},
	)
}

// CmdPrivMsg is a handler for the /PRIVMSG command.
func CmdPrivMsg(s Server, u *User, msg *irc.Message) error {
	query := msg.Params[0]
	if toChan, exists := s.HasChannel(query); exists {
		toChan.Message(u, msg.Trailing)
		s.Publish(&event{ChanMsgEvent, s, toChan, u, msg})
	} else if toUser, exists := s.HasUser(query); exists {
		s.Publish(&event{UserMsgEvent, s, nil, u, msg})
		toUser.Encode(&irc.Message{
			Prefix:   u.Prefix(),
			Command:  irc.PRIVMSG,
			Params:   []string{toUser.Nick},
			Trailing: msg.Trailing,
		})
	} else {
		return u.Encode(&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.ERR_NOSUCHNICK,
			Params:   msg.Params,
			Trailing: "No such nick/channel",
		})
	}
	return nil
}

// CmdNick is a handler for the /NICK command.
func CmdNick(s Server, u *User, msg *irc.Message) error {
	s.RenameUser(u, msg.Params[0])
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/md5"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildslave/proto"
	pbs "github.com/brotherlogic/goserver/proto"
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	runner *Runner
	disk   diskChecker
	jobs   map[string]*pb.JobDetails
}

func (s *Server) monitor(job *pb.JobDetails) {
	for true {
		switch job.State {
		case pb.JobDetails_ACKNOWLEDGED:
			job.StartTime = 0
			job.State = pb.JobDetails_BUILDING
			s.runner.Checkout(job.GetSpec().Name)
			job.State = pb.JobDetails_BUILT
		case pb.JobDetails_BUILT:
			s.runner.Run(job)
			for job.StartTime == 0 {
				time.Sleep(waitTime)
			}
			job.State = pb.JobDetails_PENDING
		case pb.JobDetails_KILLING:
			s.runner.kill(job)
			if !isAlive(job.GetSpec()) {
				job.State = pb.JobDetails_DEAD
			}
		case pb.JobDetails_UPDATE_STARTING:
			s.runner.Update(job)
			job.State = pb.JobDetails_RUNNING
		case pb.JobDetails_PENDING:
			time.Sleep(time.Second * 10)
			if isAlive(job.GetSpec()) {
				job.State = pb.JobDetails_RUNNING
			} else {
				job.State = pb.JobDetails_DEAD
			}
		case pb.JobDetails_RUNNING:
			time.Sleep(waitTime)
			if !isAlive(job.GetSpec()) {
				job.State = pb.JobDetails_DEAD
			}
		case pb.JobDetails_DEAD:
			job.State = pb.JobDetails_ACKNOWLEDGED
		}
	}
}

func getHash(file string) (string, error) {
	env := os.Environ()
	home := ""
	for _, s := range env {
		if strings.HasPrefix(s, "HOME=") {
			home = s[5:]
		}
	}

	gpath := home + "/gobuild"

	f, err := os.Open(strings.Replace(file, "$GOPATH", gpath, 1))
	if err != nil {
		return "", err
	}
	defer f.Close()

	h := md5.New()
	if _, err := io.Copy(h, f); err != nil {
		return "", err
	}

	return string(h.Sum(nil)), nil
}

func getIP(name string, server string) (string, int) {
	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	entry := pbd.RegistryEntry{Name: name, Identifier: server}
	r, err := registry.Discover(context.Background(), &entry)

	if err != nil {
		return "", -1
	}

	return r.Ip, int(r.Port)
}

// updateState of the runner command
func isAlive(spec *pb.JobSpec) bool {
	elems := strings.Split(spec.Name, "/")
	dServer, dPort := getIP(elems[len(elems)-1], spec.Server)

	if dPort > 0 {
		dConn, err := grpc.Dial(dServer+":"+strconv.Itoa(dPort), grpc.WithInsecure())
		if err != nil {
			return false
		}
		defer dConn.Close()

		c := pbs.NewGoserverServiceClient(dConn)
		_, err = c.IsAlive(context.Background(), &pbs.Alive{})
		return err == nil
	}

	//Mark as false if we can't locate the job
	return false
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildSlaveServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Init builds the default runner framework
func Init() *Runner {
	r := &Runner{gopath: "goautobuild"}
	r.runner = runCommand
	go r.run()
	return r
}

func runCommand(c *runnerCommand) {
	if c.command == nil {
		return
	}

	env := os.Environ()
	home := ""
	for _, s := range env {
		if strings.HasPrefix(s, "HOME=") {
			home = s[5:]
		}
	}

	gpath := home + "/gobuild"
	c.command.Path = strings.Replace(c.command.Path, "$GOPATH", gpath, -1)
	for i := range c.command.Args {
		c.command.Args[i] = strings.Replace(c.command.Args[i], "$GOPATH", gpath, -1)
	}

	path := fmt.Sprintf("GOPATH=" + home + "/gobuild")
	found := false
	envl := os.Environ()
	for i, blah := range envl {
		if strings.HasPrefix(blah, "GOPATH") {
			envl[i] = path
			found = true
		}
	}
	if !found {
		envl = append(envl, path)
	}
	c.command.Env = envl

	out, _ := c.command.StdoutPipe()

	c.command.Start()

	if !c.background {
		str := ""

		if out != nil {
			buf := new(bytes.Buffer)
			buf.ReadFrom(out)
			str = buf.String()
		}

		c.command.Wait()
		c.output = str
		c.complete = true
	} else {
		c.details.StartTime = time.Now().Unix()
	}
}

func (diskChecker prodDiskChecker) diskUsage(path string) int64 {
	return diskUsage(path)
}

func (s *Server) rebuildLoop() {
	for true {
		time.Sleep(time.Minute)

		var rebuildList []*pb.JobDetails
		var hashList []string
		for _, job := range s.runner.backgroundTasks {
			if time.Since(job.started) > time.Hour {
				rebuildList = append(rebuildList, job.details)
				hashList = append(hashList, job.hash)
			}
		}

		for i := range rebuildList {
			s.runner.Rebuild(rebuildList[i], hashList[i])
		}
	}
}

func main() {
	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	s := Server{&goserver.GoServer{}, Init(), prodDiskChecker{}, make(map[string]*pb.JobDetails)}
	s.Register = s
	s.PrepServer()
	s.GoServer.Killme = false
	s.RegisterServingTask(s.rebuildLoop)
	s.RegisterServer("gobuildslave", false)
	s.Serve()
}
<commit_msg>Added atest for nil commands<commit_after>package main

import (
	"bytes"
	"crypto/md5"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildslave/proto"
	pbs "github.com/brotherlogic/goserver/proto"
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	runner *Runner
	disk   diskChecker
	jobs   map[string]*pb.JobDetails
}

func (s *Server) monitor(job *pb.JobDetails) {
	for true {
		switch job.State {
		case pb.JobDetails_ACKNOWLEDGED:
			job.StartTime = 0
			job.State = pb.JobDetails_BUILDING
			s.runner.Checkout(job.GetSpec().Name)
			job.State = pb.JobDetails_BUILT
		case pb.JobDetails_BUILT:
			s.runner.Run(job)
			for job.StartTime == 0 {
				time.Sleep(waitTime)
			}
			job.State = pb.JobDetails_PENDING
		case pb.JobDetails_KILLING:
			s.runner.kill(job)
			if !isAlive(job.GetSpec()) {
				job.State = pb.JobDetails_DEAD
			}
		case pb.JobDetails_UPDATE_STARTING:
			s.runner.Update(job)
			job.State = pb.JobDetails_RUNNING
		case pb.JobDetails_PENDING:
			time.Sleep(time.Second * 10)
			if isAlive(job.GetSpec()) {
				job.State = pb.JobDetails_RUNNING
			} else {
				job.State = pb.JobDetails_DEAD
			}
		case pb.JobDetails_RUNNING:
			time.Sleep(waitTime)
			if !isAlive(job.GetSpec()) {
				job.State = pb.JobDetails_DEAD
			}
		case pb.JobDetails_DEAD:
			job.State = pb.JobDetails_ACKNOWLEDGED
		}
	}
}

func getHash(file string) (string, error) {
	env := os.Environ()
	home := ""
	for _, s := range env {
		if strings.HasPrefix(s, "HOME=") {
			home = s[5:]
		}
	}

	gpath := home + "/gobuild"

	f, err := os.Open(strings.Replace(file, "$GOPATH", gpath, 1))
	if err != nil {
		return "", err
	}
	defer f.Close()

	h := md5.New()
	if _, err := io.Copy(h, f); err != nil {
		return "", err
	}

	return string(h.Sum(nil)), nil
}

func getIP(name string, server string) (string, int) {
	conn, _ := grpc.Dial("192.168.86.64:50055", grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	entry := pbd.RegistryEntry{Name: name, Identifier: server}
	r, err := registry.Discover(context.Background(), &entry)

	if err != nil {
		return "", -1
	}

	return r.Ip, int(r.Port)
}

// updateState of the runner command
func isAlive(spec *pb.JobSpec) bool {
	elems := strings.Split(spec.Name, "/")
	dServer, dPort := getIP(elems[len(elems)-1], spec.Server)

	if dPort > 0 {
		dConn, err := grpc.Dial(dServer+":"+strconv.Itoa(dPort), grpc.WithInsecure())
		if err != nil {
			return false
		}
		defer dConn.Close()

		c := pbs.NewGoserverServiceClient(dConn)
		_, err = c.IsAlive(context.Background(), &pbs.Alive{})
		return err == nil
	}

	//Mark as false if we can't locate the job
	return false
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildSlaveServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Init builds the default runner framework
func Init() *Runner {
	r := &Runner{gopath: "goautobuild"}
	r.runner = runCommand
	go r.run()
	return r
}

func runCommand(c *runnerCommand) {
	if c == nil || c.command == nil {
		return
	}

	env := os.Environ()
	home := ""
	for _, s := range env {
		if strings.HasPrefix(s, "HOME=") {
			home = s[5:]
		}
	}

	gpath := home + "/gobuild"
	c.command.Path = strings.Replace(c.command.Path, "$GOPATH", gpath, -1)
	for i := range c.command.Args {
		c.command.Args[i] = strings.Replace(c.command.Args[i], "$GOPATH", gpath, -1)
	}

	path := fmt.Sprintf("GOPATH=" + home + "/gobuild")
	found := false
	envl := os.Environ()
	for i, blah := range envl {
		if strings.HasPrefix(blah, "GOPATH") {
			envl[i] = path
			found = true
		}
	}
	if !found {
		envl = append(envl, path)
	}
	c.command.Env = envl

	out, _ := c.command.StdoutPipe()

	c.command.Start()

	if !c.background {
		str := ""

		if out != nil {
			buf := new(bytes.Buffer)
			buf.ReadFrom(out)
			str = buf.String()
		}

		c.command.Wait()
		c.output = str
		c.complete = true
	} else {
		c.details.StartTime = time.Now().Unix()
	}
}

func (diskChecker prodDiskChecker) diskUsage(path string) int64 {
	return diskUsage(path)
}

func (s *Server) rebuildLoop() {
	for true {
		time.Sleep(time.Minute)

		var rebuildList []*pb.JobDetails
		var hashList []string
		for _, job := range s.runner.backgroundTasks {
			if time.Since(job.started) > time.Hour {
				rebuildList = append(rebuildList, job.details)
				hashList = append(hashList, job.hash)
			}
		}

		for i := range rebuildList {
			s.runner.Rebuild(rebuildList[i], hashList[i])
		}
	}
}

func main() {
	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	s := Server{&goserver.GoServer{}, Init(), prodDiskChecker{}, make(map[string]*pb.JobDetails)}
	s.Register = s
	s.PrepServer()
	s.GoServer.Killme = false
	s.RegisterServingTask(s.rebuildLoop)
	s.RegisterServer("gobuildslave", false)
	s.Serve()
}
<|endoftext|>


<commit_before>package dual

import (
	"fmt"
	"math"
	"strings"
)

// A Complex represents a dual complex number as an ordered array of four
// float64 values.
type Complex [4]float64

var (
	symbC = [4]string{"", "i", "ε", "εi"}
)

// String returns the string representation of a Complex value. If z
// corresponds to the dual complex number a + bi + cε + diε, then the string is
// "(a+bi+cε+diε)", similar to complex128 values.
func (z *Complex) String() string {
	a := make([]string, 9)
	a[0] = "("
	a[1] = fmt.Sprintf("%g", z[0])
	i := 1
	for j := 2; j < 8; j = j + 2 {
		switch {
		case math.Signbit(z[i]):
			a[j] = fmt.Sprintf("%g", z[i])
		case math.IsInf(z[i], +1):
			a[j] = "+Inf"
		default:
			a[j] = fmt.Sprintf("+%g", z[i])
		}
		a[j+1] = symbC[i]
		i++
	}
	a[8] = ")"
	return strings.Join(a, "")
}

// Equals returns true if z and y are equal.
func (z *Complex) Equals(y *Complex) bool {
	for i := range z {
		if notEquals(z[i], y[i]) {
			return false
		}
	}
	return true
}

// Copy copies y onto z, and returns z.
func (z *Complex) Copy(y *Complex) *Complex {
	for i, v := range y {
		z[i] = v
	}
	return z
}

// NewComplex returns a pointer to a Complex value made from four given float64
// values.
func NewComplex(a, b, c, d float64) *Complex {
	z := new(Complex)
	z[0] = a
	z[1] = b
	z[2] = c
	z[3] = d
	return z
}

// IsComplexInf returns true if any of the components of z are infinite.
func (z *Complex) IsComplexInf() bool {
	for _, v := range z {
		if math.IsInf(v, 0) {
			return true
		}
	}
	return false
}

// ComplexInf returns a pointer to a dual complex infinity value.
func ComplexInf(a, b, c, d int) *Complex {
	z := new(Complex)
	z[0] = math.Inf(a)
	z[1] = math.Inf(b)
	z[2] = math.Inf(c)
	z[3] = math.Inf(d)
	return z
}

// IsComplexNaN returns true if any component of z is NaN and neither is an
// infinity.
func (z *Complex) IsComplexNaN() bool {
	for _, v := range z {
		if math.IsInf(v, 0) {
			return false
		}
	}
	for _, v := range z {
		if math.IsNaN(v) {
			return true
		}
	}
	return false
}

// ComplexNaN returns a pointer to a dual complex NaN value.
func ComplexNaN() *Complex {
	nan := math.NaN()
	return &Complex{nan, nan, nan, nan}
}

// Scal sets z equal to y scaled by a, and returns z.
func (z *Complex) Scal(y *Complex, a float64) *Complex {
	for i, v := range y {
		z[i] = a * v
	}
	return z
}

// Neg sets z equal to the negative of y, and returns z.
func (z *Complex) Neg(y *Complex) *Complex {
	return z.Scal(y, -1)
}

// DConj sets z equal to the dual conjugate of y, and returns z.
func (z *Complex) DConj(y *Complex) *Complex {
	z[0] = +y[0]
	z[1] = +y[1]
	z[2] = -y[2]
	z[3] = -y[3]
	return z
}

// Conj sets z equal to the complex conjugate of y, and returns z.
func (z *Complex) Conj(y *Complex) *Complex {
	z[0] = +y[0]
	z[1] = -y[1]
	z[2] = +y[2]
	z[3] = -y[3]
	return z
}

// Add sets z equal to the sum of x and y, and returns z.
func (z *Complex) Add(x, y *Complex) *Complex {
	for i, v := range x {
		z[i] = v + y[i]
	}
	return z
}

// Sub sets z equal to the difference of x and y, and returns z.
func (z *Complex) Sub(x, y *Complex) *Complex {
	for i, v := range x {
		z[i] = v - y[i]
	}
	return z
}

// Mul sets z equal to the product of x and y, and returns z.
//
// The basic rules are:
// 		ε * ε = 0
// 		i * i = -1
// 		εi * εi = 0
// 		ε * i = i * ε = εi
// 		εi * i = i * εi = -ε
// 		ε * εi = εi * ε = 0
func (z *Complex) Mul(x, y *Complex) *Complex {
	p := new(Complex).Copy(x)
	q := new(Complex).Copy(y)
	z[0] = (p[0] * q[0]) - (p[1] * q[1])
	z[1] = (p[0] * q[1]) + (p[1] * q[0])
	z[2] = (p[0] * q[2]) - (p[1] * q[3]) + (p[2] * q[0]) - (p[3] * q[1])
	z[3] = (p[0] * q[3]) + (p[1] * q[2]) + (p[2] * q[1]) + (p[3] * q[0])
	return z
}

// Quad returns the quadrance of z, a dual real value.
func (z *Complex) Quad() *Real {
	p := new(Complex).Mul(z, new(Complex).Conj(z))
	d := new(Real)
	d[0] = p[0]
	d[1] = p[2]
	return d
}

// DQuad returns the dual quadrance of z, a complex128 value.
func (z *Complex) DQuad() complex128 {
	p := new(Complex).Mul(z, new(Complex).DConj(z))
	return complex(p[0], p[1])
}
<commit_msg>Test changes to goimports<commit_after>package dual

import (
    "fmt"
    "math"
    "strings"
)

// A Complex represents a dual complex number as an ordered array of four
// float64 values.
type Complex [4]float64

var (
    symbC = [4]string{"", "i", "ε", "εi"}
)

// String returns the string representation of a Complex value. If z
// corresponds to the dual complex number a + bi + cε + diε, then the string is
// "(a+bi+cε+diε)", similar to complex128 values.
func (z *Complex) String() string {
    a := make([]string, 9)
    a[0] = "("
    a[1] = fmt.Sprintf("%g", z[0])
    i := 1
    for j := 2; j < 8; j = j + 2 {
        switch {
        case math.Signbit(z[i]):
            a[j] = fmt.Sprintf("%g", z[i])
        case math.IsInf(z[i], +1):
            a[j] = "+Inf"
        default:
            a[j] = fmt.Sprintf("+%g", z[i])
        }
        a[j+1] = symbC[i]
        i++
    }
    a[8] = ")"
    return strings.Join(a, "")
}

// Equals returns true if z and y are equal.
func (z *Complex) Equals(y *Complex) bool {
    for i := range z {
        if notEquals(z[i], y[i]) {
            return false
        }
    }
    return true
}

// Copy copies y onto z, and returns z.
func (z *Complex) Copy(y *Complex) *Complex {
    for i, v := range y {
        z[i] = v
    }
    return z
}

// NewComplex returns a pointer to a Complex value made from four given float64
// values.
func NewComplex(a, b, c, d float64) *Complex {
    z := new(Complex)
    z[0] = a
    z[1] = b
    z[2] = c
    z[3] = d
    return z
}

// IsComplexInf returns true if any of the components of z are infinite.
func (z *Complex) IsComplexInf() bool {
    for _, v := range z {
        if math.IsInf(v, 0) {
            return true
        }
    }
    return false
}

// ComplexInf returns a pointer to a dual complex infinity value.
func ComplexInf(a, b, c, d int) *Complex {
    z := new(Complex)
    z[0] = math.Inf(a)
    z[1] = math.Inf(b)
    z[2] = math.Inf(c)
    z[3] = math.Inf(d)
    return z
}

// IsComplexNaN returns true if any component of z is NaN and neither is an
// infinity.
func (z *Complex) IsComplexNaN() bool {
    for _, v := range z {
        if math.IsInf(v, 0) {
            return false
        }
    }
    for _, v := range z {
        if math.IsNaN(v) {
            return true
        }
    }
    return false
}

// ComplexNaN returns a pointer to a dual complex NaN value.
func ComplexNaN() *Complex {
    nan := math.NaN()
    return &Complex{nan, nan, nan, nan}
}

// Scal sets z equal to y scaled by a, and returns z.
func (z *Complex) Scal(y *Complex, a float64) *Complex {
    for i, v := range y {
        z[i] = a * v
    }
    return z
}

// Neg sets z equal to the negative of y, and returns z.
func (z *Complex) Neg(y *Complex) *Complex {
    return z.Scal(y, -1)
}

// DConj sets z equal to the dual conjugate of y, and returns z.
func (z *Complex) DConj(y *Complex) *Complex {
    z[0] = +y[0]
    z[1] = +y[1]
    z[2] = -y[2]
    z[3] = -y[3]
    return z
}

// Conj sets z equal to the complex conjugate of y, and returns z.
func (z *Complex) Conj(y *Complex) *Complex {
    z[0] = +y[0]
    z[1] = -y[1]
    z[2] = +y[2]
    z[3] = -y[3]
    return z
}

// Add sets z equal to the sum of x and y, and returns z.
func (z *Complex) Add(x, y *Complex) *Complex {
    for i, v := range x {
        z[i] = v + y[i]
    }
    return z
}

// Sub sets z equal to the difference of x and y, and returns z.
func (z *Complex) Sub(x, y *Complex) *Complex {
    for i, v := range x {
        z[i] = v - y[i]
    }
    return z
}

// Mul sets z equal to the product of x and y, and returns z.
//
// The basic rules are:
//      ε * ε = 0
//      i * i = -1
//      εi * εi = 0
//      ε * i = i * ε = εi
//      εi * i = i * εi = -ε
//      ε * εi = εi * ε = 0
func (z *Complex) Mul(x, y *Complex) *Complex {
    p := new(Complex).Copy(x)
    q := new(Complex).Copy(y)
    z[0] = (p[0] * q[0]) - (p[1] * q[1])
    z[1] = (p[0] * q[1]) + (p[1] * q[0])
    z[2] = (p[0] * q[2]) - (p[1] * q[3]) + (p[2] * q[0]) - (p[3] * q[1])
    z[3] = (p[0] * q[3]) + (p[1] * q[2]) + (p[2] * q[1]) + (p[3] * q[0])
    return z
}

// Quad returns the quadrance of z, a dual real value.
func (z *Complex) Quad() *Real {
    p := new(Complex).Mul(z, new(Complex).Conj(z))
    d := new(Real)
    d[0] = p[0]
    d[1] = p[2]
    return d
}

// DQuad returns the dual quadrance of z, a complex128 value.
func (z *Complex) DQuad() complex128 {
    p := new(Complex).Mul(z, new(Complex).DConj(z))
    return complex(p[0], p[1])
}
<|endoftext|>


<commit_before>package wf

import (
	"fmt"
	"reflect"
	"unsafe"

	"golang.org/x/sys/windows"
)

func toSublayer0(a *arena, sl *Sublayer) *fwpmSublayer0 {
	ret := (*fwpmSublayer0)(a.alloc(unsafe.Sizeof(fwpmSublayer0{})))
	*ret = fwpmSublayer0{
		SublayerKey: sl.Key,
		DisplayData: fwpmDisplayData0{
			Name:        toUint16(a, sl.Name),
			Description: toUint16(a, sl.Description),
		},
		ProviderData: fwpByteBlob{
			Size: uint32(len(sl.ProviderData)),
			Data: toBytes(a, sl.ProviderData),
		},
		Weight: sl.Weight,
	}
	if sl.Provider != nil {
		guid := (*windows.GUID)(a.alloc(unsafe.Sizeof(windows.GUID{})))
		*guid = *sl.Provider
	}

	return ret
}

func toProvider0(a *arena, p *Provider) *fwpmProvider0 {
	ret := (*fwpmProvider0)(a.alloc(unsafe.Sizeof(fwpmProvider0{})))
	*ret = fwpmProvider0{
		ProviderKey: p.Key,
		DisplayData: fwpmDisplayData0{
			Name:        toUint16(a, p.Name),
			Description: toUint16(a, p.Description),
		},
		ProviderData: fwpByteBlob{
			Size: uint32(len(p.Data)),
			Data: toBytes(a, p.Data),
		},
		ServiceName: toUint16(a, p.ServiceName),
	}
	if p.Persistent {
		ret.Flags = fwpmProviderFlagsPersistent
	}

	return ret
}

func toFilter0(a *arena, r *Rule, lt layerTypes) (*fwpmFilter0, error) {
	conds, err := toCondition0(a, r.Conditions, lt[r.Layer])
	if err != nil {
		return nil, err
	}

	typ, val, err := toValue0(a, r.Weight, reflect.TypeOf(uint64(0)))
	if err != nil {
		return nil, err
	}

	ret := (*fwpmFilter0)(a.alloc(unsafe.Sizeof(fwpmFilter0{})))
	*ret = fwpmFilter0{
		FilterKey: r.Key,
		DisplayData: fwpmDisplayData0{
			Name:        toUint16(a, r.Name),
			Description: toUint16(a, r.Description),
		},
		ProviderKey: r.Provider,
		ProviderData: fwpByteBlob{
			Size: uint32(len(r.ProviderData)), // todo: overflow?
			Data: toBytes(a, r.ProviderData),
		},
		LayerKey:    r.Layer,
		SublayerKey: r.Sublayer,
		Weight: fwpValue0{
			Type:  typ,
			Value: val,
		},
		NumFilterConditions: uint32(len(r.Conditions)), // TODO: overflow?
		FilterConditions:    conds,
		Action: fwpmAction0{
			Type: r.Action,
			GUID: r.Callout,
		},
	}

	if r.PermitIfMissing {
		ret.Flags |= fwpmFilterFlagsPermitIfCalloutUnregistered
	}
	if r.Persistent {
		ret.Flags |= fwpmFilterFlagsPersistent
	}
	if r.BootTime {
		ret.Flags |= fwpmFilterFlagsBootTime
	}

	return ret, nil
}

func toCondition0(a *arena, ms []*Match, ft fieldTypes) (array *fwpmFilterCondition0, err error) {
	array = (*fwpmFilterCondition0)(a.calloc(len(ms), unsafe.Sizeof(fwpmFilterCondition0{})))

	for i, m := range ms {
		typ, val, err := toValue0(a, m.Value, ft[m.Key])
		if err != nil {
			return nil, err
		}

		c := (*fwpmFilterCondition0)(unsafe.Pointer(uintptr(unsafe.Pointer(array)) + uintptr(i)*unsafe.Sizeof(fwpmFilterCondition0{})))
		*c = fwpmFilterCondition0{
			FieldKey:  m.Key,
			MatchType: m.Op,
			Value: fwpConditionValue0{
				Type:  typ,
				Value: val,
			},
		}
	}

	return array, nil
}

func toValue0(a *arena, v interface{}, ftype reflect.Type) (typ dataType, val uintptr, err error) {
	mapErr := func() (dataType, uintptr, error) {
		return 0, 0, fmt.Errorf("can't map type %T into condition type %v", v, ftype)
	}

	// TODO: exceptions go here

	typ = fieldTypeMapReverse[ftype]
	switch typ {
	case dataTypeUint8:
		u, ok := v.(uint8)
		if !ok {
			return mapErr()
		}
		*(*uint8)(unsafe.Pointer(&val)) = u
	case dataTypeUint16:
		u, ok := v.(uint16)
		if !ok {
			return mapErr()
		}
		*(*uint16)(unsafe.Pointer(&val)) = u
	case dataTypeUint32:
		u, ok := v.(uint32)
		if !ok {
			return mapErr()
		}
		*(*uint32)(unsafe.Pointer(&val)) = u
	case dataTypeUint64:
		p := a.alloc(unsafe.Sizeof(uint64(0)))

		u, ok := v.(uint64)
		if !ok {
			return mapErr()
		}
		*(*uint64)(p) = u
		val = uintptr(p)
	case dataTypeByteBlob:
		u, ok := v.([]byte)
		if !ok {
			return mapErr()
		}

		p := a.alloc(unsafe.Sizeof(fwpByteBlob{}))
		*(*fwpByteBlob)(p) = fwpByteBlob{
			Size: uint32(len(u)), // todo: overflow
			Data: toBytes(a, u),
		}
		val = uintptr(p)
	case dataTypeSID:
		u, ok := v.(*windows.SID)
		if !ok {
			return mapErr()
		}

		sidLen := windows.GetLengthSid(u)
		p := a.alloc(uintptr(sidLen))
		if err := windows.CopySid(sidLen, (*windows.SID)(p), u); err != nil {
			return 0, 0, err
		}
		val = uintptr(p)
	}

	// TODO: bitmapIndex
	// TODO: dataTypeArray16
	// TODO: dataTypeArray6
	// TODO: dataTypeSecurityDescriptor
	// TODO: dataTypeTokenInformation
	// TODO: dataTypeTokenAccessInformation
	// TODO: addr masks

	return typ, val, nil
}

func toUint16(a *arena, s string) *uint16 {
	n := windows.StringToUTF16(s)
	np := a.calloc(len(n), 2)
	for i := range n {
		*(*uint16)(unsafe.Pointer(uintptr(np) + uintptr(i))) = n[i]
	}
	return (*uint16)(np)
}

func toBytes(a *arena, bs []byte) *byte {
	if len(bs) == 0 {
		return nil
	}
	p := a.calloc(len(bs), 1)
	for i := range bs {
		*(*byte)(unsafe.Pointer(uintptr(p) + uintptr(i))) = bs[i]
	}
	return (*byte)(p)
}
<commit_msg>Switch to using constructed slices, in prep for 1.17 unsafe.Slice.<commit_after>package wf

import (
	"fmt"
	"reflect"
	"unsafe"

	"golang.org/x/sys/windows"
)

func toSublayer0(a *arena, sl *Sublayer) *fwpmSublayer0 {
	ret := (*fwpmSublayer0)(a.alloc(unsafe.Sizeof(fwpmSublayer0{})))
	*ret = fwpmSublayer0{
		SublayerKey: sl.Key,
		DisplayData: fwpmDisplayData0{
			Name:        toUint16(a, sl.Name),
			Description: toUint16(a, sl.Description),
		},
		ProviderKey: toGUID(a, sl.Provider),
		ProviderData: fwpByteBlob{
			Size: uint32(len(sl.ProviderData)),
			Data: toBytes(a, sl.ProviderData),
		},
		Weight: sl.Weight,
	}

	return ret
}

func toProvider0(a *arena, p *Provider) *fwpmProvider0 {
	ret := (*fwpmProvider0)(a.alloc(unsafe.Sizeof(fwpmProvider0{})))
	*ret = fwpmProvider0{
		ProviderKey: p.Key,
		DisplayData: fwpmDisplayData0{
			Name:        toUint16(a, p.Name),
			Description: toUint16(a, p.Description),
		},
		ProviderData: fwpByteBlob{
			Size: uint32(len(p.Data)),
			Data: toBytes(a, p.Data),
		},
		ServiceName: toUint16(a, p.ServiceName),
	}
	if p.Persistent {
		ret.Flags = fwpmProviderFlagsPersistent
	}

	return ret
}

func toFilter0(a *arena, r *Rule, lt layerTypes) (*fwpmFilter0, error) {
	conds, err := toCondition0(a, r.Conditions, lt[r.Layer])
	if err != nil {
		return nil, err
	}

	typ, val, err := toValue0(a, r.Weight, reflect.TypeOf(uint64(0)))
	if err != nil {
		return nil, err
	}

	ret := (*fwpmFilter0)(a.alloc(unsafe.Sizeof(fwpmFilter0{})))
	*ret = fwpmFilter0{
		FilterKey: r.Key,
		DisplayData: fwpmDisplayData0{
			Name:        toUint16(a, r.Name),
			Description: toUint16(a, r.Description),
		},
		ProviderKey: toGUID(a, r.Provider),
		ProviderData: fwpByteBlob{
			Size: uint32(len(r.ProviderData)), // todo: overflow?
			Data: toBytes(a, r.ProviderData),
		},
		LayerKey:    r.Layer,
		SublayerKey: r.Sublayer,
		Weight: fwpValue0{
			Type:  typ,
			Value: val,
		},
		NumFilterConditions: uint32(len(r.Conditions)), // TODO: overflow?
		FilterConditions:    conds,
		Action: fwpmAction0{
			Type: r.Action,
			GUID: r.Callout,
		},
	}

	if r.PermitIfMissing {
		ret.Flags |= fwpmFilterFlagsPermitIfCalloutUnregistered
	}
	if r.Persistent {
		ret.Flags |= fwpmFilterFlagsPersistent
	}
	if r.BootTime {
		ret.Flags |= fwpmFilterFlagsBootTime
	}

	return ret, nil
}

func toCondition0(a *arena, ms []*Match, ft fieldTypes) (array *fwpmFilterCondition0, err error) {
	array = (*fwpmFilterCondition0)(a.calloc(len(ms), unsafe.Sizeof(fwpmFilterCondition0{})))

	var conds []fwpmFilterCondition0
	sh := (*reflect.SliceHeader)(unsafe.Pointer(&conds))
	sh.Cap = len(ms)
	sh.Len = len(ms)
	sh.Data = uintptr(unsafe.Pointer(array))

	for i, m := range ms {
		c := &conds[i]

		typ, val, err := toValue0(a, m.Value, ft[m.Key])
		if err != nil {
			return nil, err
		}

		*c = fwpmFilterCondition0{
			FieldKey:  m.Key,
			MatchType: m.Op,
			Value: fwpConditionValue0{
				Type:  typ,
				Value: val,
			},
		}
	}

	return array, nil
}

func toValue0(a *arena, v interface{}, ftype reflect.Type) (typ dataType, val uintptr, err error) {
	mapErr := func() (dataType, uintptr, error) {
		return 0, 0, fmt.Errorf("can't map type %T into condition type %v", v, ftype)
	}

	// TODO: exceptions go here

	typ = fieldTypeMapReverse[ftype]
	switch typ {
	case dataTypeUint8:
		u, ok := v.(uint8)
		if !ok {
			return mapErr()
		}
		*(*uint8)(unsafe.Pointer(&val)) = u
	case dataTypeUint16:
		u, ok := v.(uint16)
		if !ok {
			return mapErr()
		}
		*(*uint16)(unsafe.Pointer(&val)) = u
	case dataTypeUint32:
		u, ok := v.(uint32)
		if !ok {
			return mapErr()
		}
		*(*uint32)(unsafe.Pointer(&val)) = u
	case dataTypeUint64:
		p := a.alloc(unsafe.Sizeof(uint64(0)))

		u, ok := v.(uint64)
		if !ok {
			return mapErr()
		}
		*(*uint64)(p) = u
		val = uintptr(p)
	case dataTypeByteBlob:
		u, ok := v.([]byte)
		if !ok {
			return mapErr()
		}

		p := a.alloc(unsafe.Sizeof(fwpByteBlob{}))
		*(*fwpByteBlob)(p) = fwpByteBlob{
			Size: uint32(len(u)), // todo: overflow
			Data: toBytes(a, u),
		}
		val = uintptr(p)
	case dataTypeSID:
		u, ok := v.(*windows.SID)
		if !ok {
			return mapErr()
		}

		sidLen := windows.GetLengthSid(u)
		p := a.alloc(uintptr(sidLen))
		if err := windows.CopySid(sidLen, (*windows.SID)(p), u); err != nil {
			return 0, 0, err
		}
		val = uintptr(p)
	}

	// TODO: bitmapIndex
	// TODO: dataTypeArray16
	// TODO: dataTypeArray6
	// TODO: dataTypeSecurityDescriptor
	// TODO: dataTypeTokenInformation
	// TODO: dataTypeTokenAccessInformation
	// TODO: addr masks

	return typ, val, nil
}

func toUint16(a *arena, s string) *uint16 {
	if len(s) == 0 {
		return nil
	}

	n := windows.StringToUTF16(s)
	ret := a.calloc(len(n), 2)

	var sl []uint16
	sh := (*reflect.SliceHeader)(unsafe.Pointer(&sl))
	sh.Cap = len(s)
	sh.Len = len(s)
	sh.Data = uintptr(ret)

	copy(sl, n)
	return (*uint16)(ret)
}

func toBytes(a *arena, bs []byte) *byte {
	if len(bs) == 0 {
		return nil
	}

	ret := a.calloc(len(bs), 1)

	var sl []byte
	sh := (*reflect.SliceHeader)(unsafe.Pointer(&sl))
	sh.Cap = len(bs)
	sh.Len = len(bs)
	sh.Data = uintptr(ret)

	copy(sl, bs)
	return (*byte)(ret)
}

func toGUID(a *arena, guid *windows.GUID) *windows.GUID {
	if guid == nil {
		return nil
	}
	ret := (*windows.GUID)(a.alloc(unsafe.Sizeof(windows.GUID{})))
	*ret = *guid
	return ret
}
<|endoftext|>


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

package dns

// Holds a bunch of helper functions for dealing with labels.

// SplitDomainName splits a name string into it's labels.
// www.miek.nl. returns []string{"www", "miek", "nl"}
// The root label (.) returns nil.
func SplitDomainName(s string) (labels []string) {
	if len(s) == 0 {
		return nil
	}
	fqdnEnd := 0 // offset of the final '.' or the length of the name
	idx := Split(s)
	begin := 0
	if s[len(s)-1] == '.' {
		fqdnEnd = len(s) - 1
	} else {
		fqdnEnd = len(s)
	}

	switch len(idx) {
	case 0:
		return nil
	case 1:
		// no-op
	default:
		end := 0
		for i := 1; i < len(idx); i++ {
			end = idx[i]
			labels = append(labels, s[begin:end-1])
			begin = end
		}
	}

	labels = append(labels, s[begin:fqdnEnd])
	return labels
}

// CompareDomainName compares the names s1 and s2 and
// returns how many labels they have in common starting from the *right*.
// The comparison stops at the first inequality. The names are not downcased
// before the comparison.
//
// www.miek.nl. and miek.nl. have two labels in common: miek and nl
// www.miek.nl. and www.bla.nl. have one label in common: nl
func CompareDomainName(s1, s2 string) (n int) {
	s1 = Fqdn(s1)
	s2 = Fqdn(s2)
	l1 := Split(s1)
	l2 := Split(s2)

	// the first check: root label
	if l1 == nil || l2 == nil {
		return
	}

	j1 := len(l1) - 1 // end
	i1 := len(l1) - 2 // start
	j2 := len(l2) - 1
	i2 := len(l2) - 2
	// the second check can be done here: last/only label
	// before we fall through into the for-loop below
	if s1[l1[j1]:] == s2[l2[j2]:] {
		n++
	} else {
		return
	}
	for {
		if i1 < 0 || i2 < 0 {
			break
		}
		if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] {
			n++
		} else {
			break
		}
		j1--
		i1--
		j2--
		i2--
	}
	return
}

// CountLabel counts the the number of labels in the string s.
func CountLabel(s string) (labels int) {
	if s == "." {
		return
	}
	off := 0
	end := false
	for {
		off, end = NextLabel(s, off)
		labels++
		if end {
			return
		}
	}
	panic("dns: not reached")
}

// Split splits a name s into its label indexes.
// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
// The root name (.) returns nil.
func Split(s string) []int {
	if s == "." {
		return nil
	}
	idx := []int{0}
	off := 0
	end := false

	for {
		off, end = NextLabel(s, off)
		if end {
			return idx
		}
		idx = append(idx, off)
	}
	panic("dns: not reached")
}

// NextLabel returns the index of the start of the next label in the
// string s starting at offset.
// The bool end is true when the end of the string has been reached.
func NextLabel(s string, offset int) (i int, end bool) {
	quote := false
	for i = offset; i < len(s)-1; i++ {
		switch s[i] {
		case '\\':
			quote = !quote
		default:
			quote = false
		case '.':
			if quote {
				quote = !quote
				continue
			}
			return i + 1, false
		}
	}
	return i + 1, true
}

// PrevLabel returns the index of the label when starting from the right and
// jumping n labels to the left.
// The bool start is true when the start of the string has been overshot.
func PrevLabel(s string, n int) (i int, start bool) {
	if n == 0 {
		return len(s), false
	}
	lab := Split(s)
	if lab == nil {
		return 0, true
	}
	if n > len(lab) {
		return 0, true
	}
	return lab[len(lab)-n], false
}
<commit_msg>Overallocate label index buffer<commit_after>// Copyright 2011 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dns

// Holds a bunch of helper functions for dealing with labels.

// SplitDomainName splits a name string into it's labels.
// www.miek.nl. returns []string{"www", "miek", "nl"}
// The root label (.) returns nil.
func SplitDomainName(s string) (labels []string) {
	if len(s) == 0 {
		return nil
	}
	fqdnEnd := 0 // offset of the final '.' or the length of the name
	idx := Split(s)
	begin := 0
	if s[len(s)-1] == '.' {
		fqdnEnd = len(s) - 1
	} else {
		fqdnEnd = len(s)
	}

	switch len(idx) {
	case 0:
		return nil
	case 1:
		// no-op
	default:
		end := 0
		for i := 1; i < len(idx); i++ {
			end = idx[i]
			labels = append(labels, s[begin:end-1])
			begin = end
		}
	}

	labels = append(labels, s[begin:fqdnEnd])
	return labels
}

// CompareDomainName compares the names s1 and s2 and
// returns how many labels they have in common starting from the *right*.
// The comparison stops at the first inequality. The names are not downcased
// before the comparison.
//
// www.miek.nl. and miek.nl. have two labels in common: miek and nl
// www.miek.nl. and www.bla.nl. have one label in common: nl
func CompareDomainName(s1, s2 string) (n int) {
	s1 = Fqdn(s1)
	s2 = Fqdn(s2)
	l1 := Split(s1)
	l2 := Split(s2)

	// the first check: root label
	if l1 == nil || l2 == nil {
		return
	}

	j1 := len(l1) - 1 // end
	i1 := len(l1) - 2 // start
	j2 := len(l2) - 1
	i2 := len(l2) - 2
	// the second check can be done here: last/only label
	// before we fall through into the for-loop below
	if s1[l1[j1]:] == s2[l2[j2]:] {
		n++
	} else {
		return
	}
	for {
		if i1 < 0 || i2 < 0 {
			break
		}
		if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] {
			n++
		} else {
			break
		}
		j1--
		i1--
		j2--
		i2--
	}
	return
}

// CountLabel counts the the number of labels in the string s.
func CountLabel(s string) (labels int) {
	if s == "." {
		return
	}
	off := 0
	end := false
	for {
		off, end = NextLabel(s, off)
		labels++
		if end {
			return
		}
	}
	panic("dns: not reached")
}

// Split splits a name s into its label indexes.
// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
// The root name (.) returns nil.
func Split(s string) []int {
	if s == "." {
		return nil
	}
	idx := make([]int, 1, 3)
	off := 0
	end := false

	for {
		off, end = NextLabel(s, off)
		if end {
			return idx
		}
		idx = append(idx, off)
	}
	panic("dns: not reached")
}

// NextLabel returns the index of the start of the next label in the
// string s starting at offset.
// The bool end is true when the end of the string has been reached.
func NextLabel(s string, offset int) (i int, end bool) {
	quote := false
	for i = offset; i < len(s)-1; i++ {
		switch s[i] {
		case '\\':
			quote = !quote
		default:
			quote = false
		case '.':
			if quote {
				quote = !quote
				continue
			}
			return i + 1, false
		}
	}
	return i + 1, true
}

// PrevLabel returns the index of the label when starting from the right and
// jumping n labels to the left.
// The bool start is true when the start of the string has been overshot.
func PrevLabel(s string, n int) (i int, start bool) {
	if n == 0 {
		return len(s), false
	}
	lab := Split(s)
	if lab == nil {
		return 0, true
	}
	if n > len(lab) {
		return 0, true
	}
	return lab[len(lab)-n], false
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"time"

	"github.com/buildkite/buildkite-metrics/backend"
	"github.com/buildkite/buildkite-metrics/collector"
	"github.com/buildkite/buildkite-metrics/metrics"
	"github.com/buildkite/go-buildkite/buildkite"
	"github.com/eawsy/aws-lambda-go/service/lambda/runtime"
)

func handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) {
	org := os.Getenv("BUILDKITE_ORG")
	token := os.Getenv("BUILDKITE_TOKEN")
	backendOpt := os.Getenv("BUILDKITE_BACKEND")
	queue := os.Getenv("BUILDKITE_QUEUE")
	quiet := os.Getenv("BUILDKITE_QUIET")

	if quiet == "1" || quiet == "false" {
		log.SetOutput(ioutil.Discard)
	}

	config, err := buildkite.NewTokenConfig(token, false)
	if err != nil {
		return nil, err
	}

	client := buildkite.NewClient(config.Client())
	t := time.Now()

	client.UserAgent = fmt.Sprintf(
		"%s buildkite-metrics/%s buildkite-metrics-lambda queue=%q",
		client.UserAgent, metrics.Version, queue,
	)

	col := collector.New(client, collector.Opts{
		OrgSlug: org,
	})

	if queue != "" {
		col.Queue = queue
	}

	var bk backend.Backend
	if backendOpt == "statsd" {
		bk, err = backend.NewStatsDBackend(os.Getenv("STATSD_HOST"), strings.ToLower(os.Getenv("STATSD_TAGS")) == "true")
		if err != nil {
			return nil, err
		}
	} else {
		bk = &backend.CloudWatchBackend{}
	}

	res, err := col.Collect()
	if err != nil {
		return nil, err
	}

	res.Dump()

	err = bk.Collect(res)
	if err != nil {
		return nil, err
	}

	log.Printf("Finished in %s", time.Now().Sub(t))
	return "", nil
}

func init() {
	runtime.HandleFunc(handle)
}
<commit_msg>Fix reference to metrics package<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"time"

	"github.com/buildkite/buildkite-metrics/backend"
	"github.com/buildkite/buildkite-metrics/collector"
	"github.com/buildkite/buildkite-metrics/version"
	"github.com/buildkite/go-buildkite/buildkite"
	"github.com/eawsy/aws-lambda-go/service/lambda/runtime"
)

func handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) {
	org := os.Getenv("BUILDKITE_ORG")
	token := os.Getenv("BUILDKITE_TOKEN")
	backendOpt := os.Getenv("BUILDKITE_BACKEND")
	queue := os.Getenv("BUILDKITE_QUEUE")
	quiet := os.Getenv("BUILDKITE_QUIET")

	if quiet == "1" || quiet == "false" {
		log.SetOutput(ioutil.Discard)
	}

	config, err := buildkite.NewTokenConfig(token, false)
	if err != nil {
		return nil, err
	}

	client := buildkite.NewClient(config.Client())
	t := time.Now()

	client.UserAgent = fmt.Sprintf(
		"%s buildkite-metrics/%s buildkite-metrics-lambda queue=%q",
		client.UserAgent, version.Version, queue,
	)

	col := collector.New(client, collector.Opts{
		OrgSlug: org,
	})

	if queue != "" {
		col.Queue = queue
	}

	var bk backend.Backend
	if backendOpt == "statsd" {
		bk, err = backend.NewStatsDBackend(os.Getenv("STATSD_HOST"), strings.ToLower(os.Getenv("STATSD_TAGS")) == "true")
		if err != nil {
			return nil, err
		}
	} else {
		bk = &backend.CloudWatchBackend{}
	}

	res, err := col.Collect()
	if err != nil {
		return nil, err
	}

	res.Dump()

	err = bk.Collect(res)
	if err != nil {
		return nil, err
	}

	log.Printf("Finished in %s", time.Now().Sub(t))
	return "", nil
}

func init() {
	runtime.HandleFunc(handle)
}
<|endoftext|>


<commit_before>// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
	"fmt"
	"os"
	"strings"

	"github.com/openfaas/faas-cli/proxy"
	"github.com/openfaas/faas-cli/stack"

	"github.com/spf13/cobra"
)

func init() {
	describeCmd.Flags().StringVar(&functionName, "name", "", "Name of the function")
	describeCmd.Flags().StringVarP(&gateway, "gateway", "g", defaultGateway, "Gateway URL starting with http(s)://")
	describeCmd.Flags().BoolVar(&tlsInsecure, "tls-no-verify", false, "Disable TLS validation")
	faasCmd.AddCommand(describeCmd)
}

var describeCmd = &cobra.Command{
	Use:   "describe FUNCTION_NAME [--gateway GATEWAY_URL]",
	Short: "Describe an OpenFaaS function",
	Long:  `Display details of an OpenFaaS function`,
	Example: `faas-cli describe figlet
faas-cli describe env --gateway http://127.0.0.1:8080
faas-cli describe echo -g http://127.0.0.1.8080`,
	PreRunE: preRunDescribe,
	RunE:    runDescribe,
}

func preRunDescribe(cmd *cobra.Command, args []string) error {
	return nil
}

func runDescribe(cmd *cobra.Command, args []string) error {
	if len(args) < 1 {
		return fmt.Errorf("please provide a name for the function")
	}
	var yamlGateway string
	var services stack.Services
	functionName = args[0]

	if len(yamlFile) > 0 {
		parsedServices, err := stack.ParseYAMLFile(yamlFile, regex, filter)
		if err != nil {
			return err
		}

		if parsedServices != nil {
			services = *parsedServices
			yamlGateway = services.Provider.GatewayURL
		}
	}
	gatewayAddress := getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv(openFaaSURLEnvironment))

	function, err := proxy.GetFunctionInfo(gatewayAddress, functionName, tlsInsecure)
	if err != nil {
		return err
	}

	var status string
	if function.AvailableReplicas > 0 {
		status = "Ready"
	} else {
		status = "Not Ready"
	}

	fmt.Printf("%s:\t\t\t%s\n", "Name", function.Name)
	fmt.Printf("%s:\t\t\t%s\n", "Status", status)
	fmt.Printf("%s:\t\t%d\n", "Replicas", function.Replicas)
	fmt.Printf("%s:\t%d\n", "Available replicas", function.AvailableReplicas)
	fmt.Printf("%s:\t\t%v\n", "Invocations", function.InvocationCount)
	fmt.Printf("%s:\t\t\t%s\n", "Image", function.Image)
	fmt.Printf("%s:\t%s\n", "Function process", function.EnvProcess)
	fmt.Printf("%s:\t\t\t%s\n", "URL", getFunctionURL(gatewayAddress, functionName))
	fmt.Printf("%s:\t\t%s\n", "Async URL", getFunctionAsyncURL(gatewayAddress, functionName))

	return nil
}

func getFunctionURL(gateway string, functionName string) string {
	gateway = strings.TrimRight(gateway, "/")
	return gateway + "/function/" + functionName
}

func getFunctionAsyncURL(gateway string, functionName string) string {
	gateway = strings.TrimRight(gateway, "/")
	return gateway + "/async-function/" + functionName
}
<commit_msg>Use /system/functions endpoint for invocation count value<commit_after>// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
	"fmt"
	"os"
	"strings"

	"github.com/openfaas/faas-cli/proxy"
	"github.com/openfaas/faas-cli/stack"

	"github.com/spf13/cobra"
)

func init() {
	describeCmd.Flags().StringVar(&functionName, "name", "", "Name of the function")
	describeCmd.Flags().StringVarP(&gateway, "gateway", "g", defaultGateway, "Gateway URL starting with http(s)://")
	describeCmd.Flags().BoolVar(&tlsInsecure, "tls-no-verify", false, "Disable TLS validation")
	faasCmd.AddCommand(describeCmd)
}

var describeCmd = &cobra.Command{
	Use:   "describe FUNCTION_NAME [--gateway GATEWAY_URL]",
	Short: "Describe an OpenFaaS function",
	Long:  `Display details of an OpenFaaS function`,
	Example: `faas-cli describe figlet
faas-cli describe env --gateway http://127.0.0.1:8080
faas-cli describe echo -g http://127.0.0.1.8080`,
	PreRunE: preRunDescribe,
	RunE:    runDescribe,
}

func preRunDescribe(cmd *cobra.Command, args []string) error {
	return nil
}

func runDescribe(cmd *cobra.Command, args []string) error {
	if len(args) < 1 {
		return fmt.Errorf("please provide a name for the function")
	}
	var yamlGateway string
	var services stack.Services
	functionName = args[0]

	if len(yamlFile) > 0 {
		parsedServices, err := stack.ParseYAMLFile(yamlFile, regex, filter)
		if err != nil {
			return err
		}

		if parsedServices != nil {
			services = *parsedServices
			yamlGateway = services.Provider.GatewayURL
		}
	}
	gatewayAddress := getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv(openFaaSURLEnvironment))

	function, err := proxy.GetFunctionInfo(gatewayAddress, functionName, tlsInsecure)
	if err != nil {
		return err
	}

	//To get correct value for invocation count from /system/functions endpoint
	functionList, err := proxy.ListFunctions(gatewayAddress, tlsInsecure)
	if err != nil {
		return err
	}

	var invocationCount float64
	for _, fn := range functionList {
		if fn.Name == function.Name {
			invocationCount = fn.InvocationCount
		}
	}

	var status string
	if function.AvailableReplicas > 0 {
		status = "Ready"
	} else {
		status = "Not Ready"
	}

	fmt.Printf("%s:\t\t\t%s\n", "Name", function.Name)
	fmt.Printf("%s:\t\t\t%s\n", "Status", status)
	fmt.Printf("%s:\t\t%d\n", "Replicas", function.Replicas)
	fmt.Printf("%s:\t%d\n", "Available replicas", function.AvailableReplicas)
	fmt.Printf("%s:\t\t%v\n", "Invocations", invocationCount)
	fmt.Printf("%s:\t\t\t%s\n", "Image", function.Image)
	fmt.Printf("%s:\t%s\n", "Function process", function.EnvProcess)
	fmt.Printf("%s:\t\t\t%s\n", "URL", getFunctionURL(gatewayAddress, functionName))
	fmt.Printf("%s:\t\t%s\n", "Async URL", getFunctionAsyncURL(gatewayAddress, functionName))

	return nil
}

func getFunctionURL(gateway string, functionName string) string {
	gateway = strings.TrimRight(gateway, "/")
	return gateway + "/function/" + functionName
}

func getFunctionAsyncURL(gateway string, functionName string) string {
	gateway = strings.TrimRight(gateway, "/")
	return gateway + "/async-function/" + functionName
}
<|endoftext|>


<commit_before>package mpb_test

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"testing"
	"time"

	"github.com/vbauerster/mpb"
)

func TestPrependName(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)
	name := "TestBar"
	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependName(name, 0, 0)
	for i := 0; i < 100; i++ {
		bar.Incr(1)
	}

	p.Stop()

	want := name + "["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependNameDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)
	name := "TestBar"
	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependName(name, len(name)+1, mpb.DidentRight)
	for i := 0; i < 100; i++ {
		bar.Incr(1)
	}

	p.Stop()

	want := name + " ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependCounters(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	reader := strings.NewReader(content)

	total := int64(len(content))
	bar := p.AddBar(total).TrimLeftSpace().TrimRightSpace().
		PrependCounters("%3s / %3s", mpb.UnitBytes, 0, 0)
	preader := bar.ProxyReader(reader)

	_, err := io.Copy(ioutil.Discard, preader)
	if err != nil {
		t.Errorf("Error copying from reader: %+v\n", err)
	}

	p.Stop()

	barOut := buf.String()
	want := fmt.Sprintf("%[1]db / %[1]db[", total)
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependCountersDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	reader := strings.NewReader(content)

	total := int64(len(content))
	bar := p.AddBar(total).TrimLeftSpace().TrimRightSpace().
		PrependCounters("%3s / %3s", mpb.UnitBytes, 12, mpb.DidentRight)
	preader := bar.ProxyReader(reader)

	_, err := io.Copy(ioutil.Discard, preader)
	if err != nil {
		t.Errorf("Error copying from reader: %+v\n", err)
	}

	p.Stop()

	barOut := buf.String()
	want := fmt.Sprintf("%[1]db / %[1]db [", total)
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendPercentage(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendPercentage(6, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "] 100 %"
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendPercentageDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendPercentage(6, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "]100 % "
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependPercentage(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependPercentage(6, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := " 100 %["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependPercentageDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependPercentage(6, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "100 % ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependElapsed(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependElapsed(0, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "1s["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependElapsedDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependElapsed(3, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "1s ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendElapsed(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendElapsed(0, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "]1s"
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendElapsedDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendElapsed(3, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "]1s "
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}
<commit_msg>TestPrependETA<commit_after>package mpb_test

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"testing"
	"time"

	"github.com/vbauerster/mpb"
)

func TestPrependName(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)
	name := "TestBar"
	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependName(name, 0, 0)
	for i := 0; i < 100; i++ {
		bar.Incr(1)
	}

	p.Stop()

	want := name + "["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependNameDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)
	name := "TestBar"
	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependName(name, len(name)+1, mpb.DidentRight)
	for i := 0; i < 100; i++ {
		bar.Incr(1)
	}

	p.Stop()

	want := name + " ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependCounters(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	reader := strings.NewReader(content)

	total := int64(len(content))
	bar := p.AddBar(total).TrimLeftSpace().TrimRightSpace().
		PrependCounters("%3s / %3s", mpb.UnitBytes, 0, 0)
	preader := bar.ProxyReader(reader)

	_, err := io.Copy(ioutil.Discard, preader)
	if err != nil {
		t.Errorf("Error copying from reader: %+v\n", err)
	}

	p.Stop()

	barOut := buf.String()
	want := fmt.Sprintf("%[1]db / %[1]db[", total)
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependCountersDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	reader := strings.NewReader(content)

	total := int64(len(content))
	bar := p.AddBar(total).TrimLeftSpace().TrimRightSpace().
		PrependCounters("%3s / %3s", mpb.UnitBytes, 12, mpb.DidentRight)
	preader := bar.ProxyReader(reader)

	_, err := io.Copy(ioutil.Discard, preader)
	if err != nil {
		t.Errorf("Error copying from reader: %+v\n", err)
	}

	p.Stop()

	barOut := buf.String()
	want := fmt.Sprintf("%[1]db / %[1]db [", total)
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendPercentage(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendPercentage(6, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "] 100 %"
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendPercentageDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendPercentage(6, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "]100 % "
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependPercentage(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependPercentage(6, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := " 100 %["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependPercentageDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependPercentage(6, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "100 % ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependElapsed(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependElapsed(0, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "1s["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependElapsedDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependElapsed(3, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "1s ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendElapsed(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendElapsed(0, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "]1s"
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestAppendElapsedDindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		AppendElapsed(3, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "]1s "
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependETA(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependETA(0, 0)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "0s["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}

func TestPrependETADindentRight(t *testing.T) {
	var buf bytes.Buffer
	p := mpb.New().SetOut(&buf)

	bar := p.AddBar(100).TrimLeftSpace().TrimRightSpace().
		PrependETA(3, mpb.DidentRight)

	for i := 0; i < 100; i++ {
		time.Sleep(10 * time.Millisecond)
		bar.Incr(1)
	}

	p.Stop()

	want := "0s ["
	barOut := buf.String()
	if !strings.Contains(barOut, want) {
		t.Errorf("%q not found in bar: %s\n", want, barOut)
	}
}
<|endoftext|>


<commit_before>package evar

import (
	"strings"

	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/commands/steps"
	"github.com/nanobox-io/nanobox/helpers"
	"github.com/nanobox-io/nanobox/models"
	app_evar "github.com/nanobox-io/nanobox/processors/app/evar"
	production_evar "github.com/nanobox-io/nanobox/processors/evar"
	"github.com/nanobox-io/nanobox/util/config"
	"github.com/nanobox-io/nanobox/util/display"
)

// AddCmd ...
var AddCmd = &cobra.Command{
	Use:   "add",
	Short: "Adds environment variable(s)",
	Long:  ``,
	// PreRun: steps.Run("login"),
	Run: addFn,
}

// addFn ...
func addFn(ccmd *cobra.Command, args []string) {

	// parse the evars excluding the context
	env, _ := models.FindEnvByID(config.EnvID())
	args, location, name := helpers.Endpoint(env, args, 0)
	evars := parseEvars(args)

	switch location {
	case "local":
		app, _ := models.FindAppBySlug(config.EnvID(), name)
		display.CommandErr(app_evar.Add(env, app, evars))
	case "production":
		steps.Run("login")(ccmd, args)

		production_evar.Add(env, name, evars)
	}
}

func parseEvars(args []string) map[string]string {
	evars := map[string]string{}

	for _, arg := range args {
		// define a function that will allow us to
		// split on ',' or ' '
		f := func(c rune) bool {
			return c == ','
		}

		for _, pair := range strings.FieldsFunc(arg, f) {
			// define a field split that llows us to split on
			// ':' or '='
			parts := strings.FieldsFunc(pair, func(c rune) bool {
				return c == '='
			})
			if len(parts) == 2 {

				evars[strings.ToUpper(parts[0])] = parts[1]
			}
		}
	}

	return evars
}
<commit_msg>adding evars with bad options will report errors fixes #338<commit_after>package evar

import (
	"strings"

	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/commands/steps"
	"github.com/nanobox-io/nanobox/helpers"
	"github.com/nanobox-io/nanobox/models"
	app_evar "github.com/nanobox-io/nanobox/processors/app/evar"
	production_evar "github.com/nanobox-io/nanobox/processors/evar"
	"github.com/nanobox-io/nanobox/util/config"
	"github.com/nanobox-io/nanobox/util/display"
)

// AddCmd ...
var AddCmd = &cobra.Command{
	Use:   "add",
	Short: "Adds environment variable(s)",
	Long:  ``,
	// PreRun: steps.Run("login"),
	Run: addFn,
}

// addFn ...
func addFn(ccmd *cobra.Command, args []string) {

	// parse the evars excluding the context
	env, _ := models.FindEnvByID(config.EnvID())
	args, location, name := helpers.Endpoint(env, args, 0)
	evars := parseEvars(args)

	switch location {
	case "local":
		app, _ := models.FindAppBySlug(config.EnvID(), name)
		display.CommandErr(app_evar.Add(env, app, evars))
	case "production":
		steps.Run("login")(ccmd, args)

		production_evar.Add(env, name, evars)
	}
}

func parseEvars(args []string) map[string]string {
	evars := map[string]string{}

	for _, arg := range args {
		// define a function that will allow us to
		// split on ',' or ' '
		f := func(c rune) bool {
			return c == ','
		}

		for _, pair := range strings.FieldsFunc(arg, f) {
			// define a field split that llows us to split on
			// ':' or '='
			parts := strings.FieldsFunc(pair, func(c rune) bool {
				return c == '='
			})
			if len(parts) == 2 {

				evars[strings.ToUpper(parts[0])] = parts[1]
			} else {
				fmt.Printf("invalid field option (%s)\n", pair)
			}
		}
	}

	return evars
}
<|endoftext|>