<commit_before>package pop

import (
	"fmt"
	"os"
)

func CreateDB(c *Connection) error {
	var err error
	deets := c.Dialect.Details()
	if deets.Database != "" {
		if Debug {
			fmt.Printf("[POP] Create %s (%s)\n", deets.Database, c.URL())
		}
		err = c.Dialect.CreateDB()
		if err != nil {
			fmt.Fprint(os.Stderr, err)
		}
	}
	return err
}

func DropDB(c *Connection) error {
	var err error
	deets := c.Dialect.Details()
	if deets.Database != "" {
		if Debug {
			fmt.Printf("[POP] Drop %s (%s)\n", deets.Database, c.URL())
		}
		err = c.Dialect.DropDB()
		if err != nil {
			fmt.Fprint(os.Stderr, err)
		}
	}
	return err
}
<commit_msg>always print details of drop/create<commit_after>package pop

import (
	"fmt"
	"os"
)

func CreateDB(c *Connection) error {
	var err error
	deets := c.Dialect.Details()
	if deets.Database != "" {
		fmt.Printf("[POP] Create %s (%s)\n", deets.Database, c.URL())
		err = c.Dialect.CreateDB()
		if err != nil {
			fmt.Fprint(os.Stderr, err)
		}
	}
	return err
}

func DropDB(c *Connection) error {
	var err error
	deets := c.Dialect.Details()
	if deets.Database != "" {
		fmt.Printf("[POP] Drop %s (%s)\n", deets.Database, c.URL())
		err = c.Dialect.DropDB()
		if err != nil {
			fmt.Fprint(os.Stderr, err)
		}
	}
	return err
}
<|endoftext|>


<commit_before>// Copyright (c) Liam Stanley <me@liamstanley.io>. All rights reserved. Use
// of this source code is governed by the MIT license that can be found in
// the LICENSE file.

package girc

import (
	"errors"
	"fmt"
)

// Commands holds a large list of useful methods to interact with the server,
// and wrappers for common events.
type Commands struct {
	c *Client
}

// Nick changes the client nickname.
func (cmd *Commands) Nick(name string) {
	cmd.c.Send(&Event{Command: NICK, Params: []string{name}})
}

// Join attempts to enter a list of IRC channels, at bulk if possible to
// prevent sending extensive JOIN commands.
func (cmd *Commands) Join(channels ...string) {
	// We can join multiple channels at once, however we need to ensure that
	// we are not exceeding the line length. (see maxLength)
	max := maxLength - len(JOIN) - 1

	var buffer string

	for i := 0; i < len(channels); i++ {
		if len(buffer+","+channels[i]) > max {
			cmd.c.Send(&Event{Command: JOIN, Params: []string{buffer}})
			buffer = ""
			continue
		}

		if len(buffer) == 0 {
			buffer = channels[i]
		} else {
			buffer += "," + channels[i]
		}

		if i == len(channels)-1 {
			cmd.c.Send(&Event{Command: JOIN, Params: []string{buffer}})
			return
		}
	}
}

// JoinKey attempts to enter an IRC channel with a password.
func (cmd *Commands) JoinKey(channel, password string) {
	cmd.c.Send(&Event{Command: JOIN, Params: []string{channel, password}})
}

// Part leaves an IRC channel.
func (cmd *Commands) Part(channel string) {
	cmd.c.Send(&Event{Command: PART, Params: []string{channel}})
}

// PartMessage leaves an IRC channel with a specified leave message.
func (cmd *Commands) PartMessage(channel, message string) {
	cmd.c.Send(&Event{Command: PART, Params: []string{channel}, Trailing: message, EmptyTrailing: true})
}

// SendCTCP sends a CTCP request to target. Note that this method uses
// PRIVMSG specifically. ctcpType is the CTCP command, e.g. "FINGER", "TIME",
// "VERSION", etc.
func (cmd *Commands) SendCTCP(target, ctcpType, message string) {
	out := encodeCTCPRaw(ctcpType, message)
	if out == "" {
		panic(fmt.Sprintf("invalid CTCP: %s -> %s: %s", target, ctcpType, message))
	}

	cmd.Message(target, out)
}

// SendCTCPf sends a CTCP request to target using a specific format. Note that
// this method uses PRIVMSG specifically. ctcpType is the CTCP command, e.g.
// "FINGER", "TIME", "VERSION", etc.
func (cmd *Commands) SendCTCPf(target, ctcpType, format string, a ...interface{}) {
	cmd.SendCTCP(target, ctcpType, fmt.Sprintf(format, a...))
}

// SendCTCPReplyf sends a CTCP response to target using a specific format.
// Note that this method uses NOTICE specifically. ctcpType is the CTCP
// command, e.g. "FINGER", "TIME", "VERSION", etc.
func (cmd *Commands) SendCTCPReplyf(target, ctcpType, format string, a ...interface{}) {
	cmd.SendCTCPReply(target, ctcpType, fmt.Sprintf(format, a...))
}

// SendCTCPReply sends a CTCP response to target. Note that this method uses
// NOTICE specifically.
func (cmd *Commands) SendCTCPReply(target, ctcpType, message string) {
	out := encodeCTCPRaw(ctcpType, message)
	if out == "" {
		panic(fmt.Sprintf("invalid CTCP: %s -> %s: %s", target, ctcpType, message))
	}

	cmd.Notice(target, out)
}

// Message sends a PRIVMSG to target (either channel, service, or user).
func (cmd *Commands) Message(target, message string) {
	cmd.c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: message, EmptyTrailing: true})
}

// Messagef sends a formated PRIVMSG to target (either channel, service, or
// user).
func (cmd *Commands) Messagef(target, format string, a ...interface{}) {
	cmd.Message(target, fmt.Sprintf(format, a...))
}

// ErrInvalidSource is returned when a method needs to know the origin of an
// event, however Event.Source is unknown (e.g. sent by the user, not the
// server.)
var ErrInvalidSource = errors.New("event has nil or invalid source address")

// Reply sends a reply to channel or user, based on where the supplied event
// originated from. See also ReplyTo(). Panics if the incoming event has no
// source.
func (cmd *Commands) Reply(event Event, message string) {
	if event.Source == nil {
		panic(ErrInvalidSource)
	}

	if len(event.Params) > 0 && IsValidChannel(event.Params[0]) {
		cmd.Message(event.Params[0], message)
		return
	}

	cmd.Message(event.Source.Name, message)
}

// Replyf sends a reply to channel or user with a format string, based on
// where the supplied event originated from. See also ReplyTof(). Panics if
// the incoming event has no source.
func (cmd *Commands) Replyf(event Event, format string, a ...interface{}) {
	cmd.Reply(event, fmt.Sprintf(format, a...))
}

// ReplyTo sends a reply to a channel or user, based on where the supplied
// event originated from. ReplyTo(), when originating from a channel will
// default to replying with "<user>, <message>". See also Reply(). Panics if
// the incoming event has no source.
func (cmd *Commands) ReplyTo(event Event, message string) {
	if event.Source == nil {
		panic(ErrInvalidSource)
	}

	if len(event.Params) > 0 && IsValidChannel(event.Params[0]) {
		cmd.Message(event.Params[0], event.Source.Name+", "+message)
		return
	}

	cmd.Message(event.Source.Name, message)
}

// ReplyTof sends a reply to a channel or user with a format string, based
// on where the supplied event originated from. ReplyTo(), when originating
// from a channel will default to replying with "<user>, <message>". See
// also Replyf(). Panics if the incoming event has no source.
func (cmd *Commands) ReplyTof(event Event, format string, a ...interface{}) {
	cmd.ReplyTo(event, fmt.Sprintf(format, a...))
}

// Action sends a PRIVMSG ACTION (/me) to target (either channel, service,
// or user).
func (cmd *Commands) Action(target, message string) {
	cmd.c.Send(&Event{
		Command:  PRIVMSG,
		Params:   []string{target},
		Trailing: fmt.Sprintf("\001ACTION %s\001", message),
	})
}

// Actionf sends a formated PRIVMSG ACTION (/me) to target (either channel,
// service, or user).
func (cmd *Commands) Actionf(target, format string, a ...interface{}) {
	cmd.Action(target, fmt.Sprintf(format, a...))
}

// Notice sends a NOTICE to target (either channel, service, or user).
func (cmd *Commands) Notice(target, message string) {
	cmd.c.Send(&Event{Command: NOTICE, Params: []string{target}, Trailing: message, EmptyTrailing: true})
}

// Noticef sends a formated NOTICE to target (either channel, service, or
// user).
func (cmd *Commands) Noticef(target, format string, a ...interface{}) {
	cmd.Notice(target, fmt.Sprintf(format, a...))
}

// SendRaw sends a raw string back to the server, without carriage returns
// or newlines.
func (cmd *Commands) SendRaw(raw string) error {
	e := ParseEvent(raw)
	if e == nil {
		return errors.New("invalid event: " + raw)
	}

	cmd.c.Send(e)
	return nil
}

// SendRawf sends a formated string back to the server, without carriage
// returns or newlines.
func (cmd *Commands) SendRawf(format string, a ...interface{}) error {
	return cmd.SendRaw(fmt.Sprintf(format, a...))
}

// Topic sets the topic of channel to message. Does not verify the length
// of the topic.
func (cmd *Commands) Topic(channel, message string) {
	cmd.c.Send(&Event{Command: TOPIC, Params: []string{channel}, Trailing: message, EmptyTrailing: true})
}

// Who sends a WHO query to the server, which will attempt WHOX by default.
// See http://faerion.sourceforge.net/doc/irc/whox.var for more details. This
// sends "%tcuhnr,2" per default. Do not use "1" as this will conflict with
// girc's builtin tracking functionality.
func (cmd *Commands) Who(target string) {
	cmd.c.Send(&Event{Command: WHO, Params: []string{target, "%tcuhnr,2"}})
}

// Whois sends a WHOIS query to the server, targeted at a specific user.
// as WHOIS is a bit slower, you may want to use WHO for brief user info.
func (cmd *Commands) Whois(nick string) {
	cmd.c.Send(&Event{Command: WHOIS, Params: []string{nick}})
}

// Ping sends a PING query to the server, with a specific identifier that
// the server should respond with.
func (cmd *Commands) Ping(id string) {
	cmd.c.write(&Event{Command: PING, Params: []string{id}})
}

// Pong sends a PONG query to the server, with an identifier which was
// received from a previous PING query received by the client.
func (cmd *Commands) Pong(id string) {
	cmd.c.write(&Event{Command: PONG, Params: []string{id}})
}

// Oper sends a OPER authentication query to the server, with a username
// and password.
func (cmd *Commands) Oper(user, pass string) {
	cmd.c.Send(&Event{Command: OPER, Params: []string{user, pass}, Sensitive: true})
}

// Kick sends a KICK query to the server, attempting to kick nick from
// channel, with reason. If reason is blank, one will not be sent to the
// server.
func (cmd *Commands) Kick(channel, nick, reason string) {
	if reason != "" {
		cmd.c.Send(&Event{Command: KICK, Params: []string{channel, nick}, Trailing: reason, EmptyTrailing: true})
	}

	cmd.c.Send(&Event{Command: KICK, Params: []string{channel, nick}})
}

// Invite sends a INVITE query to the server, to invite nick to channel.
func (cmd *Commands) Invite(channel, nick string) {
	cmd.c.Send(&Event{Command: INVITE, Params: []string{nick, channel}})
}

// Away sends a AWAY query to the server, suggesting that the client is no
// longer active. If reason is blank, Client.Back() is called. Also see
// Client.Back().
func (cmd *Commands) Away(reason string) {
	if reason == "" {
		cmd.Back()
		return
	}

	cmd.c.Send(&Event{Command: AWAY, Params: []string{reason}})
}

// Back sends a AWAY query to the server, however the query is blank,
// suggesting that the client is active once again. Also see Client.Away().
func (cmd *Commands) Back() {
	cmd.c.Send(&Event{Command: AWAY})
}

// List sends a LIST query to the server, which will list channels and topics.
// Supports multiple channels at once, in hopes it will reduce extensive
// LIST queries to the server. Supply no channels to run a list against the
// entire server (warning, that may mean LOTS of channels!)
func (cmd *Commands) List(channels ...string) {
	if len(channels) == 0 {
		cmd.c.Send(&Event{Command: LIST})
		return
	}

	// We can LIST multiple channels at once, however we need to ensure that
	// we are not exceeding the line length. (see maxLength)
	max := maxLength - len(JOIN) - 1

	var buffer string

	for i := 0; i < len(channels); i++ {
		if len(buffer+","+channels[i]) > max {
			cmd.c.Send(&Event{Command: LIST, Params: []string{buffer}})
			buffer = ""
			continue
		}

		if len(buffer) == 0 {
			buffer = channels[i]
		} else {
			buffer += "," + channels[i]
		}

		if i == len(channels)-1 {
			cmd.c.Send(&Event{Command: LIST, Params: []string{buffer}})
			return
		}
	}
}

// Whowas sends a WHOWAS query to the server. amount is the amount of results
// you want back.
func (cmd *Commands) Whowas(nick string, amount int) {
	cmd.c.Send(&Event{Command: WHOWAS, Params: []string{nick, string(amount)}})
}
<commit_msg>additional variadic command methods<commit_after>// Copyright (c) Liam Stanley <me@liamstanley.io>. All rights reserved. Use
// of this source code is governed by the MIT license that can be found in
// the LICENSE file.

package girc

import (
	"errors"
	"fmt"
)

// Commands holds a large list of useful methods to interact with the server,
// and wrappers for common events.
type Commands struct {
	c *Client
}

// Nick changes the client nickname.
func (cmd *Commands) Nick(name string) {
	cmd.c.Send(&Event{Command: NICK, Params: []string{name}})
}

// Join attempts to enter a list of IRC channels, at bulk if possible to
// prevent sending extensive JOIN commands.
func (cmd *Commands) Join(channels ...string) {
	// We can join multiple channels at once, however we need to ensure that
	// we are not exceeding the line length. (see maxLength)
	max := maxLength - len(JOIN) - 1

	var buffer string

	for i := 0; i < len(channels); i++ {
		if len(buffer+","+channels[i]) > max {
			cmd.c.Send(&Event{Command: JOIN, Params: []string{buffer}})
			buffer = ""
			continue
		}

		if len(buffer) == 0 {
			buffer = channels[i]
		} else {
			buffer += "," + channels[i]
		}

		if i == len(channels)-1 {
			cmd.c.Send(&Event{Command: JOIN, Params: []string{buffer}})
			return
		}
	}
}

// JoinKey attempts to enter an IRC channel with a password.
func (cmd *Commands) JoinKey(channel, password string) {
	cmd.c.Send(&Event{Command: JOIN, Params: []string{channel, password}})
}

// Part leaves an IRC channel.
func (cmd *Commands) Part(channels ...string) {
	for i := 0; i < len(channels); i++ {
		cmd.c.Send(&Event{Command: PART, Params: []string{channels[i]}})
	}
}

// PartMessage leaves an IRC channel with a specified leave message.
func (cmd *Commands) PartMessage(channel, message string) {
	cmd.c.Send(&Event{Command: PART, Params: []string{channel}, Trailing: message, EmptyTrailing: true})
}

// SendCTCP sends a CTCP request to target. Note that this method uses
// PRIVMSG specifically. ctcpType is the CTCP command, e.g. "FINGER", "TIME",
// "VERSION", etc.
func (cmd *Commands) SendCTCP(target, ctcpType, message string) {
	out := encodeCTCPRaw(ctcpType, message)
	if out == "" {
		panic(fmt.Sprintf("invalid CTCP: %s -> %s: %s", target, ctcpType, message))
	}

	cmd.Message(target, out)
}

// SendCTCPf sends a CTCP request to target using a specific format. Note that
// this method uses PRIVMSG specifically. ctcpType is the CTCP command, e.g.
// "FINGER", "TIME", "VERSION", etc.
func (cmd *Commands) SendCTCPf(target, ctcpType, format string, a ...interface{}) {
	cmd.SendCTCP(target, ctcpType, fmt.Sprintf(format, a...))
}

// SendCTCPReplyf sends a CTCP response to target using a specific format.
// Note that this method uses NOTICE specifically. ctcpType is the CTCP
// command, e.g. "FINGER", "TIME", "VERSION", etc.
func (cmd *Commands) SendCTCPReplyf(target, ctcpType, format string, a ...interface{}) {
	cmd.SendCTCPReply(target, ctcpType, fmt.Sprintf(format, a...))
}

// SendCTCPReply sends a CTCP response to target. Note that this method uses
// NOTICE specifically.
func (cmd *Commands) SendCTCPReply(target, ctcpType, message string) {
	out := encodeCTCPRaw(ctcpType, message)
	if out == "" {
		panic(fmt.Sprintf("invalid CTCP: %s -> %s: %s", target, ctcpType, message))
	}

	cmd.Notice(target, out)
}

// Message sends a PRIVMSG to target (either channel, service, or user).
func (cmd *Commands) Message(target, message string) {
	cmd.c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: message, EmptyTrailing: true})
}

// Messagef sends a formated PRIVMSG to target (either channel, service, or
// user).
func (cmd *Commands) Messagef(target, format string, a ...interface{}) {
	cmd.Message(target, fmt.Sprintf(format, a...))
}

// ErrInvalidSource is returned when a method needs to know the origin of an
// event, however Event.Source is unknown (e.g. sent by the user, not the
// server.)
var ErrInvalidSource = errors.New("event has nil or invalid source address")

// Reply sends a reply to channel or user, based on where the supplied event
// originated from. See also ReplyTo(). Panics if the incoming event has no
// source.
func (cmd *Commands) Reply(event Event, message string) {
	if event.Source == nil {
		panic(ErrInvalidSource)
	}

	if len(event.Params) > 0 && IsValidChannel(event.Params[0]) {
		cmd.Message(event.Params[0], message)
		return
	}

	cmd.Message(event.Source.Name, message)
}

// Replyf sends a reply to channel or user with a format string, based on
// where the supplied event originated from. See also ReplyTof(). Panics if
// the incoming event has no source.
func (cmd *Commands) Replyf(event Event, format string, a ...interface{}) {
	cmd.Reply(event, fmt.Sprintf(format, a...))
}

// ReplyTo sends a reply to a channel or user, based on where the supplied
// event originated from. ReplyTo(), when originating from a channel will
// default to replying with "<user>, <message>". See also Reply(). Panics if
// the incoming event has no source.
func (cmd *Commands) ReplyTo(event Event, message string) {
	if event.Source == nil {
		panic(ErrInvalidSource)
	}

	if len(event.Params) > 0 && IsValidChannel(event.Params[0]) {
		cmd.Message(event.Params[0], event.Source.Name+", "+message)
		return
	}

	cmd.Message(event.Source.Name, message)
}

// ReplyTof sends a reply to a channel or user with a format string, based
// on where the supplied event originated from. ReplyTo(), when originating
// from a channel will default to replying with "<user>, <message>". See
// also Replyf(). Panics if the incoming event has no source.
func (cmd *Commands) ReplyTof(event Event, format string, a ...interface{}) {
	cmd.ReplyTo(event, fmt.Sprintf(format, a...))
}

// Action sends a PRIVMSG ACTION (/me) to target (either channel, service,
// or user).
func (cmd *Commands) Action(target, message string) {
	cmd.c.Send(&Event{
		Command:  PRIVMSG,
		Params:   []string{target},
		Trailing: fmt.Sprintf("\001ACTION %s\001", message),
	})
}

// Actionf sends a formated PRIVMSG ACTION (/me) to target (either channel,
// service, or user).
func (cmd *Commands) Actionf(target, format string, a ...interface{}) {
	cmd.Action(target, fmt.Sprintf(format, a...))
}

// Notice sends a NOTICE to target (either channel, service, or user).
func (cmd *Commands) Notice(target, message string) {
	cmd.c.Send(&Event{Command: NOTICE, Params: []string{target}, Trailing: message, EmptyTrailing: true})
}

// Noticef sends a formated NOTICE to target (either channel, service, or
// user).
func (cmd *Commands) Noticef(target, format string, a ...interface{}) {
	cmd.Notice(target, fmt.Sprintf(format, a...))
}

// SendRaw sends a raw string (or multiple) to the server, without carriage
// returns or newlines. Returns an error if one of the raw strings cannot be
// properly parsed.
func (cmd *Commands) SendRaw(raw ...string) error {
	var event *Event

	for i := 0; i < len(raw); i++ {
		event = ParseEvent(raw[i])
		if event == nil {
			return errors.New("invalid event: " + raw[i])
		}

		cmd.c.Send(event)
	}

	return nil
}

// SendRawf sends a formated string back to the server, without carriage
// returns or newlines.
func (cmd *Commands) SendRawf(format string, a ...interface{}) error {
	return cmd.SendRaw(fmt.Sprintf(format, a...))
}

// Topic sets the topic of channel to message. Does not verify the length
// of the topic.
func (cmd *Commands) Topic(channel, message string) {
	cmd.c.Send(&Event{Command: TOPIC, Params: []string{channel}, Trailing: message, EmptyTrailing: true})
}

// Who sends a WHO query to the server, which will attempt WHOX by default.
// See http://faerion.sourceforge.net/doc/irc/whox.var for more details. This
// sends "%tcuhnr,2" per default. Do not use "1" as this will conflict with
// girc's builtin tracking functionality.
func (cmd *Commands) Who(users ...string) {
	for i := 0; i < len(users); i++ {
		cmd.c.Send(&Event{Command: WHO, Params: []string{users[i], "%tcuhnr,2"}})
	}
}

// Whois sends a WHOIS query to the server, targeted at a specific user (or
// set of users). As WHOIS is a bit slower, you may want to use WHO for brief
// user info.
func (cmd *Commands) Whois(users ...string) {
	for i := 0; i < len(users); i++ {
		cmd.c.Send(&Event{Command: WHOIS, Params: []string{users[i]}})
	}
}

// Ping sends a PING query to the server, with a specific identifier that
// the server should respond with.
func (cmd *Commands) Ping(id string) {
	cmd.c.write(&Event{Command: PING, Params: []string{id}})
}

// Pong sends a PONG query to the server, with an identifier which was
// received from a previous PING query received by the client.
func (cmd *Commands) Pong(id string) {
	cmd.c.write(&Event{Command: PONG, Params: []string{id}})
}

// Oper sends a OPER authentication query to the server, with a username
// and password.
func (cmd *Commands) Oper(user, pass string) {
	cmd.c.Send(&Event{Command: OPER, Params: []string{user, pass}, Sensitive: true})
}

// Kick sends a KICK query to the server, attempting to kick nick from
// channel, with reason. If reason is blank, one will not be sent to the
// server.
func (cmd *Commands) Kick(channel, user, reason string) {
	if reason != "" {
		cmd.c.Send(&Event{Command: KICK, Params: []string{channel, user}, Trailing: reason, EmptyTrailing: true})
	}

	cmd.c.Send(&Event{Command: KICK, Params: []string{channel, user}})
}

// Invite sends a INVITE query to the server, to invite nick to channel.
func (cmd *Commands) Invite(channel string, users ...string) {
	for i := 0; i < len(users); i++ {
		cmd.c.Send(&Event{Command: INVITE, Params: []string{users[i], channel}})
	}
}

// Away sends a AWAY query to the server, suggesting that the client is no
// longer active. If reason is blank, Client.Back() is called. Also see
// Client.Back().
func (cmd *Commands) Away(reason string) {
	if reason == "" {
		cmd.Back()
		return
	}

	cmd.c.Send(&Event{Command: AWAY, Params: []string{reason}})
}

// Back sends a AWAY query to the server, however the query is blank,
// suggesting that the client is active once again. Also see Client.Away().
func (cmd *Commands) Back() {
	cmd.c.Send(&Event{Command: AWAY})
}

// List sends a LIST query to the server, which will list channels and topics.
// Supports multiple channels at once, in hopes it will reduce extensive
// LIST queries to the server. Supply no channels to run a list against the
// entire server (warning, that may mean LOTS of channels!)
func (cmd *Commands) List(channels ...string) {
	if len(channels) == 0 {
		cmd.c.Send(&Event{Command: LIST})
		return
	}

	// We can LIST multiple channels at once, however we need to ensure that
	// we are not exceeding the line length. (see maxLength)
	max := maxLength - len(JOIN) - 1

	var buffer string

	for i := 0; i < len(channels); i++ {
		if len(buffer+","+channels[i]) > max {
			cmd.c.Send(&Event{Command: LIST, Params: []string{buffer}})
			buffer = ""
			continue
		}

		if len(buffer) == 0 {
			buffer = channels[i]
		} else {
			buffer += "," + channels[i]
		}

		if i == len(channels)-1 {
			cmd.c.Send(&Event{Command: LIST, Params: []string{buffer}})
			return
		}
	}
}

// Whowas sends a WHOWAS query to the server. amount is the amount of results
// you want back.
func (cmd *Commands) Whowas(user string, amount int) {
	cmd.c.Send(&Event{Command: WHOWAS, Params: []string{user, string(amount)}})
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package syncutil_test

import (
	"errors"
	"math/rand"
	"sync"
	"sync/atomic"
	"testing"
	"time"

	"github.com/jacobsa/gcloud/syncutil"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
)

func TestOgletest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type BundleTest struct {
	bundle       *syncutil.Bundle
	cancelParent context.CancelFunc
}

func init() { RegisterTestSuite(&BundleTest{}) }

func (t *BundleTest) SetUp(ti *TestInfo) {
	// Set up the parent context.
	parentCtx, cancelParent := context.WithCancel(context.Background())
	t.cancelParent = cancelParent

	// Set up the bundle.
	t.bundle = syncutil.NewBundle(parentCtx)
}

////////////////////////////////////////////////////////////////////////
// Test functions
////////////////////////////////////////////////////////////////////////

func (t *BundleTest) NoOperations() {
	ExpectEq(nil, t.bundle.Join())
}

func (t *BundleTest) SingleOp_Success() {
	t.bundle.Add(func(c context.Context) error {
		return nil
	})

	ExpectEq(nil, t.bundle.Join())
}

func (t *BundleTest) SingleOp_Error() {
	expected := errors.New("taco")
	t.bundle.Add(func(c context.Context) error {
		return expected
	})

	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) SingleOp_ParentCancelled() {
	// Start an op that waits for the context to be cancelled before returning an
	// expected value.
	expected := errors.New("taco")
	t.bundle.Add(func(c context.Context) error {
		<-c.Done()
		return expected
	})

	// Cancel the parent context, then join the bundle. The op should see the
	// cancellation, so we shouldn't deadlock and we should get the expected
	// value.
	t.cancelParent()
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_Success() {
	for i := 0; i < 4; i++ {
		t.bundle.Add(func(c context.Context) error {
			return nil
		})
	}

	ExpectEq(nil, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_UnorderedErrors() {
	// Start multiple ops, each returning a different error.
	errs := []error{
		errors.New("taco"),
		errors.New("burrito"),
		errors.New("enchilada"),
	}

	for i := 0; i < len(errs); i++ {
		iCopy := i
		t.bundle.Add(func(c context.Context) error {
			return errs[iCopy]
		})
	}

	// Joining the bundle should result in some error from the list.
	ExpectThat(errs, Contains(t.bundle.Join()))
}

func (t *BundleTest) MultipleOps_OneError_OthersDontWait() {
	expected := errors.New("taco")

	// Add two operations that succeed and one that fails.
	t.bundle.Add(func(c context.Context) error { return nil })
	t.bundle.Add(func(c context.Context) error { return expected })
	t.bundle.Add(func(c context.Context) error { return nil })

	// We should see the failure.
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_OneError_OthersWaitForCancellation() {
	expected := errors.New("taco")

	// Add several ops that wait for cancellation then succeed, and one that
	// returns an error.
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })
	t.bundle.Add(func(c context.Context) error { return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })

	// We should see the failure.
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_ParentCancelled() {
	expected := errors.New("taco")

	// Start multiple ops that wait for the context to be cancelled before
	// returning an expected value.
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })

	// Cancel the parent context, then join the bundle. The ops should see the
	// cancellation, so we shouldn't deadlock and we should get the expected
	// value.
	t.cancelParent()
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_PreviousError_NewOpsObserve() {
	var wg sync.WaitGroup
	signalCancellation := func(c context.Context) error {
		<-c.Done()
		wg.Done()
		return nil
	}

	// Start an op that will let us know when it is cancelled.
	wg.Add(1)
	t.bundle.Add(signalCancellation)

	// Start an op that returns an error.
	expected := errors.New("taco")
	t.bundle.Add(func(c context.Context) error { return expected })

	// Wait for the error to be observed.
	wg.Wait()

	// Further ops should be immediately cancelled.
	wg = sync.WaitGroup{}
	for i := 0; i < 10; i++ {
		wg.Add(1)
		t.bundle.Add(signalCancellation)
	}

	wg.Wait()

	// Join.
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_PreviousParentCancel_NewOpsObserve() {
	var wg sync.WaitGroup
	signalCancellation := func(c context.Context) error {
		<-c.Done()
		wg.Done()
		return nil
	}

	// Cancel the parent context.
	t.cancelParent()

	// Further ops should be immediately cancelled.
	wg = sync.WaitGroup{}
	for i := 0; i < 10; i++ {
		wg.Add(1)
		t.bundle.Add(signalCancellation)
	}

	wg.Wait()

	// Join.
	t.bundle.Join()
}

func (t *BundleTest) JoinWaitsForAllOps_Success() {
	// Set up a 64-bit counter that is guaranteed to be properly aligned.
	// Cf. "Bugs" section of http://godoc.org/sync/atomic.
	slice := make([]uint64, 1)
	var counter *uint64 = &slice[0]

	// Start several ops that sleep awhile, increment a counter, and return.
	const N = 100
	for i := 0; i < N; i++ {
		t.bundle.Add(func(c context.Context) error {
			numMs := rand.Float64() * 100
			time.Sleep(time.Duration(numMs) * time.Millisecond)
			atomic.AddUint64(counter, 1)
			return nil
		})
	}

	// Wait for all of the ops. Afterward, the counter should have the expected
	// value.
	AssertEq(nil, t.bundle.Join())
	ExpectEq(N, atomic.LoadUint64(counter))
}

func (t *BundleTest) JoinWaitsForAllOps_Error() {
	expected := errors.New("taco")

	// Set up a 64-bit counter that is guaranteed to be properly aligned.
	// Cf. "Bugs" section of http://godoc.org/sync/atomic.
	slice := make([]uint64, 1)
	var counter *uint64 = &slice[0]

	// Start several ops that sleep awhile, increment a counter, and return an
	// error.
	const N = 100
	for i := 0; i < N; i++ {
		t.bundle.Add(func(c context.Context) error {
			numMs := rand.Float64() * 100
			time.Sleep(time.Duration(numMs) * time.Millisecond)
			atomic.AddUint64(counter, 1)
			return expected
		})
	}

	// Wait for all of the ops. Afterward, the counter should have the expected
	// value.
	AssertEq(expected, t.bundle.Join())
	ExpectEq(N, atomic.LoadUint64(counter))
}

func (t *BundleTest) JoinWaitsForAllOps_ParentCancelled() {
	t.cancelParent()

	// Set up a 64-bit counter that is guaranteed to be properly aligned.
	// Cf. "Bugs" section of http://godoc.org/sync/atomic.
	slice := make([]uint64, 1)
	var counter *uint64 = &slice[0]

	// Start several ops that sleep awhile, increment a counter, and return an
	// error.
	const N = 100
	for i := 0; i < N; i++ {
		t.bundle.Add(func(c context.Context) error {
			numMs := rand.Float64() * 100
			time.Sleep(time.Duration(numMs) * time.Millisecond)
			atomic.AddUint64(counter, 1)
			return nil
		})
	}

	// Wait for all of the ops. Afterward, the counter should have the expected
	// value.
	AssertEq(nil, t.bundle.Join())
	ExpectEq(N, atomic.LoadUint64(counter))
}
<commit_msg>Allow parallelism in tests.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package syncutil_test

import (
	"errors"
	"math/rand"
	"runtime"
	"sync"
	"sync/atomic"
	"testing"
	"time"

	"github.com/jacobsa/gcloud/syncutil"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
)

func TestOgletest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type BundleTest struct {
	bundle       *syncutil.Bundle
	cancelParent context.CancelFunc
}

var _ SetUpTestSuiteInterface = &BundleTest{}
var _ SetUpInterface = &BundleTest{}

func init() { RegisterTestSuite(&BundleTest{}) }

func (t *BundleTest) SetUpTestSuite() {
	// Make sure parallelism is allowed.
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func (t *BundleTest) SetUp(ti *TestInfo) {
	// Set up the parent context.
	parentCtx, cancelParent := context.WithCancel(context.Background())
	t.cancelParent = cancelParent

	// Set up the bundle.
	t.bundle = syncutil.NewBundle(parentCtx)
}

////////////////////////////////////////////////////////////////////////
// Test functions
////////////////////////////////////////////////////////////////////////

func (t *BundleTest) NoOperations() {
	ExpectEq(nil, t.bundle.Join())
}

func (t *BundleTest) SingleOp_Success() {
	t.bundle.Add(func(c context.Context) error {
		return nil
	})

	ExpectEq(nil, t.bundle.Join())
}

func (t *BundleTest) SingleOp_Error() {
	expected := errors.New("taco")
	t.bundle.Add(func(c context.Context) error {
		return expected
	})

	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) SingleOp_ParentCancelled() {
	// Start an op that waits for the context to be cancelled before returning an
	// expected value.
	expected := errors.New("taco")
	t.bundle.Add(func(c context.Context) error {
		<-c.Done()
		return expected
	})

	// Cancel the parent context, then join the bundle. The op should see the
	// cancellation, so we shouldn't deadlock and we should get the expected
	// value.
	t.cancelParent()
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_Success() {
	for i := 0; i < 4; i++ {
		t.bundle.Add(func(c context.Context) error {
			return nil
		})
	}

	ExpectEq(nil, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_UnorderedErrors() {
	// Start multiple ops, each returning a different error.
	errs := []error{
		errors.New("taco"),
		errors.New("burrito"),
		errors.New("enchilada"),
	}

	for i := 0; i < len(errs); i++ {
		iCopy := i
		t.bundle.Add(func(c context.Context) error {
			return errs[iCopy]
		})
	}

	// Joining the bundle should result in some error from the list.
	ExpectThat(errs, Contains(t.bundle.Join()))
}

func (t *BundleTest) MultipleOps_OneError_OthersDontWait() {
	expected := errors.New("taco")

	// Add two operations that succeed and one that fails.
	t.bundle.Add(func(c context.Context) error { return nil })
	t.bundle.Add(func(c context.Context) error { return expected })
	t.bundle.Add(func(c context.Context) error { return nil })

	// We should see the failure.
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_OneError_OthersWaitForCancellation() {
	expected := errors.New("taco")

	// Add several ops that wait for cancellation then succeed, and one that
	// returns an error.
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })
	t.bundle.Add(func(c context.Context) error { return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return nil })

	// We should see the failure.
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_ParentCancelled() {
	expected := errors.New("taco")

	// Start multiple ops that wait for the context to be cancelled before
	// returning an expected value.
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })
	t.bundle.Add(func(c context.Context) error { <-c.Done(); return expected })

	// Cancel the parent context, then join the bundle. The ops should see the
	// cancellation, so we shouldn't deadlock and we should get the expected
	// value.
	t.cancelParent()
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_PreviousError_NewOpsObserve() {
	var wg sync.WaitGroup
	signalCancellation := func(c context.Context) error {
		<-c.Done()
		wg.Done()
		return nil
	}

	// Start an op that will let us know when it is cancelled.
	wg.Add(1)
	t.bundle.Add(signalCancellation)

	// Start an op that returns an error.
	expected := errors.New("taco")
	t.bundle.Add(func(c context.Context) error { return expected })

	// Wait for the error to be observed.
	wg.Wait()

	// Further ops should be immediately cancelled.
	wg = sync.WaitGroup{}
	for i := 0; i < 10; i++ {
		wg.Add(1)
		t.bundle.Add(signalCancellation)
	}

	wg.Wait()

	// Join.
	ExpectEq(expected, t.bundle.Join())
}

func (t *BundleTest) MultipleOps_PreviousParentCancel_NewOpsObserve() {
	var wg sync.WaitGroup
	signalCancellation := func(c context.Context) error {
		<-c.Done()
		wg.Done()
		return nil
	}

	// Cancel the parent context.
	t.cancelParent()

	// Further ops should be immediately cancelled.
	wg = sync.WaitGroup{}
	for i := 0; i < 10; i++ {
		wg.Add(1)
		t.bundle.Add(signalCancellation)
	}

	wg.Wait()

	// Join.
	t.bundle.Join()
}

func (t *BundleTest) JoinWaitsForAllOps_Success() {
	// Set up a 64-bit counter that is guaranteed to be properly aligned.
	// Cf. "Bugs" section of http://godoc.org/sync/atomic.
	slice := make([]uint64, 1)
	var counter *uint64 = &slice[0]

	// Start several ops that sleep awhile, increment a counter, and return.
	const N = 100
	for i := 0; i < N; i++ {
		t.bundle.Add(func(c context.Context) error {
			numMs := rand.Float64() * 100
			time.Sleep(time.Duration(numMs) * time.Millisecond)
			atomic.AddUint64(counter, 1)
			return nil
		})
	}

	// Wait for all of the ops. Afterward, the counter should have the expected
	// value.
	AssertEq(nil, t.bundle.Join())
	ExpectEq(N, atomic.LoadUint64(counter))
}

func (t *BundleTest) JoinWaitsForAllOps_Error() {
	expected := errors.New("taco")

	// Set up a 64-bit counter that is guaranteed to be properly aligned.
	// Cf. "Bugs" section of http://godoc.org/sync/atomic.
	slice := make([]uint64, 1)
	var counter *uint64 = &slice[0]

	// Start several ops that sleep awhile, increment a counter, and return an
	// error.
	const N = 100
	for i := 0; i < N; i++ {
		t.bundle.Add(func(c context.Context) error {
			numMs := rand.Float64() * 100
			time.Sleep(time.Duration(numMs) * time.Millisecond)
			atomic.AddUint64(counter, 1)
			return expected
		})
	}

	// Wait for all of the ops. Afterward, the counter should have the expected
	// value.
	AssertEq(expected, t.bundle.Join())
	ExpectEq(N, atomic.LoadUint64(counter))
}

func (t *BundleTest) JoinWaitsForAllOps_ParentCancelled() {
	t.cancelParent()

	// Set up a 64-bit counter that is guaranteed to be properly aligned.
	// Cf. "Bugs" section of http://godoc.org/sync/atomic.
	slice := make([]uint64, 1)
	var counter *uint64 = &slice[0]

	// Start several ops that sleep awhile, increment a counter, and return an
	// error.
	const N = 100
	for i := 0; i < N; i++ {
		t.bundle.Add(func(c context.Context) error {
			numMs := rand.Float64() * 100
			time.Sleep(time.Duration(numMs) * time.Millisecond)
			atomic.AddUint64(counter, 1)
			return nil
		})
	}

	// Wait for all of the ops. Afterward, the counter should have the expected
	// value.
	AssertEq(nil, t.bundle.Join())
	ExpectEq(N, atomic.LoadUint64(counter))
}
<|endoftext|>


<commit_before>package iris1

import (
	"encoding/binary"
	"fmt"
	"github.com/DrItanium/cores/registration/parser"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"
)

type segment int

const (
	codeSegment segment = iota
	dataSegment
)

type ParsingRegistrar func(...interface{}) (parser.Parser, error)

func (this ParsingRegistrar) New(args ...interface{}) (parser.Parser, error) {
	return this(args)
}

type labelEntry struct {
	seg  segment
	addr Word
}

type labelMap map[string]labelEntry

func generateParser(a ...interface{}) (parser.Parser, error) {
	var p _parser
	if core, err := New(); err != nil {
		return nil, err
	} else {
		p.core = core
		p.labels = make(labelMap)
		return &p, nil
	}
}

func init() {
	parser.Register(RegistrationName(), ParsingRegistrar(generateParser))
}

type _parser struct {
	core               *Core
	statements         []statement
	labels             labelMap
	dataAddr, codeAddr Word
	currSegment        segment
}

func (this *_parser) Dump(pipe chan<- byte) error {
	c, d := make([]byte, 4), make([]byte, 2)
	for _, val := range this.core.code {
		binary.LittleEndian.PutUint32(c, uint32(val))
		for _, b := range c {
			pipe <- b
		}
	}
	for _, val := range this.core.data {
		binary.LittleEndian.PutUint16(d, uint16(val))
		for _, b := range d {
			pipe <- b
		}
	}
	return nil
}
func (this *_parser) Process() error {
	// we'll probably want to process labels at this point
	return nil
}

func (this *_parser) Parse(lines <-chan parser.Entry) error {
	for line := range lines {
		stmt := carveLine(line.Line)
		this.statements = append(this.statements, stmt)
		fmt.Println("{")
		for _, str := range stmt {
			if err := str.Parse(); err != nil {
				return fmt.Errorf("Error: line: %d : %s\n", line.Index, err)
			}
			fmt.Println("\t", str)
		}
		fmt.Println("}")
	}
	return nil
}

type nodeType int

const (
	typeUnknown nodeType = iota
	typeEquals
	typeComma
	typeLabel
	typeRegister
	typeImmediate
	typeBinaryImmediate
	typeHexImmediate
	typeComment
	typeSymbol
	typeDirective
	typeDirectiveData
	typeDirectiveCode
	typeDirectiveOrg
	typeDirectiveDeclare
	// keywords
	// memory words
	keywordSet
	keywordMove
	keywordLoad
	keywordStore
	// branch words
	keywordBranch
	keywordIf0
	keywordIf1
	keywordLink
	keywordThen
	keywordElse
	// arithmetic words
	keywordAdd
	keywordSub
	keywordMul
	keywordDiv
	keywordRem
	keywordShiftLeft
	keywordShiftRight
	keywordAnd
	keywordOr
	keywordNot
	keywordXor
	keywordIncrement
	keywordDecrement
	keywordHalve
	// compare words
	keywordEqual
	keywordNotEqual
	keywordLessThan
	keywordGreaterThan
	keywordLessThanOrEqualTo
	keywordGreaterThanOrEqualTo
	// misc words
	keywordSystem
)

type node struct {
	Value interface{}
	Type  nodeType
}

func parseHexImmediate(str string) (Word, error) {
	val, err := strconv.ParseUint(str, 16, 16)
	return Word(val), err
}
func parseBinaryImmediate(str string) (Word, error) {
	val, err := strconv.ParseUint(str, 2, 16)
	return Word(val), err
}
func parseDecimalImmediate(str string) (Word, error) {
	val, err := strconv.ParseUint(str, 10, 16)
	return Word(val), err
}
func parseRegisterValue(str string) (byte, error) {
	val, err := strconv.ParseUint(str, 10, 8)
	return byte(val), err
}

type invalidRegisterError struct {
	Value string
}

func (this *invalidRegisterError) Error() string {
	return fmt.Sprintf("Register %s is not a valid register!", this.Value)
}
func InvalidRegister(value string) error {
	return &invalidRegisterError{Value: value}
}
func (this *node) parseLabel(val string) error {
	nVal := strings.TrimSuffix(val, ":")
	q, _ := utf8.DecodeRuneInString(nVal)
	if !unicode.IsLetter(q) {
		return fmt.Errorf("Label %s starts with a non letter %s!", nVal, q)
	} else {
		this.Type = typeLabel
		this.Value = nVal
		// now parse the label as a entirely new node and see if we get a register back
		nod := node{Value: this.Value, Type: typeUnknown}
		if err := nod.Parse(); err != nil {
			switch err.(type) {
			case *strconv.NumError:
				j := err.(*strconv.NumError)
				if j.Err == strconv.ErrRange {
					return fmt.Errorf("Label %s is interpreted as an out of range value! This is not allowed as it is ambiguous!", this.Value)
				} else if j.Err == strconv.ErrSyntax {
					// probably legal, will require an extra pass most likely
					return nil
				} else {
					return err
				}
			case *invalidRegisterError:
				j := err.(*invalidRegisterError)
				return fmt.Errorf("Label %s is interpreted as an out of range register! This is not allowed as it is ambiguous!", j.Value)
			default:
				return fmt.Errorf("Unkown error occurred: %s! Programmer failure!", err)
			}
		} else {
			return nil
		}
	}
}
func (this *node) parseHexImmediate(val string) error {
	this.Type = typeHexImmediate
	if v, err := parseHexImmediate(val[2:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}
func (this *node) parseBinaryImmediate(val string) error {
	this.Type = typeBinaryImmediate
	if v, err := parseBinaryImmediate(val[2:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}
func (this *node) parseImmediate(val string) error {
	this.Type = typeImmediate
	if v, err := parseDecimalImmediate(val[1:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}
func (this *node) parseRegister(val string) error {
	this.Type = typeRegister
	if v, err := parseRegisterValue(val[1:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}

var directives = map[string]nodeType{
	{"data", typeDirectiveData},
	{"code", typeDirectiveCode},
	{"org", typeDirectiveOrg},
	{"declare", typeDirectiveDeclare},
}

func (this *node) parseDirective(val string) error {
	str := val[1:]
	this.Value = str
	if q, ok := directives[str]; ok {
		this.Type = q
	} else {
		this.Type = typeDirective
	}
	return nil
}

var keywords = map[string]nodeType{
	{"branch", keywordBranch},
	{"if0", keywordIf0},
	{"if1", keywordIf1},
	{"then", keywordThen},
	{"else", keywordElse},
	{"link", keywordLink},
	{"add", keywordAdd},
	{"sub", keywordSub},
	{"mul", keywordMul},
	{"div", keywordDiv},
	{"rem", keywordRem},
	{"shiftleft", keywordShiftLeft},
	{"shiftright", keywordShiftRight},
	{"and", keywordAnd},
	{"or", keywordOr},
	{"not", keywordNot},
	{"xor", keywordXor},
	{"halve", keywordHalve},
	{"incr", keywordIncrement},
	{"decr", keywordDecrement},
	{"system", keywordSystem},
	{"set", keywordSet},
	{"move", keywordMove},
	{"swap", keywordSwap},
	{"load", keywordLoad},
	{"store", keywordStore},
}

func (this *node) parseGeneric(str string) error {
	if v, ok := keywords[str]; ok {
		this.Type = v
	}
	return nil
}
func (this *node) Parse() error {
	if this.Type == typeUnknown {
		val := this.Value.(string)
		if val == "=" {
			this.Type = typeEquals
		} else if val == "," {
			this.Type = typeComma
		} else if strings.HasSuffix(val, ":") {
			return this.parseLabel(val)
		} else if strings.HasPrefix(val, ";") {
			this.Type = typeComma
			this.Value = strings.TrimPrefix(val, ";")
		} else if strings.HasPrefix(val, "#x") {
			return this.parseHexImmediate(val)
		} else if strings.HasPrefix(val, "#b") {
			return this.parseBinaryImmediate(val)
		} else if strings.HasPrefix(val, "#") {
			return this.parseImmediate(val)
		} else if strings.HasPrefix(val, "r") {
			return this.parseRegister(val)
		} else if strings.HasPrefix(val, "@") {
			return this.parseDirective(val)
		} else {
			return this.parseGeneric(val)
		}
	}
	return nil
}

func (this *node) IsComment() bool {
	return this.Type == typeComment
}
func (this *node) IsLabel() bool {
	return this.Type == typeLabel
}

type statement []*node

func (this *statement) Add(value string, t nodeType) {
	// always trim before adding
	str := strings.TrimSpace(value)
	if len(str) > 0 {
		*this = append(*this, &node{Value: str, Type: t})
	}
}
func (this *statement) AddUnknown(value string) {
	this.Add(value, typeUnknown)
}
func (this *statement) String() string {
	var str string
	for _, n := range *this {
		str += fmt.Sprintf(" %T: %s ", n, *n)
	}
	return str
}

func carveLine(line string) statement {
	// trim the damn line first
	data := strings.TrimSpace(line)
	var s statement
	if len(data) == 0 {
		return s
	}
	oldStart := 0
	start := 0
	// skip the strings at the beginning
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRuneInString(data[start:])
		if unicode.IsSpace(r) {
			s.AddUnknown(data[oldStart:start])
			oldStart = start
		} else if r == '=' {
			s.AddUnknown(data[oldStart:start])
			s.Add("=", typeEquals)
			oldStart = start + width
		} else if r == ',' {
			s.AddUnknown(data[oldStart:start])
			s.Add(",", typeComma)
			oldStart = start + width
		} else if r == ';' {
			// consume the rest of the data
			s.AddUnknown(data[oldStart:start])
			// then capture the comment
			s.Add(data[start:], typeComment)
			oldStart = start
			break
		}
	}
	if oldStart < start {
		s.AddUnknown(data[oldStart:])
	}
	return s
}
<commit_msg>More features added<commit_after>package iris1

import (
	"encoding/binary"
	"fmt"
	"github.com/DrItanium/cores/registration/parser"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"
)

type segment int

const (
	codeSegment segment = iota
	dataSegment
)

type ParsingRegistrar func(...interface{}) (parser.Parser, error)

func (this ParsingRegistrar) New(args ...interface{}) (parser.Parser, error) {
	return this(args)
}

type labelEntry struct {
	seg  segment
	addr Word
}

type labelMap map[string]labelEntry

func generateParser(a ...interface{}) (parser.Parser, error) {
	var p _parser
	if core, err := New(); err != nil {
		return nil, err
	} else {
		p.core = core
		p.labels = make(labelMap)
		return &p, nil
	}
}

func init() {
	parser.Register(RegistrationName(), ParsingRegistrar(generateParser))
}

type _parser struct {
	core               *Core
	statements         []statement
	labels             labelMap
	dataAddr, codeAddr Word
	currSegment        segment
}

func (this *_parser) Dump(pipe chan<- byte) error {
	c, d := make([]byte, 4), make([]byte, 2)
	for _, val := range this.core.code {
		binary.LittleEndian.PutUint32(c, uint32(val))
		for _, b := range c {
			pipe <- b
		}
	}
	for _, val := range this.core.data {
		binary.LittleEndian.PutUint16(d, uint16(val))
		for _, b := range d {
			pipe <- b
		}
	}
	return nil
}
func (this *_parser) Process() error {
	// we'll probably want to process labels at this point
	return nil
}

func (this *_parser) Parse(lines <-chan parser.Entry) error {
	for line := range lines {
		stmt := carveLine(line.Line)
		this.statements = append(this.statements, stmt)
		for _, str := range stmt {
			if err := str.Parse(); err != nil {
				return fmt.Errorf("Error: line: %d : %s\n", line.Index, err)
			}
			fmt.Print("\t", str, " ")
		}
		fmt.Println()
	}
	return nil
}

type nodeType int

const (
	typeUnknown nodeType = iota
	typeEquals
	typeComma
	typeLabel
	typeRegister
	typeImmediate
	typeBinaryImmediate
	typeHexImmediate
	typeComment
	typeSymbol
	typeAlias
	// directives
	typeDirective
	typeDirectiveData
	typeDirectiveCode
	typeDirectiveOrg
	typeDirectiveWord
	typeDirectiveAlias
	// keywords
	// memory words
	keywordSet
	keywordMove
	keywordLoad
	keywordStore
	keywordSwap
	// branch words
	keywordBranch
	keywordIf0
	keywordIf1
	keywordLink
	keywordThen
	keywordElse
	// arithmetic words
	keywordAdd
	keywordSub
	keywordMul
	keywordDiv
	keywordRem
	keywordShiftLeft
	keywordShiftRight
	keywordAnd
	keywordOr
	keywordNot
	keywordXor
	keywordIncrement
	keywordDecrement
	keywordHalve
	// compare words
	keywordEqual
	keywordNotEqual
	keywordLessThan
	keywordGreaterThan
	keywordLessThanOrEqualTo
	keywordGreaterThanOrEqualTo
	// misc words
	keywordSystem
)

type node struct {
	Value interface{}
	Type  nodeType
}

func parseHexImmediate(str string) (Word, error) {
	val, err := strconv.ParseUint(str, 16, 16)
	return Word(val), err
}
func parseBinaryImmediate(str string) (Word, error) {
	val, err := strconv.ParseUint(str, 2, 16)
	return Word(val), err
}
func parseDecimalImmediate(str string) (Word, error) {
	val, err := strconv.ParseUint(str, 10, 16)
	return Word(val), err
}
func parseRegisterValue(str string) (byte, error) {
	val, err := strconv.ParseUint(str, 10, 8)
	return byte(val), err
}

type invalidRegisterError struct {
	Value string
}

func (this *invalidRegisterError) Error() string {
	return fmt.Sprintf("Register %s is not a valid register!", this.Value)
}
func InvalidRegister(value string) error {
	return &invalidRegisterError{Value: value}
}
func (this *node) parseLabel(val string) error {
	nVal := strings.TrimSuffix(val, ":")
	q, _ := utf8.DecodeRuneInString(nVal)
	if !unicode.IsLetter(q) {
		return fmt.Errorf("Label %s starts with a non letter %s!", nVal, q)
	} else {
		this.Type = typeLabel
		this.Value = nVal
		// now parse the label as a entirely new node and see if we get a register back
		nod := node{Value: this.Value, Type: typeUnknown}
		if err := nod.Parse(); err != nil {
			switch err.(type) {
			case *strconv.NumError:
				j := err.(*strconv.NumError)
				if j.Err == strconv.ErrRange {
					return fmt.Errorf("Label %s is interpreted as an out of range value! This is not allowed as it is ambiguous!", this.Value)
				} else if j.Err == strconv.ErrSyntax {
					// probably legal, will require an extra pass most likely
					return nil
				} else {
					return err
				}
			case *invalidRegisterError:
				j := err.(*invalidRegisterError)
				return fmt.Errorf("Label %s is interpreted as an out of range register! This is not allowed as it is ambiguous!", j.Value)
			default:
				return fmt.Errorf("Unkown error occurred: %s! Programmer failure!", err)
			}
		} else {
			return nil
		}
	}
}
func (this *node) parseHexImmediate(val string) error {
	this.Type = typeHexImmediate
	if v, err := parseHexImmediate(val[2:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}
func (this *node) parseBinaryImmediate(val string) error {
	this.Type = typeBinaryImmediate
	if v, err := parseBinaryImmediate(val[2:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}
func (this *node) parseImmediate(val string) error {
	this.Type = typeImmediate
	if v, err := parseDecimalImmediate(val[1:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}
func (this *node) parseRegister(val string) error {
	this.Type = typeRegister
	if v, err := parseRegisterValue(val[1:]); err != nil {
		return err
	} else {
		this.Value = v
		return nil
	}
}

var directives = map[string]nodeType{
	"data":  typeDirectiveData,
	"code":  typeDirectiveCode,
	"org":   typeDirectiveOrg,
	"word":  typeDirectiveWord,
	"alias": typeDirectiveAlias,
}

func (this *node) parseDirective(val string) error {
	str := val[1:]
	this.Value = str
	if q, ok := directives[str]; ok {
		this.Type = q
	} else {
		this.Type = typeDirective
	}
	return nil
}

func (this *node) parseAlias(str string) error {
	this.Value = str[1:]
	this.Type = typeAlias
	return nil
}

var keywords = map[string]nodeType{
	"branch":     keywordBranch,
	"if0":        keywordIf0,
	"if1":        keywordIf1,
	"then":       keywordThen,
	"else":       keywordElse,
	"link":       keywordLink,
	"add":        keywordAdd,
	"sub":        keywordSub,
	"mul":        keywordMul,
	"div":        keywordDiv,
	"rem":        keywordRem,
	"shiftleft":  keywordShiftLeft,
	"shiftright": keywordShiftRight,
	"and":        keywordAnd,
	"or":         keywordOr,
	"not":        keywordNot,
	"xor":        keywordXor,
	"halve":      keywordHalve,
	"incr":       keywordIncrement,
	"decr":       keywordDecrement,
	"system":     keywordSystem,
	"set":        keywordSet,
	"move":       keywordMove,
	"swap":       keywordSwap,
	"load":       keywordLoad,
	"store":      keywordStore,
}

func (this *node) parseGeneric(str string) error {
	if v, ok := keywords[str]; ok {
		this.Type = v
	}
	return nil
}
func (this *node) Parse() error {
	if this.Type == typeUnknown {
		val := this.Value.(string)
		if val == "=" {
			this.Type = typeEquals
		} else if val == "," {
			this.Type = typeComma
		} else if strings.HasSuffix(val, ":") {
			return this.parseLabel(val)
		} else if strings.HasPrefix(val, ";") {
			this.Type = typeComment
			this.Value = strings.TrimPrefix(val, ";")
		} else if strings.HasPrefix(val, "#x") {
			return this.parseHexImmediate(val)
		} else if strings.HasPrefix(val, "#b") {
			return this.parseBinaryImmediate(val)
		} else if strings.HasPrefix(val, "#") {
			return this.parseImmediate(val)
		} else if strings.HasPrefix(val, "r") {
			return this.parseRegister(val)
		} else if strings.HasPrefix(val, ".") {
			return this.parseDirective(val)
		} else if strings.HasPrefix(val, "?") {
			return this.parseAlias(val)
		} else {
			return this.parseGeneric(val)
		}
	}
	return nil
}

func (this *node) IsComment() bool {
	return this.Type == typeComment
}
func (this *node) IsLabel() bool {
	return this.Type == typeLabel
}

type statement []*node

func (this *statement) Add(value string, t nodeType) {
	// always trim before adding
	str := strings.TrimSpace(value)
	if len(str) > 0 {
		*this = append(*this, &node{Value: str, Type: t})
	}
}
func (this *statement) AddUnknown(value string) {
	this.Add(value, typeUnknown)
}
func (this *statement) String() string {
	var str string
	for _, n := range *this {
		str += fmt.Sprintf(" %T: %s ", n, *n)
	}
	return str
}

func carveLine(line string) statement {
	// trim the damn line first
	data := strings.TrimSpace(line)
	var s statement
	if len(data) == 0 {
		return s
	}
	oldStart := 0
	start := 0
	// skip the strings at the beginning
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRuneInString(data[start:])
		if unicode.IsSpace(r) {
			s.AddUnknown(data[oldStart:start])
			oldStart = start
		} else if r == '=' {
			s.AddUnknown(data[oldStart:start])
			s.Add("=", typeEquals)
			oldStart = start + width
		} else if r == ',' {
			s.AddUnknown(data[oldStart:start])
			s.Add(",", typeComma)
			oldStart = start + width
		} else if r == ';' {
			// consume the rest of the data
			s.AddUnknown(data[oldStart:start])
			// then capture the comment
			s.Add(data[start:], typeComment)
			oldStart = start
			break
		}
	}
	if oldStart < start {
		s.AddUnknown(data[oldStart:])
	}
	return s
}
<|endoftext|>


<commit_before>package iscsi

import (
	"bytes"
	_ "fmt"
	_ "log"
	"os/exec"
	"strings"
)

type ISCSIPlugin struct {
	hosts string
}

func ExecuteCommand(command string, args ...string) (string, string) {
	cmd := exec.Command(command, args...)
	var out bytes.Buffer
	var errMsg bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &errMsg
	err := cmd.Run()
	if err != nil {
		if strings.Contains(err.Error(), "not found") {
			return "", "Command Not Found"
		}
		return "", errMsg.String()
	}
	return out.String(), errMsg.String()
}

func NewISCSIPlugin() ISCSIPlugin {
	return ISCSIPlugin{
		"test1",
	}
}

func (plugin *ISCSIPlugin) CheckIscsiSupport() bool {
	//Check if "iscsiadm" is installed
	_, err := ExecuteCommand("iscsiadm")
	if strings.Contains(err, "Command Not Found") {
		return false
	}
	return true
}

func (plugin *ISCSIPlugin) DiscoverLUNs(host string) error {
	return nil
}

func (plugin *ISCSIPlugin) ListVolumes() error {
	return nil
}

func (plugin *ISCSIPlugin) AddVolumes(volume string) error {
	return nil

}

func (plugin *ISCSIPlugin) DeleteVolumes(volume string) error {
	return nil

}
<commit_msg>comments<commit_after>package iscsi

import (
	"bytes"
	_ "fmt"
	_ "log"
	"os/exec"
	"strings"
)

type ISCSIPlugin struct {
	hosts string
}

func ExecuteCommand(command string, args ...string) (string, string) {
	cmd := exec.Command(command, args...)
	var out bytes.Buffer
	var errMsg bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &errMsg
	err := cmd.Run()
	if err != nil {
		if strings.Contains(err.Error(), "not found") {
			return "", "Command Not Found"
		}
		return "", errMsg.String()
	}
	return out.String(), errMsg.String()
}

func NewISCSIPlugin() ISCSIPlugin {
	return ISCSIPlugin{
		"test1",
	}
}

func (plugin *ISCSIPlugin) CheckIscsiSupport() bool {
	//Check if "iscsiadm" is installed
	_, err := ExecuteCommand("iscsiadm")
	if strings.Contains(err, "Command Not Found") {
		return false
	}
	return true
}

// iscsiadm -m discovery -t sendtargets -p <IP | Target>

func (plugin *ISCSIPlugin) DiscoverLUNs(host string) error {
	return nil
}

// iscsiadm -m node -o show  (Shows discovered list)
func (plugin *ISCSIPlugin) ListVolumes() error {
	return nil
}

func (plugin *ISCSIPlugin) AddVolumes(volume string) error {
	return nil

}

func (plugin *ISCSIPlugin) DeleteVolumes(volume string) error {
	return nil

}

//Login: iscsiadm -m node --login (login on all discovered nodes.)

// iscsiadm -m session -o show  (List current active session)
<|endoftext|>


<commit_before>package octokat

import (
	"github.com/bmizerany/assert"
	"net/http"
	"testing"
	"time"
)

func TestIssues(t *testing.T) {
	setup()
	defer tearDown()

	mux.HandleFunc("/repos/octocat/Hello-World/issues", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		respondWith(w, loadFixture("issues.json"))
	})

	repo := Repo{UserName: "octocat", Name: "Hello-World"}
	issues, _ := client.Issues(repo, nil)

	assert.Equal(t, 1, len(issues))

	issue := issues[0]

	validateIssue(t, issue)

}

func TestIssue(t *testing.T) {
	setup()
	defer tearDown()

	mux.HandleFunc("/repos/octocat/Hello-World/issues/1347", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		respondWith(w, loadFixture("issue.json"))
	})

	repo := Repo{UserName: "octocat", Name: "Hello-World"}
	issue, _ := client.Issue(repo, 1347, nil)

	validateIssue(t, issue)
}

func validateIssue(t *testing.T, issue Issue) {

	assert.Equal(t, "https://api.github.com/repos/octocat/Hello-World/issues/1347", issue.URL)
	assert.Equal(t, "https://github.com/octocat/Hello-World/issues/1347", issue.HTMLURL)
	assert.Equal(t, 1347, issue.Number)
	assert.Equal(t, "open", issue.State)
	assert.Equal(t, "Found a bug", issue.Title)
	assert.Equal(t, "I'm having a problem with this.", issue.Body)

	assert.Equal(t, "octocat", issue.User.Login)
	assert.Equal(t, 1, issue.User.ID)
	assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", issue.User.AvatarURL)
	assert.Equal(t, "somehexcode", issue.User.GravatarID)
	assert.Equal(t, "https://api.github.com/users/octocat", issue.User.URL)

	assert.Equal(t, 1, len(issue.Labels))
	assert.Equal(t, "https://api.github.com/repos/octocat/Hello-World/labels/bug", issue.Labels[0].URL)
	assert.Equal(t, "bug", issue.Labels[0].Name)

	assert.Equal(t, "octocat", issue.Assignee.Login)
	assert.Equal(t, 1, issue.Assignee.ID)
	assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", issue.Assignee.AvatarURL)
	assert.Equal(t, "somehexcode", issue.Assignee.GravatarID)
	assert.Equal(t, "https://api.github.com/users/octocat", issue.Assignee.URL)

	assert.Equal(t, "https://api.github.com/repos/octocat/Hello-World/milestones/1", issue.Milestone.URL)
	assert.Equal(t, 1, issue.Milestone.Number)
	assert.Equal(t, "open", issue.Milestone.State)
	assert.Equal(t, "v1.0", issue.Milestone.Title)
	assert.Equal(t, "", issue.Milestone.Description)

	assert.Equal(t, "octocat", issue.Milestone.Creator.Login)
	assert.Equal(t, 1, issue.Milestone.Creator.ID)
	assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", issue.Milestone.Creator.AvatarURL)
	assert.Equal(t, "somehexcode", issue.Milestone.Creator.GravatarID)
	assert.Equal(t, "https://api.github.com/users/octocat", issue.Milestone.Creator.URL)

	assert.Equal(t, 4, issue.Milestone.OpenIssues)
	assert.Equal(t, 8, issue.Milestone.ClosedIssues)
	assert.Equal(t, "2011-04-10 20:09:31 +0000 UTC", issue.Milestone.CreatedAt.String())
	assert.Equal(t, (*time.Time)(nil), issue.Milestone.DueOn)

	assert.Equal(t, 0, issue.Comments)
	assert.Equal(t, "https://github.com/octocat/Hello-World/pull/1347", issue.PullRequest.HTMLURL)
	assert.Equal(t, "https://github.com/octocat/Hello-World/pull/1347.diff", issue.PullRequest.DiffURL)
	assert.Equal(t, "https://github.com/octocat/Hello-World/pull/1347.patch", issue.PullRequest.PatchURL)

	assert.Equal(t, (*time.Time)(nil), issue.ClosedAt)
	assert.Equal(t, "2011-04-22 13:33:48 +0000 UTC", issue.CreatedAt.String())
	assert.Equal(t, "2011-04-22 13:33:48 +0000 UTC", issue.UpdatedAt.String())

	// phew!
}
<commit_msg>- Fixed the issue's test in order to work with the new prototype<commit_after>package octokat

import (
	"github.com/bmizerany/assert"
	"net/http"
	"testing"
	"time"
)

func TestIssues(t *testing.T) {
	setup()
	defer tearDown()

	mux.HandleFunc("/repos/octocat/Hello-World/issues", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		respondWith(w, loadFixture("issues.json"))
	})

	repo := Repo{UserName: "octocat", Name: "Hello-World"}
	issues, _ := client.Issues(repo, nil)

	assert.Equal(t, 1, len(issues))

	issue := issues[0]

	validateIssue(t, issue)

}

func TestIssue(t *testing.T) {
	setup()
	defer tearDown()

	mux.HandleFunc("/repos/octocat/Hello-World/issues/1347", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		respondWith(w, loadFixture("issue.json"))
	})

	repo := Repo{UserName: "octocat", Name: "Hello-World"}
	issue, _ := client.Issue(repo, 1347, nil)

	validateIssue(t, issue)
}

func validateIssue(t *testing.T, issue *Issue) {

	assert.Equal(t, "https://api.github.com/repos/octocat/Hello-World/issues/1347", issue.URL)
	assert.Equal(t, "https://github.com/octocat/Hello-World/issues/1347", issue.HTMLURL)
	assert.Equal(t, 1347, issue.Number)
	assert.Equal(t, "open", issue.State)
	assert.Equal(t, "Found a bug", issue.Title)
	assert.Equal(t, "I'm having a problem with this.", issue.Body)

	assert.Equal(t, "octocat", issue.User.Login)
	assert.Equal(t, 1, issue.User.ID)
	assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", issue.User.AvatarURL)
	assert.Equal(t, "somehexcode", issue.User.GravatarID)
	assert.Equal(t, "https://api.github.com/users/octocat", issue.User.URL)

	assert.Equal(t, 1, len(issue.Labels))
	assert.Equal(t, "https://api.github.com/repos/octocat/Hello-World/labels/bug", issue.Labels[0].URL)
	assert.Equal(t, "bug", issue.Labels[0].Name)

	assert.Equal(t, "octocat", issue.Assignee.Login)
	assert.Equal(t, 1, issue.Assignee.ID)
	assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", issue.Assignee.AvatarURL)
	assert.Equal(t, "somehexcode", issue.Assignee.GravatarID)
	assert.Equal(t, "https://api.github.com/users/octocat", issue.Assignee.URL)

	assert.Equal(t, "https://api.github.com/repos/octocat/Hello-World/milestones/1", issue.Milestone.URL)
	assert.Equal(t, 1, issue.Milestone.Number)
	assert.Equal(t, "open", issue.Milestone.State)
	assert.Equal(t, "v1.0", issue.Milestone.Title)
	assert.Equal(t, "", issue.Milestone.Description)

	assert.Equal(t, "octocat", issue.Milestone.Creator.Login)
	assert.Equal(t, 1, issue.Milestone.Creator.ID)
	assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", issue.Milestone.Creator.AvatarURL)
	assert.Equal(t, "somehexcode", issue.Milestone.Creator.GravatarID)
	assert.Equal(t, "https://api.github.com/users/octocat", issue.Milestone.Creator.URL)

	assert.Equal(t, 4, issue.Milestone.OpenIssues)
	assert.Equal(t, 8, issue.Milestone.ClosedIssues)
	assert.Equal(t, "2011-04-10 20:09:31 +0000 UTC", issue.Milestone.CreatedAt.String())
	assert.Equal(t, (*time.Time)(nil), issue.Milestone.DueOn)

	assert.Equal(t, 0, issue.Comments)
	assert.Equal(t, "https://github.com/octocat/Hello-World/pull/1347", issue.PullRequest.HTMLURL)
	assert.Equal(t, "https://github.com/octocat/Hello-World/pull/1347.diff", issue.PullRequest.DiffURL)
	assert.Equal(t, "https://github.com/octocat/Hello-World/pull/1347.patch", issue.PullRequest.PatchURL)

	assert.Equal(t, (*time.Time)(nil), issue.ClosedAt)
	assert.Equal(t, "2011-04-22 13:33:48 +0000 UTC", issue.CreatedAt.String())
	assert.Equal(t, "2011-04-22 13:33:48 +0000 UTC", issue.UpdatedAt.String())

	// phew!
}
<|endoftext|>


<commit_before>// UVa 231 - Testing the CATCHER

package main

import (
	"fmt"
	"os"
)

func lds(h []int) int {
	max := 1
	l := len(h)
	m := make([]int, l)
	for i := range m {
		m[i] = 1
	}

	for i := 1; i < l; i++ {
		for j := 0; j < i; j++ {
			if h[i] < h[j] && m[i] <= m[j] {
				m[i] = m[j] + 1
				if max < m[i] {
					max = m[i]
				}
			}
		}
	}
	return max
}

func main() {
	in, _ := os.Open("231.in")
	defer in.Close()
	out, _ := os.Create("231.out")
	defer out.Close()

	var h []int
	var tmp int
	count := 0
	first := true
	for {
		if fmt.Fscanf(in, "%d", &tmp); first && tmp == -1 {
			break
		}
		if first {
			first = false
			count++
		}
		if tmp == -1 {
			if count > 1 {
				fmt.Fprintln(out)
			}
			fmt.Fprintf(out, "Test #%d:\n", count)
			fmt.Fprintf(out, "  maximum possible interceptions: %d\n", lds(h))
			first = true
			h = nil
		} else {
			h = append(h, tmp)
		}
	}
}
<commit_msg>code clean up<commit_after>// UVa 231 - Testing the CATCHER

package main

import (
	"fmt"
	"os"
)

func lds(h []int) int {
	l := len(h)
	m := make([]int, l)
	for i := range m {
		m[i] = 1
	}
	max := 1
	for i := 1; i < l; i++ {
		for j := 0; j < i; j++ {
			if h[i] < h[j] && m[i] <= m[j] {
				m[i] = m[j] + 1
				if max < m[i] {
					max = m[i]
				}
			}
		}
	}
	return max
}

func main() {
	in, _ := os.Open("231.in")
	defer in.Close()
	out, _ := os.Create("231.out")
	defer out.Close()

	var h []int
	var tmp int
	count := 0
	for {
		if fmt.Fscanf(in, "%d", &tmp); tmp == -1 && len(h) == 0 {
			break
		}
		if tmp == -1 {
			if count++; count > 1 {
				fmt.Fprintln(out)
			}
			fmt.Fprintf(out, "Test #%d:\n", count)
			fmt.Fprintf(out, "  maximum possible interceptions: %d\n", lds(h))
			h = nil
		} else {
			h = append(h, tmp)
		}
	}
}
<|endoftext|>


<commit_before>package p2p

import (
	"bufio"
	"fmt"
	"github.com/subutai-io/Subutai/agent/config"
	"github.com/subutai-io/Subutai/agent/log"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

func p2pFile(line string) {
	path := config.Agent.DataPrefix + "/var/subutai-network/"
	file := path + "p2p.txt"
	if _, err := os.Stat(path); os.IsNotExist(err) {
		log.Check(log.FatalLevel, "create "+path+" folder", os.MkdirAll(path, 0755))
	}
	if _, err := os.Stat(file); os.IsNotExist(err) {
		_, err = os.Create(file)
		log.Check(log.FatalLevel, "Creating "+file, err)
	}

	f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0600)
	log.Check(log.FatalLevel, "Opening file for append "+file, err)
	defer f.Close()
	_, err = f.WriteString(line + "\n")
	log.Check(log.FatalLevel, "Opening file for append "+file, err)
}

func Create(interfaceName, localPeepIPAddr, hash, key, ttl string) {
	p2pFile(interfaceName + " " + localPeepIPAddr + " " + key + " " + ttl + " " + hash)
	log.Check(log.FatalLevel, "Creating p2p interface", exec.Command("p2p", "-start", "-key", key, "-dev", interfaceName, "-ip", localPeepIPAddr, "-ttl", ttl, "-hash", hash).Run())
}

func Print() {
	fmt.Println("Interface\tLocalPeerIP\tHash")

	file, err := os.Open(config.Agent.DataPrefix + "/var/subutai-network/p2p.txt")
	if log.Check(log.DebugLevel, "Opening p2p.txt", err) {
		return
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	for scanner.Scan() {
		line := strings.Fields(scanner.Text())
		if len(line) > 4 {
			fmt.Println(line[0] + "\t" + line[1] + "\t" + line[4])
		}
	}
	file.Close()
}

func Remove(hash string) {
	if log.Check(log.WarnLevel, "Removing p2p interface", exec.Command("p2p", "-stop", "-hash", hash).Run()) {
		return
	}

	file, err := os.Open(config.Agent.DataPrefix + "/var/subutai-network/p2p.txt")
	if log.Check(log.WarnLevel, "Opening p2p.txt", err) {
		return
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	newconf := ""
	for scanner.Scan() {
		line := scanner.Text()
		if !strings.HasSuffix(line, hash) {
			newconf = newconf + line + "\n"
		}
	}
	file.Close()
	log.Check(log.FatalLevel, "Removing p2p tunnel", ioutil.WriteFile(config.Agent.DataPrefix+"/var/subutai-network/p2p.txt", []byte(newconf), 0644))
}

func UpdateKey(hash, newkey, ttl string) {
	err := exec.Command("p2p", "-add-key", "-key", newkey, "-ttl", ttl, "-hash", hash).Run()
	log.Check(log.FatalLevel, "Updating p2p key: ", err)
}

func Peers(hash string) {
	out, err := exec.Command("p2p", "-show", hash).Output()
	log.Check(log.FatalLevel, "Getting list of p2p participants", err)
	fmt.Println(string(out))
}
<commit_msg>Updated p2p execution to new flags model.<commit_after>package p2p

import (
	"bufio"
	"fmt"
	"github.com/subutai-io/Subutai/agent/config"
	"github.com/subutai-io/Subutai/agent/log"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

func p2pFile(line string) {
	path := config.Agent.DataPrefix + "/var/subutai-network/"
	file := path + "p2p.txt"
	if _, err := os.Stat(path); os.IsNotExist(err) {
		log.Check(log.FatalLevel, "create "+path+" folder", os.MkdirAll(path, 0755))
	}
	if _, err := os.Stat(file); os.IsNotExist(err) {
		_, err = os.Create(file)
		log.Check(log.FatalLevel, "Creating "+file, err)
	}

	f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0600)
	log.Check(log.FatalLevel, "Opening file for append "+file, err)
	defer f.Close()
	_, err = f.WriteString(line + "\n")
	log.Check(log.FatalLevel, "Opening file for append "+file, err)
}

func Create(interfaceName, localPeepIPAddr, hash, key, ttl string) {
	p2pFile(interfaceName + " " + localPeepIPAddr + " " + key + " " + ttl + " " + hash)
	log.Check(log.FatalLevel, "Creating p2p interface", exec.Command("p2p", "start", "-key", key, "-dev", interfaceName, "-ip", localPeepIPAddr, "-ttl", ttl, "-hash", hash).Run())
}

func Print() {
	fmt.Println("Interface\tLocalPeerIP\tHash")

	file, err := os.Open(config.Agent.DataPrefix + "/var/subutai-network/p2p.txt")
	if log.Check(log.DebugLevel, "Opening p2p.txt", err) {
		return
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	for scanner.Scan() {
		line := strings.Fields(scanner.Text())
		if len(line) > 4 {
			fmt.Println(line[0] + "\t" + line[1] + "\t" + line[4])
		}
	}
	file.Close()
}

func Remove(hash string) {
	if log.Check(log.WarnLevel, "Removing p2p interface", exec.Command("p2p", "stop", "-hash", hash).Run()) {
		return
	}

	file, err := os.Open(config.Agent.DataPrefix + "/var/subutai-network/p2p.txt")
	if log.Check(log.WarnLevel, "Opening p2p.txt", err) {
		return
	}
	scanner := bufio.NewScanner(bufio.NewReader(file))
	newconf := ""
	for scanner.Scan() {
		line := scanner.Text()
		if !strings.HasSuffix(line, hash) {
			newconf = newconf + line + "\n"
		}
	}
	file.Close()
	log.Check(log.FatalLevel, "Removing p2p tunnel", ioutil.WriteFile(config.Agent.DataPrefix+"/var/subutai-network/p2p.txt", []byte(newconf), 0644))
}

func UpdateKey(hash, newkey, ttl string) {
	err := exec.Command("p2p", "set", "-key", newkey, "-ttl", ttl, "-hash", hash).Run()
	log.Check(log.FatalLevel, "Updating p2p key: ", err)
}

func Peers(hash string) {
	out, err := exec.Command("p2p", "show", hash).Output()
	log.Check(log.FatalLevel, "Getting list of p2p participants", err)
	fmt.Println(string(out))
}
<|endoftext|>


<commit_before>// This packages contains an interface for accessing other processes' memory.
package memaccess

import "fmt"

// Creates a new ProcessMemoryReader for a given process.
func NewProcessMemoryReader(pid uint) (reader ProcessMemoryReader, harderror error, softerrors []error) {
	return newProcessMemoryReaderImpl(pid)
}

// This interface is used to access a process memory. For getting an instance
// of a type implementing it you must call NewProcessMemoryReader function.
type ProcessMemoryReader interface {
	// Frees the resources attached to this interface.
	Close() (harderror error, softerrors []error)

	// Returns a memory region containing address, or the next readable region
	// after address in case addresss is not in a readable region.
	//
	// If there aren't more regions available the special value
	// NoRegionAvailable is returned.
	NextReadableMemoryRegion(address uintptr) (region MemoryRegion, harderror error, softerrors []error)

	// Fills the entire buffer with memory from the process starting in address (in the process address space).
	// If there is not enough memory to read it returns a hard error. Note that this is not the only hard error it may
	// return though.
	CopyMemory(address uintptr, buffer []byte) (harderror error, softerrors []error)
}

// This struct represents a region of readable contiguos memory of a process.
//
// No readable memory can be available right next to this region, it's maximal
// in its upper bound.
//
// Note that this region is not necessary equivalent to the OS's region, if any.
type MemoryRegion struct {
	Address uintptr
	Size    uint
}

func (m MemoryRegion) String() string {
	return fmt.Sprintf("MemoryRegion[%x-%x)", m.Address, m.Address+uintptr(m.Size))
}

// A centinel value indicating that there is no more regions available.
var NoRegionAvailable MemoryRegion

// This type represents a function used for walking through the memory, see
// WalkMemory for more details.
type WalkFunc func(address uintptr, buf []byte) (keepSearching bool)

// WalkMemory reads all the memory of a process starting at a given address
// reading upto bufSize bytes into a buffer, and calling walkFn with the buffer
// and the start address of the memory in the buffer. If walkFn returns false
// WalkMemory stop reading the memory.
func WalkMemory(reader ProcessMemoryReader, startAddress uintptr, bufSize uint, walkFn WalkFunc) (harderror error,
	softerrors []error) {

	var region MemoryRegion
	region, harderror, softerrors = reader.NextReadableMemoryRegion(startAddress)
	if harderror != nil {
		return
	}

	const max_retries int = 5

	buf := make([]byte, bufSize)
	retries := max_retries

	for region != NoRegionAvailable {

		keepWalking, addr, err, serrs := walkRegion(reader, region, buf, walkFn)
		softerrors = append(softerrors, serrs...)

		if err != nil && retries > 0 {
			// An error occurred: retry using the nearest region to the address that failed.
			retries--
			region, harderror, serrs = reader.NextReadableMemoryRegion(addr)
			softerrors = append(softerrors, serrs...)
			if harderror != nil {
				return
			}

			// if some chunk of this new region was already read we don't want to read it again.
			if region.Address < addr {
				region.Address = addr
			}

			continue
		} else if err != nil {
			// we have exceeded our retries, mark the error as soft error and keep going.
			softerrors = append(softerrors, err)
		} else if !keepWalking {
			return
		}

		region, harderror, serrs = reader.NextReadableMemoryRegion(region.Address + uintptr(region.Size))
		softerrors = append(softerrors, serrs...)
		if harderror != nil {
			return
		}
		retries = max_retries
	}
	return
}

// This function walks through a single memory region calling walkFunc with a given buffer. It always fills as much of
// the buffer as possible before calling walkFunc, but it never calls it with overlaped memory sections.
//
// If the buffer cannot be filled a hard error is returned with the starting address of the chunk of memory that could
// not be read. If no harderror is returned errorAddress must be ignored.
//
// If any of the calls to walkFn returns false, this function inmediatly returns, with keepWalking set to false and no
// hard error.
func walkRegion(reader ProcessMemoryReader, region MemoryRegion, buf []byte, walkFn WalkFunc) (keepWalking bool,
	errorAddress uintptr, harderror error, softerrors []error) {

	softerrors = make([]error, 0)
	keepWalking = true

	remaningBytes := uintptr(region.Size)
	for addr := region.Address; remaningBytes > 0; addr += uintptr(len(buf)) {
		err, serrs := reader.CopyMemory(addr, buf)
		softerrors = append(softerrors, serrs...)

		if err != nil {
			harderror = err
			errorAddress = addr
			return
		}

		keepWalking = walkFn(addr, buf)
		if !keepWalking {
			return
		}

		remaningBytes -= uintptr(len(buf))
		if remaningBytes < uintptr(len(buf)) {
			buf = buf[:remaningBytes]
		}
	}

	return
}
<commit_msg>[memaccess] Improve WalkMemory error reporting<commit_after>// This packages contains an interface for accessing other processes' memory.
package memaccess

import "fmt"

// Creates a new ProcessMemoryReader for a given process.
func NewProcessMemoryReader(pid uint) (reader ProcessMemoryReader, harderror error, softerrors []error) {
	return newProcessMemoryReaderImpl(pid)
}

// This interface is used to access a process memory. For getting an instance
// of a type implementing it you must call NewProcessMemoryReader function.
type ProcessMemoryReader interface {
	// Frees the resources attached to this interface.
	Close() (harderror error, softerrors []error)

	// Returns a memory region containing address, or the next readable region
	// after address in case addresss is not in a readable region.
	//
	// If there aren't more regions available the special value
	// NoRegionAvailable is returned.
	NextReadableMemoryRegion(address uintptr) (region MemoryRegion, harderror error, softerrors []error)

	// Fills the entire buffer with memory from the process starting in address (in the process address space).
	// If there is not enough memory to read it returns a hard error. Note that this is not the only hard error it may
	// return though.
	CopyMemory(address uintptr, buffer []byte) (harderror error, softerrors []error)
}

// This struct represents a region of readable contiguos memory of a process.
//
// No readable memory can be available right next to this region, it's maximal
// in its upper bound.
//
// Note that this region is not necessary equivalent to the OS's region, if any.
type MemoryRegion struct {
	Address uintptr
	Size    uint
}

func (m MemoryRegion) String() string {
	return fmt.Sprintf("MemoryRegion[%x-%x)", m.Address, m.Address+uintptr(m.Size))
}

// A centinel value indicating that there is no more regions available.
var NoRegionAvailable MemoryRegion

// This type represents a function used for walking through the memory, see
// WalkMemory for more details.
type WalkFunc func(address uintptr, buf []byte) (keepSearching bool)

// WalkMemory reads all the memory of a process starting at a given address
// reading upto bufSize bytes into a buffer, and calling walkFn with the buffer
// and the start address of the memory in the buffer. If walkFn returns false
// WalkMemory stop reading the memory.
func WalkMemory(reader ProcessMemoryReader, startAddress uintptr, bufSize uint, walkFn WalkFunc) (harderror error,
	softerrors []error) {

	var region MemoryRegion
	region, harderror, softerrors = reader.NextReadableMemoryRegion(startAddress)
	if harderror != nil {
		return
	}

	const max_retries int = 5

	buf := make([]byte, bufSize)
	retries := max_retries

	for region != NoRegionAvailable {

		keepWalking, addr, err, serrs := walkRegion(reader, region, buf, walkFn)
		softerrors = append(softerrors, serrs...)

		if err != nil && retries > 0 {
			// An error occurred: retry using the nearest region to the address that failed.
			retries--
			region, harderror, serrs = reader.NextReadableMemoryRegion(addr)
			softerrors = append(softerrors, serrs...)
			if harderror != nil {
				return
			}

			// if some chunk of this new region was already read we don't want to read it again.
			if region.Address < addr {
				region.Address = addr
			}

			continue
		} else if err != nil {
			// we have exceeded our retries, mark the error as soft error and keep going.
			softerrors = append(softerrors, fmt.Errorf("Retries exceeded on reading %d bytes starting at %x: %s",
				len(buf), addr, err.Error()))
		} else if !keepWalking {
			return
		}

		region, harderror, serrs = reader.NextReadableMemoryRegion(region.Address + uintptr(region.Size))
		softerrors = append(softerrors, serrs...)
		if harderror != nil {
			return
		}
		retries = max_retries
	}
	return
}

// This function walks through a single memory region calling walkFunc with a given buffer. It always fills as much of
// the buffer as possible before calling walkFunc, but it never calls it with overlaped memory sections.
//
// If the buffer cannot be filled a hard error is returned with the starting address of the chunk of memory that could
// not be read. If no harderror is returned errorAddress must be ignored.
//
// If any of the calls to walkFn returns false, this function inmediatly returns, with keepWalking set to false and no
// hard error.
func walkRegion(reader ProcessMemoryReader, region MemoryRegion, buf []byte, walkFn WalkFunc) (keepWalking bool,
	errorAddress uintptr, harderror error, softerrors []error) {

	softerrors = make([]error, 0)
	keepWalking = true

	remaningBytes := uintptr(region.Size)
	for addr := region.Address; remaningBytes > 0; addr += uintptr(len(buf)) {
		err, serrs := reader.CopyMemory(addr, buf)
		softerrors = append(softerrors, serrs...)

		if err != nil {
			harderror = err
			errorAddress = addr
			return
		}

		keepWalking = walkFn(addr, buf)
		if !keepWalking {
			return
		}

		remaningBytes -= uintptr(len(buf))
		if remaningBytes < uintptr(len(buf)) {
			buf = buf[:remaningBytes]
		}
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"xorkevin.dev/governor"
	"xorkevin.dev/governor/service/courier"
	"xorkevin.dev/governor/service/courier/model"
	"xorkevin.dev/governor/service/db"
	"xorkevin.dev/governor/service/kvstore"
	"xorkevin.dev/governor/service/mail"
	"xorkevin.dev/governor/service/msgqueue"
	"xorkevin.dev/governor/service/objstore"
	"xorkevin.dev/governor/service/profile"
	"xorkevin.dev/governor/service/profile/model"
	"xorkevin.dev/governor/service/pubsub"
	"xorkevin.dev/governor/service/state/model"
	"xorkevin.dev/governor/service/template"
	"xorkevin.dev/governor/service/user"
	"xorkevin.dev/governor/service/user/apikey"
	"xorkevin.dev/governor/service/user/apikey/model"
	"xorkevin.dev/governor/service/user/approval/model"
	"xorkevin.dev/governor/service/user/gate"
	"xorkevin.dev/governor/service/user/model"
	"xorkevin.dev/governor/service/user/oauth"
	"xorkevin.dev/governor/service/user/oauth/connection/model"
	"xorkevin.dev/governor/service/user/oauth/model"
	"xorkevin.dev/governor/service/user/role"
	"xorkevin.dev/governor/service/user/role/model"
	"xorkevin.dev/governor/service/user/session/model"
	"xorkevin.dev/governor/service/user/token"
)

var (
	// GitHash is the git hash to be passed in at compile time
	GitHash string
)

func main() {
	opts := governor.Opts{
		Version: governor.Version{
			Num:  "v0.3",
			Hash: GitHash,
		},
		Appname:       "governor",
		Description:   "Governor is a web server with user and auth capabilities",
		DefaultFile:   "config",
		ClientDefault: "client",
		ClientPrefix:  "govc",
		EnvPrefix:     "gov",
	}

	dbService := db.New()
	stateService := statemodel.New(dbService)

	gov := governor.New(opts, stateService)

	kvService := kvstore.New()
	objstoreService := objstore.New()
	msgqueueService := msgqueue.New()
	pubsubService := pubsub.New()
	templateService := template.New()
	mailService := mail.New(templateService, msgqueueService)
	roleModel := rolemodel.New(dbService)
	roleService := role.New(roleModel, kvService.Subtree("roles"))
	apikeyModel := apikeymodel.New(dbService)
	apikeyService := apikey.New(apikeyModel, kvService.Subtree("apikeys"))
	tokenService := token.New()
	gateService := gate.New(roleService, apikeyService, tokenService)
	userModel := usermodel.New(dbService)
	sessionModel := sessionmodel.New(dbService)
	approvalModel := approvalmodel.New(dbService)
	userService := user.New(userModel, sessionModel, approvalModel, roleService, apikeyService, kvService.Subtree("user"), msgqueueService, mailService, tokenService, gateService)
	oauthModel := oauthmodel.New(dbService)
	oauthConnectionModel := connectionmodel.NewRepo(dbService)
	oauthService := oauth.New(oauthModel, oauthConnectionModel, tokenService, objstoreService.GetBucket("oauth-app-logo"), kvService.Subtree("oauth"), gateService)
	profileModel := profilemodel.New(dbService)
	profileService := profile.New(profileModel, objstoreService.GetBucket("profile-image"), msgqueueService, gateService)
	courierModel := couriermodel.New(dbService)
	courierService := courier.New(courierModel, objstoreService.GetBucket("link-qr-image"), kvService.Subtree("courier"), gateService)

	gov.Register("database", "/null/db", dbService)
	gov.Register("kvstore", "/null/kv", kvService)
	gov.Register("objstore", "/null/obj", objstoreService)
	gov.Register("msgqueue", "/null/msg", msgqueueService)
	gov.Register("pubsub", "/null/pubsub", pubsubService)
	gov.Register("template", "/null/tpl", templateService)
	gov.Register("mail", "/null/mail", mailService)
	gov.Register("role", "/null/role", roleService)
	gov.Register("apikey", "/null/apikey", apikeyService)
	gov.Register("token", "/null/token", tokenService)
	gov.Register("gate", "/null/gate", gateService)
	gov.Register("user", "/u", userService)
	gov.Register("oauth", "/oauth", oauthService)
	gov.Register("profile", "/profile", profileService)
	gov.Register("courier", "/courier", courierService)

	cmd := governor.NewCmd(opts, gov, governor.NewClient(opts))
	cmd.Execute()
}
<commit_msg>Add org service to example<commit_after>package main

import (
	"xorkevin.dev/governor"
	"xorkevin.dev/governor/service/courier"
	"xorkevin.dev/governor/service/courier/model"
	"xorkevin.dev/governor/service/db"
	"xorkevin.dev/governor/service/kvstore"
	"xorkevin.dev/governor/service/mail"
	"xorkevin.dev/governor/service/msgqueue"
	"xorkevin.dev/governor/service/objstore"
	"xorkevin.dev/governor/service/profile"
	"xorkevin.dev/governor/service/profile/model"
	"xorkevin.dev/governor/service/pubsub"
	"xorkevin.dev/governor/service/state/model"
	"xorkevin.dev/governor/service/template"
	"xorkevin.dev/governor/service/user"
	"xorkevin.dev/governor/service/user/apikey"
	"xorkevin.dev/governor/service/user/apikey/model"
	"xorkevin.dev/governor/service/user/approval/model"
	"xorkevin.dev/governor/service/user/gate"
	"xorkevin.dev/governor/service/user/model"
	"xorkevin.dev/governor/service/user/oauth"
	"xorkevin.dev/governor/service/user/oauth/connection/model"
	"xorkevin.dev/governor/service/user/oauth/model"
	"xorkevin.dev/governor/service/user/org"
	"xorkevin.dev/governor/service/user/org/model"
	"xorkevin.dev/governor/service/user/role"
	"xorkevin.dev/governor/service/user/role/model"
	"xorkevin.dev/governor/service/user/session/model"
	"xorkevin.dev/governor/service/user/token"
)

var (
	// GitHash is the git hash to be passed in at compile time
	GitHash string
)

func main() {
	opts := governor.Opts{
		Version: governor.Version{
			Num:  "v0.3",
			Hash: GitHash,
		},
		Appname:       "governor",
		Description:   "Governor is a web server with user and auth capabilities",
		DefaultFile:   "config",
		ClientDefault: "client",
		ClientPrefix:  "govc",
		EnvPrefix:     "gov",
	}

	dbService := db.New()
	stateService := statemodel.New(dbService)

	gov := governor.New(opts, stateService)

	kvService := kvstore.New()
	objstoreService := objstore.New()
	msgqueueService := msgqueue.New()
	pubsubService := pubsub.New()
	templateService := template.New()
	mailService := mail.New(templateService, msgqueueService)
	roleModel := rolemodel.New(dbService)
	roleService := role.New(roleModel, kvService.Subtree("roles"))
	apikeyModel := apikeymodel.New(dbService)
	apikeyService := apikey.New(apikeyModel, kvService.Subtree("apikeys"))
	tokenService := token.New()
	gateService := gate.New(roleService, apikeyService, tokenService)
	userModel := usermodel.New(dbService)
	sessionModel := sessionmodel.New(dbService)
	approvalModel := approvalmodel.New(dbService)
	userService := user.New(userModel, sessionModel, approvalModel, roleService, apikeyService, kvService.Subtree("user"), msgqueueService, mailService, tokenService, gateService)
	orgModel := orgmodel.New(dbService)
	orgService := org.New(orgModel, roleService, gateService)
	oauthModel := oauthmodel.New(dbService)
	oauthConnectionModel := connectionmodel.NewRepo(dbService)
	oauthService := oauth.New(oauthModel, oauthConnectionModel, tokenService, objstoreService.GetBucket("oauth-app-logo"), kvService.Subtree("oauth"), gateService)
	profileModel := profilemodel.New(dbService)
	profileService := profile.New(profileModel, objstoreService.GetBucket("profile-image"), msgqueueService, gateService)
	courierModel := couriermodel.New(dbService)
	courierService := courier.New(courierModel, objstoreService.GetBucket("link-qr-image"), kvService.Subtree("courier"), gateService)

	gov.Register("database", "/null/db", dbService)
	gov.Register("kvstore", "/null/kv", kvService)
	gov.Register("objstore", "/null/obj", objstoreService)
	gov.Register("msgqueue", "/null/msg", msgqueueService)
	gov.Register("pubsub", "/null/pubsub", pubsubService)
	gov.Register("template", "/null/tpl", templateService)
	gov.Register("mail", "/null/mail", mailService)
	gov.Register("role", "/null/role", roleService)
	gov.Register("apikey", "/null/apikey", apikeyService)
	gov.Register("token", "/null/token", tokenService)
	gov.Register("gate", "/null/gate", gateService)
	gov.Register("user", "/u", userService)
	gov.Register("org", "/org", orgService)
	gov.Register("oauth", "/oauth", oauthService)
	gov.Register("profile", "/profile", profileService)
	gov.Register("courier", "/courier", courierService)

	cmd := governor.NewCmd(opts, gov, governor.NewClient(opts))
	cmd.Execute()
}
<|endoftext|>