<commit_before>package main

import (
	"fmt"
	"net/http"
	"os"
	"time"

	"log"

	"github.com/Sirupsen/logrus"
	"github.com/anthonynsimon/parrot/api"
	"github.com/anthonynsimon/parrot/datastore"
	"github.com/joho/godotenv"
)

func init() {
	// Config log
	logrus.SetFormatter(&logrus.TextFormatter{})
}

func main() {
	// init environment variables
	err := godotenv.Load()
	if err != nil {
		log.Fatal(err)
	}

	// init and ping datastore
	ds, err := initDatastore()
	if err != nil {
		log.Fatal(err)
	}
	defer ds.Close()
	if err = ds.Ping(); err != nil {
		log.Fatal(err)
	}

	// init api
	apiRouter := api.Handler(ds)

	// config server
	addr := "localhost:8080"

	// init server
	s := &http.Server{
		Addr:           addr,
		Handler:        apiRouter,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	fmt.Println(fmt.Sprintf("Listening on %s", addr))

	log.Fatal(s.ListenAndServe())
}

func initDatastore() (*datastore.Datastore, error) {
	name := os.Getenv("DB")
	url := os.Getenv("DB_URL")

	ds, err := datastore.NewDatastore(name, url)
	if err != nil {
		return nil, err
	}

	return ds, nil
}
<commit_msg>Conform log usage<commit_after>package main

import (
	"fmt"
	"net/http"
	"os"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/anthonynsimon/parrot/api"
	"github.com/anthonynsimon/parrot/datastore"
	"github.com/joho/godotenv"
)

func init() {
	// Config log
	log.SetFormatter(&log.TextFormatter{})
}

func main() {
	// init environment variables
	err := godotenv.Load()
	if err != nil {
		log.Fatal(err)
	}

	// init and ping datastore
	ds, err := initDatastore()
	if err != nil {
		log.Fatal(err)
	}
	defer ds.Close()
	if err = ds.Ping(); err != nil {
		log.Fatal(err)
	}

	// init api
	apiRouter := api.Handler(ds)

	// config server
	addr := "localhost:8080"

	// init server
	s := &http.Server{
		Addr:           addr,
		Handler:        apiRouter,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	fmt.Println(fmt.Sprintf("Listening on %s", addr))

	log.Fatal(s.ListenAndServe())
}

func initDatastore() (*datastore.Datastore, error) {
	name := os.Getenv("DB")
	url := os.Getenv("DB_URL")

	ds, err := datastore.NewDatastore(name, url)
	if err != nil {
		return nil, err
	}

	return ds, nil
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"encoding/base64"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
)

var (
	proxy    string
	user     string
	password string
	dest     string
)

func main() {

	flag.StringVar(&proxy, "proxy", "", "provide proxy URL: IP:PORT")
	flag.StringVar(&user, "user", "", "provide proxy user")
	flag.StringVar(&password, "password", "", "provide proxy password")
	flag.StringVar(&dest, "dest", "", "provide URL to access")
	flag.Parse()

	req, _ := http.NewRequest("GET", dest, nil)
	//req.Header.Set("Host", "www.google.com.br")

	proxyURL := url.URL{
		Scheme: "https",
		Host:   proxy}

	transport := &http.Transport{
		Proxy:           http.ProxyURL(&proxyURL),
		TLSClientConfig: &tls.Config{},
	}
	client := &http.Client{Transport: transport}
	req.RequestURI = ""

	auth := fmt.Sprintf("%s:%s", user, password)
	basic := "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
	req.Header.Add("Proxy-Authorization", basic)

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("erro: %s", err)
	}
	fmt.Printf("code: %s", resp.StatusCode)
	htmlData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(os.Stdout, string(htmlData))
}
<commit_msg>add return in error<commit_after>package main

import (
	"crypto/tls"
	"encoding/base64"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
)

var (
	proxy    string
	user     string
	password string
	dest     string
)

func main() {

	flag.StringVar(&proxy, "proxy", "", "provide proxy URL: IP:PORT")
	flag.StringVar(&user, "user", "", "provide proxy user")
	flag.StringVar(&password, "password", "", "provide proxy password")
	flag.StringVar(&dest, "dest", "", "provide URL to access")
	flag.Parse()

	req, _ := http.NewRequest("GET", dest, nil)
	//req.Header.Set("Host", "www.google.com.br")

	proxyURL := url.URL{
		Scheme: "https",
		Host:   proxy}

	transport := &http.Transport{
		Proxy:           http.ProxyURL(&proxyURL),
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: transport}
	req.RequestURI = ""

	auth := fmt.Sprintf("%s:%s", user, password)
	basic := "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
	req.Header.Add("Proxy-Authorization", basic)

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("erro: %s", err)
		return
	}
	fmt.Printf("code: %s", resp.StatusCode)
	htmlData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(os.Stdout, string(htmlData))
}
<|endoftext|>


<commit_before>package bytepool

import (
  "io"
)

type Item struct {
  pool *Pool
  length int
  read int
  bytes []byte
}

func newItem(capacity int, pool *Pool) *Item {
  return &Item {
    pool: pool,
    bytes: make([]byte, capacity),
  }
}

func (item *Item) Write(b []byte) (int, error) {
  if item.Full() { return 0, io.ErrShortWrite }
  n := copy(item.bytes[item.length:], b)
  item.length += n
  return n, nil
}

func (item *Item) WriteByte(b byte) bool {
  if item.Full() { return false }
  item.bytes[item.length] = b
  item.length += 1
  return true
}

func (item *Item) WriteString(s string) int {
  if item.Full() { return 0 }
  n := copy(item.bytes[item.length:], s)
  item.length += n
  return n
}

func (item *Item) ReadFrom(reader io.Reader) (int64, error) {
  var read int64
  for {
    r, err := reader.Read(item.bytes[item.length:])
    read += int64(r)
    item.length += r
    if err == io.EOF || item.Full() { return read, nil }
    if err != nil { return read, err }
  }
}

func (item *Item) Read(p []byte) (int, error) {
  if item.Drained() { return 0, io.EOF }
  n := copy(p, item.bytes[item.read:item.length])
  item.read += n
  if item.Drained() { return n, io.EOF }
  return n, nil
}

func (item *Item) Bytes() []byte {
  return item.bytes[0:item.length]
}

func (item *Item) String() string {
  return string(item.Bytes())
}

func (item *Item) Len() int {
  return item.length;
}

func (item *Item) Position(position int) bool {
  if position < 0 || position > cap(item.bytes){
    return false
  }
  item.length = position
  return true
}

func (item *Item) Full() bool {
  return item.length == cap(item.bytes)
}

func (item *Item) Drained() bool {
  return item.length == item.read
}

func (item *Item) Close() error{
  item.length = 0
  item.read = 0
  if item.pool != nil {
    item.pool.list <- item
  }
  return nil
}
<commit_msg>expose the full byte array (.Raw())<commit_after>package bytepool

import (
  "io"
)

type Item struct {
  pool *Pool
  length int
  read int
  bytes []byte
}

func newItem(capacity int, pool *Pool) *Item {
  return &Item {
    pool: pool,
    bytes: make([]byte, capacity),
  }
}

func (item *Item) Write(b []byte) (int, error) {
  if item.Full() { return 0, io.ErrShortWrite }
  n := copy(item.bytes[item.length:], b)
  item.length += n
  return n, nil
}

func (item *Item) WriteByte(b byte) bool {
  if item.Full() { return false }
  item.bytes[item.length] = b
  item.length += 1
  return true
}

func (item *Item) WriteString(s string) int {
  if item.Full() { return 0 }
  n := copy(item.bytes[item.length:], s)
  item.length += n
  return n
}

func (item *Item) ReadFrom(reader io.Reader) (int64, error) {
  var read int64
  for {
    r, err := reader.Read(item.bytes[item.length:])
    read += int64(r)
    item.length += r
    if err == io.EOF || item.Full() { return read, nil }
    if err != nil { return read, err }
  }
}

func (item *Item) Read(p []byte) (int, error) {
  if item.Drained() { return 0, io.EOF }
  n := copy(p, item.bytes[item.read:item.length])
  item.read += n
  if item.Drained() { return n, io.EOF }
  return n, nil
}

func (item *Item) Bytes() []byte {
  return item.bytes[0:item.length]
}

func (item *Item) Raw() []byte {
  return item.bytes
}

func (item *Item) String() string {
  return string(item.Bytes())
}

func (item *Item) Len() int {
  return item.length;
}

func (item *Item) Position(position int) bool {
  if position < 0 || position > cap(item.bytes){
    return false
  }
  item.length = position
  return true
}

func (item *Item) Full() bool {
  return item.length == cap(item.bytes)
}

func (item *Item) Drained() bool {
  return item.length == item.read
}

func (item *Item) Close() error{
  item.length = 0
  item.read = 0
  if item.pool != nil {
    item.pool.list <- item
  }
  return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"
	"syscall"
	"unsafe"
)

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

var origTermios *Termios

func TcSetAttr(fd uintptr, termios *Termios) error {
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) (*Termios, error) {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		return nil, err
	}
	return termios, nil
}

func enableRawMode() {
	origTermios, _ = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *origTermios
	raw.Iflag &^= syscall.IXON | syscall.ICRNL
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		fmt.Fprintf(os.Stderr, "Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), origTermios); e != nil {
		fmt.Fprintf(os.Stderr, "Problem disabling raw mode: %s\n", e)
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	buffer := make([]byte, 1)
	for cc, err := os.Stdin.Read(buffer); buffer[0] != 'q' && err == nil && cc == 1; cc, err = os.Stdin.Read(buffer) {
		var r rune
		r = rune(buffer[0])
		if (strconv.IsPrint(r)) {
			fmt.Printf("%d  %c\n", buffer[0], r)
		} else {
			fmt.Printf("%d\n", buffer[0])
		}
	}
}
<commit_msg>Step 13, turn off OPOST, output processing<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"
	"syscall"
	"unsafe"
)

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

var origTermios *Termios

func TcSetAttr(fd uintptr, termios *Termios) error {
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) (*Termios, error) {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		return nil, err
	}
	return termios, nil
}

func enableRawMode() {
	origTermios, _ = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *origTermios
	raw.Iflag &^= syscall.IXON | syscall.ICRNL
	raw.Oflag &^= syscall.OPOST
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		fmt.Fprintf(os.Stderr, "Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), origTermios); e != nil {
		fmt.Fprintf(os.Stderr, "Problem disabling raw mode: %s\n", e)
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	buffer := make([]byte, 1)
	for cc, err := os.Stdin.Read(buffer); buffer[0] != 'q' && err == nil && cc == 1; cc, err = os.Stdin.Read(buffer) {
		var r rune
		r = rune(buffer[0])
		if (strconv.IsPrint(r)) {
			fmt.Printf("%d  %c\n", buffer[0], r)
		} else {
			fmt.Printf("%d\n", buffer[0])
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type lead struct {
	Id                 bson.ObjectId `bson:"_id"`
	Contact            *mgo.DBRef    `bson:"contact,omitempty"`
	Source             string        `bson:"source,omitempty"`
	Owner              string        `bson:"owner,omitempty"`
	Status             string        `bson:"status,omitempty"`
	TeamSize           float         `bson:"teamsize,omitempty"`
	RatePerHour        float         `bson:"rateperhour,omitempty"`
	DurationInMonths   float         `bson:"durationinmonths,omitempty"`
	EstimatedStartDate string        `bson:"estimatedstartdate,omitempty"`
	//Here we choose not to use time.Time because omitempty isn't supported for time.Time
	Comments []string `bson:"comments,omitempty"`
}

// NewLead takes the fields of a lead, initializes a struct of lead type and returns
// the pointer to that struct.
// Also, It inserts the lead data into a mongoDB collection, which is passed as the first parameter.
func NewLead(c *mgo.Collection, r *mgo.DBRef, source, owner, status,
	teamsize, rate, duration, start string, comments []string) (*lead, error) {

	doc := lead{
		Id:                 bson.NewObjectId(),
		Contact:            r,
		Source:             source,
		Owner:              owner,
		Status:             status,
		TeamSize:           teamsize,
		RatePerHour:        rate,
		DurationInMonths:   duration,
		EstimatedStartDate: start,
		Comments:           comments,
	}
	err := c.Insert(doc)
	if err != nil {
		return &lead{}, err
	}
	return &doc, nil
}
<commit_msg>Correct types<commit_after>package main

import (
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type lead struct {
	Id                 bson.ObjectId `bson:"_id"`
	Contact            *mgo.DBRef    `bson:"contact,omitempty"`
	Source             string        `bson:"source,omitempty"`
	Owner              string        `bson:"owner,omitempty"`
	Status             string        `bson:"status,omitempty"`
	TeamSize           float64       `bson:"teamsize,omitempty"`
	RatePerHour        float64       `bson:"rateperhour,omitempty"`
	DurationInMonths   float64       `bson:"durationinmonths,omitempty"`
	EstimatedStartDate string        `bson:"estimatedstartdate,omitempty"`
	//Here we choose not to use time.Time because omitempty isn't supported for time.Time
	Comments []string `bson:"comments,omitempty"`
}

// NewLead takes the fields of a lead, initializes a struct of lead type and returns
// the pointer to that struct.
// Also, It inserts the lead data into a mongoDB collection, which is passed as the first parameter.
func NewLead(c *mgo.Collection, r *mgo.DBRef, source, owner, status string,
	teamsize, rate, duration float64, start string, comments []string) (*lead, error) {

	doc := lead{
		Id:                 bson.NewObjectId(),
		Contact:            r,
		Source:             source,
		Owner:              owner,
		Status:             status,
		TeamSize:           teamsize,
		RatePerHour:        rate,
		DurationInMonths:   duration,
		EstimatedStartDate: start,
		Comments:           comments,
	}
	err := c.Insert(doc)
	if err != nil {
		return &lead{}, err
	}
	return &doc, nil
}
<|endoftext|>


<commit_before>package life

import (
	"sync"
)

//Life handles the creation of the background thread and shutdown management
type Life struct {
	wg   *sync.WaitGroup
	Done chan struct{}
	run  func()
	once *sync.Once
}

//NewLife creates life with the expected defaults
func NewLife() *Life {
	return &Life{wg: &sync.WaitGroup{}, Done: make(chan struct{}, 10), once: &sync.Once{}}
}

//Start the background thread.
func (l Life) Start() {
	l.once.Do(func() {
		l.wg.Add(1)
		go l.run()
	})

}

//SetRun will set the run function that will be called by Start.
func (l *Life) SetRun(f func()) {
	l.run = f
}

//WGAdd will add to lifes waitgroup.
func (l Life) WGAdd(i int) {
	l.wg.Add(i)
}

//WGDone will decrement lifes waitgroup.
func (l Life) WGDone() {
	l.wg.Done()
}

//Close will wait for he background thread to finsh and then exit
func (l Life) Close() error {
	l.Done <- struct{}{}
	l.wg.Wait()
	return nil
}
<commit_msg>move the WGDone call into Life so client doesn't have to worry about it<commit_after>package life

import (
	"sync"
)

//Life handles the creation of the background thread and shutdown management
type Life struct {
	wg   *sync.WaitGroup
	Done chan struct{}
	run  func()
	once *sync.Once
}

//NewLife creates life with the expected defaults
func NewLife() *Life {
	return &Life{wg: &sync.WaitGroup{}, Done: make(chan struct{}, 10), once: &sync.Once{}}
}

//Start the background thread.
func (l Life) Start() {
	l.once.Do(func() {
		l.WGAdd(1)
		defer l.wg.Done()
		go l.run()
	})
}

//SetRun will set the run function that will be called by Start.
func (l *Life) SetRun(f func()) {
	l.run = f
}

//WGAdd will add to lifes waitgroup.
func (l Life) WGAdd(i int) {
	l.wg.Add(i)
}

//WGDone will decrement lifes waitgroup.
func (l Life) WGDone() {
	l.wg.Done()
}

//Close will wait for he background thread to finsh and then exit
func (l Life) Close() error {
	l.Done <- struct{}{}
	l.wg.Wait()
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"
)

const (
	rows          = 32
	cols          = 48
	cellsPerValue = 16 // a uint64 contains 16 nibbles
	deadCell      = `⋅ `
	liveCell      = `○ `
	vt100         = "\033["
	vtUp          = `A`
	interframe    = 200 * time.Millisecond
)

func main() {
	fmt.Printf(fmt.Sprintf("%% %ds\n", (cols+2)), "Life")
	colz := cols / cellsPerValue
	board := make([][]uint64, rows)
	boardone := make([]uint64, rows*colz)
	for i := range board {
		board[i], boardone = boardone[:colz], boardone[colz:]
	}
	start_test := []string{
		"                               x",
		"  x            x                ",
		"  x           x                 ",
		"  x                             ",
		"                x               ",
		"",
		"",
		"  x",
		"  x",
		"  x",
		"",
		"",
		"  x   xx",
		"  x   xx",
		"  x",
		"",
		"",
		"               xx",
		"               xx",
		"                 xx",
		"                 xx",
		"",
		"",
		"",
		"      xxx",
		"      x x",
		"      xxx",
		"",
		"",
		"",
		"                               x",
		"                               x",
	}
	start_gosper := []string{
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                         1            ",
		"                       1 1            ",
		"             11      11            11 ",
		"            1   1    11            11 ",
		" 11        1     1   11               ",
		" 11        1   1 11    1 1            ",
		"           1     1       1            ",
		"            1   1                     ",
		"             11                       ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
		"                                      ",
	}

	_ = start_test
	start := start_gosper

	for i := range start {
		fmt.Println()
		for j, k := range start[i] {
			if k != ' ' {
				set(board, j, i)
			}
		}
	}

	for f := 0; ; f++ {
		out(board, f)
		count(board)
		rules(board)
	}
}

func set(board [][]uint64, x, y int) {
	if x < cols && y < rows {
		j := uint(x / cellsPerValue)
		offset := x % cellsPerValue
		mask := uint64(1) << uint((15-offset)*4)
		board[y][j] |= mask
	}
}

func out(board [][]uint64, f int) {
	fmt.Print(vt100, rows+1, vtUp, "frame:", f, "\n")
	for i := range board {
		for j := range board[i] {
			o := uint64(1) << uint(60)
			for o > 0 {
				if (board[i][j] & o) == o {
					fmt.Print(liveCell)
				} else {
					fmt.Print(deadCell)
				}
				o >>= 4
			}
		}
		fmt.Println()
	}
}

func count(board [][]uint64) {
	for i := range board {
		for j := range board[i] {
			// leftmost bit of uint64 adds to its 3 left and up and down
			m := uint64(1) << 60
			v := board[i][j] & m
			var y int
			if v > 0 {
				if j == 0 {
					y = len(board[i]) - 1
				} else {
					y = j - 1
				}
				if i == 0 {
					board[len(board)-1][y] += 2
					board[len(board)-1][j] += (uint64(2) << 60)
				} else {
					board[i-1][y] += 2
					board[i-1][j] += (uint64(2) << 60)
				}
				board[i][y] += 2
				if i == len(board)-1 {
					board[0][y] += 2
					board[0][j] += (uint64(2) << 60)
				} else {
					board[i+1][y] += 2
					board[i+1][j] += (uint64(2) << 60)
				}
			}
			// 2nd-leftmost bit of uint64 adds to its left
			m = uint64(1) << 56
			v = board[i][j] & m
			if v > 0 {
				if i == 0 {
					board[len(board)-1][j] += (uint64(2) << 60)
				} else {
					board[i-1][j] += (uint64(2) << 60)
				}
				board[i][j] += (uint64(2) << 60)
				if i == len(board)-1 {
					board[0][j] += (uint64(2) << 60)
				} else {
					board[i+1][j] += (uint64(2) << 60)
				}
			}
			// middle bits of uint64
			for k := 52; k >= 0; k -= 4 {
				m := uint64(0x111) << uint(k)
				v := board[i][j] & m
				if v > 0 {
					var u, w uint64
					switch v >> uint(k) {
					case 0x010:
						u = 1
						w = 0
					case 0x001, 0x100:
						u = 1
						w = 1
					case 0x011, 0x110:
						u = 2
						w = 1
					case 0x101:
						u = 2
						w = 2
					case 0x111:
						u = 3
						w = 2
					}
					u <<= uint(k + 5)
					if i == 0 {
						board[len(board)-1][j] += u
					} else {
						board[i-1][j] += u
					}
					board[i][j] += (w << uint(k+5))
					if i == len(board)-1 {
						board[0][j] += u
					} else {
						board[i+1][j] += u
					}
				}
			}
			// rightmost bit of uint64 adds to its 3 right and up and down
			m = uint64(1)
			v = board[i][j] & m
			if v > 0 {
				if j == len(board[i])-1 {
					y = 0
				} else {
					y = j + 1
				}
				if i == 0 {
					board[len(board)-1][y] += (uint64(2) << 60)
					board[len(board)-1][j] += 2
				} else {
					board[i-1][y] += (uint64(2) << 60)
					board[i-1][j] += 2
				}
				board[i][y] += (uint64(2) << 60)
				if i == len(board)-1 {
					board[0][y] += (uint64(2) << 60)
					board[0][j] += 2
				} else {
					board[i+1][y] += (uint64(2) << 60)
					board[i+1][j] += 2
				}
			}
			// 2nd-rightmost bit of uint64 adds to its right
			m = uint64(0x10)
			v = board[i][j] & m
			if v > 0 {
				if i == 0 {
					board[len(board)-1][j] += 2
				} else {
					board[i-1][j] += 2
				}
				board[i][j] += 2
				if i == len(board)-1 {
					board[0][j] += 2
				} else {
					board[i+1][j] += 2
				}
			}
		}
	}
	time.Sleep(interframe)
}

func rules(board [][]uint64) {
	for i := range board {
		for j := range board[i] {
			for k := 60; k >= 0; k -= 4 {
				m := uint64(0xF) << uint(k)
				v := board[i][j] & m
				if v > 0 {
					board[i][j] &= ^m
					switch v >> uint(k) {
					case 5, 6, 7:
						board[i][j] |= (uint64(1) << uint(k))
					}
				}
			}
		}
	}
}
<commit_msg>gofmt -s -tabs=false -tabwidth=2 -w life.go<commit_after>package main

import (
  "fmt"
  "time"
)

const (
  rows          = 32
  cols          = 48
  cellsPerValue = 16 // a uint64 contains 16 nibbles
  deadCell      = `⋅ `
  liveCell      = `○ `
  vt100         = "\033["
  vtUp          = `A`
  interframe    = 200 * time.Millisecond
)

func main() {
  fmt.Printf(fmt.Sprintf("%% %ds\n", (cols+2)), "Life")
  colz := cols / cellsPerValue
  board := make([][]uint64, rows)
  boardone := make([]uint64, rows*colz)
  for i := range board {
    board[i], boardone = boardone[:colz], boardone[colz:]
  }
  start_test := []string{
    "                               x",
    "  x            x                ",
    "  x           x                 ",
    "  x                             ",
    "                x               ",
    "",
    "",
    "  x",
    "  x",
    "  x",
    "",
    "",
    "  x   xx",
    "  x   xx",
    "  x",
    "",
    "",
    "               xx",
    "               xx",
    "                 xx",
    "                 xx",
    "",
    "",
    "",
    "      xxx",
    "      x x",
    "      xxx",
    "",
    "",
    "",
    "                               x",
    "                               x",
  }
  start_gosper := []string{
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                         1            ",
    "                       1 1            ",
    "             11      11            11 ",
    "            1   1    11            11 ",
    " 11        1     1   11               ",
    " 11        1   1 11    1 1            ",
    "           1     1       1            ",
    "            1   1                     ",
    "             11                       ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
    "                                      ",
  }

  _ = start_test
  start := start_gosper

  for i := range start {
    fmt.Println()
    for j, k := range start[i] {
      if k != ' ' {
        set(board, j, i)
      }
    }
  }

  for f := 0; ; f++ {
    out(board, f)
    count(board)
    rules(board)
  }
}

func set(board [][]uint64, x, y int) {
  if x < cols && y < rows {
    j := uint(x / cellsPerValue)
    offset := x % cellsPerValue
    mask := uint64(1) << uint((15-offset)*4)
    board[y][j] |= mask
  }
}

func out(board [][]uint64, f int) {
  fmt.Print(vt100, rows+1, vtUp, "frame:", f, "\n")
  for i := range board {
    for j := range board[i] {
      o := uint64(1) << uint(60)
      for o > 0 {
        if (board[i][j] & o) == o {
          fmt.Print(liveCell)
        } else {
          fmt.Print(deadCell)
        }
        o >>= 4
      }
    }
    fmt.Println()
  }
}

func count(board [][]uint64) {
  for i := range board {
    for j := range board[i] {
      // leftmost bit of uint64 adds to its 3 left and up and down
      m := uint64(1) << 60
      v := board[i][j] & m
      var y int
      if v > 0 {
        if j == 0 {
          y = len(board[i]) - 1
        } else {
          y = j - 1
        }
        if i == 0 {
          board[len(board)-1][y] += 2
          board[len(board)-1][j] += (uint64(2) << 60)
        } else {
          board[i-1][y] += 2
          board[i-1][j] += (uint64(2) << 60)
        }
        board[i][y] += 2
        if i == len(board)-1 {
          board[0][y] += 2
          board[0][j] += (uint64(2) << 60)
        } else {
          board[i+1][y] += 2
          board[i+1][j] += (uint64(2) << 60)
        }
      }
      // 2nd-leftmost bit of uint64 adds to its left
      m = uint64(1) << 56
      v = board[i][j] & m
      if v > 0 {
        if i == 0 {
          board[len(board)-1][j] += (uint64(2) << 60)
        } else {
          board[i-1][j] += (uint64(2) << 60)
        }
        board[i][j] += (uint64(2) << 60)
        if i == len(board)-1 {
          board[0][j] += (uint64(2) << 60)
        } else {
          board[i+1][j] += (uint64(2) << 60)
        }
      }
      // middle bits of uint64
      for k := 52; k >= 0; k -= 4 {
        m := uint64(0x111) << uint(k)
        v := board[i][j] & m
        if v > 0 {
          var u, w uint64
          switch v >> uint(k) {
          case 0x010:
            u = 1
            w = 0
          case 0x001, 0x100:
            u = 1
            w = 1
          case 0x011, 0x110:
            u = 2
            w = 1
          case 0x101:
            u = 2
            w = 2
          case 0x111:
            u = 3
            w = 2
          }
          u <<= uint(k + 5)
          if i == 0 {
            board[len(board)-1][j] += u
          } else {
            board[i-1][j] += u
          }
          board[i][j] += (w << uint(k+5))
          if i == len(board)-1 {
            board[0][j] += u
          } else {
            board[i+1][j] += u
          }
        }
      }
      // rightmost bit of uint64 adds to its 3 right and up and down
      m = uint64(1)
      v = board[i][j] & m
      if v > 0 {
        if j == len(board[i])-1 {
          y = 0
        } else {
          y = j + 1
        }
        if i == 0 {
          board[len(board)-1][y] += (uint64(2) << 60)
          board[len(board)-1][j] += 2
        } else {
          board[i-1][y] += (uint64(2) << 60)
          board[i-1][j] += 2
        }
        board[i][y] += (uint64(2) << 60)
        if i == len(board)-1 {
          board[0][y] += (uint64(2) << 60)
          board[0][j] += 2
        } else {
          board[i+1][y] += (uint64(2) << 60)
          board[i+1][j] += 2
        }
      }
      // 2nd-rightmost bit of uint64 adds to its right
      m = uint64(0x10)
      v = board[i][j] & m
      if v > 0 {
        if i == 0 {
          board[len(board)-1][j] += 2
        } else {
          board[i-1][j] += 2
        }
        board[i][j] += 2
        if i == len(board)-1 {
          board[0][j] += 2
        } else {
          board[i+1][j] += 2
        }
      }
    }
  }
  time.Sleep(interframe)
}

func rules(board [][]uint64) {
  for i := range board {
    for j := range board[i] {
      for k := 60; k >= 0; k -= 4 {
        m := uint64(0xF) << uint(k)
        v := board[i][j] & m
        if v > 0 {
          board[i][j] &= ^m
          switch v >> uint(k) {
          case 5, 6, 7:
            board[i][j] |= (uint64(1) << uint(k))
          }
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>package slack

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// SlackResponse handles parsing out errors from the web api.
type SlackResponse struct {
	Ok    bool   `json:"ok"`
	Error string `json:"error"`
}

func (t SlackResponse) Err() error {
	if t.Ok {
		return nil
	}

	// handle pure text based responses like chat.post
	// which while they have a slack response in their data structure
	// it doesn't actually get set during parsing.
	if strings.TrimSpace(t.Error) == "" {
		return nil
	}

	return errors.New(t.Error)
}

// StatusCodeError represents an http response error.
// type httpStatusCode interface { HTTPStatusCode() int } to handle it.
type statusCodeError struct {
	Code   int
	Status string
}

func (t statusCodeError) Error() string {
	// TODO: this is a bad error string, should clean it up with a breaking changes
	// merger.
	return fmt.Sprintf("Slack server error: %s.", t.Status)
}

func (t statusCodeError) HTTPStatusCode() int {
	return t.Code
}

type RateLimitedError struct {
	RetryAfter time.Duration
}

func (e *RateLimitedError) Error() string {
	return fmt.Sprintf("Slack rate limit exceeded, retry after %s", e.RetryAfter)
}

func fileUploadReq(ctx context.Context, path, fieldname, filename string, values url.Values, r io.Reader) (*http.Request, error) {
	pipeReader, pipeWriter := io.Pipe()
	wr := multipart.NewWriter(pipeWriter)
	go func() {
		defer pipeWriter.Close()
		ioWriter, err := wr.CreateFormFile(fieldname, filename)
		if err != nil {
			fmt.Println(err)
		}
		_, err = io.Copy(ioWriter, r)
		if err != nil {
			fmt.Println(err)
		}
		if err := wr.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	req, err := http.NewRequest("POST", path, pipeReader)
	req = req.WithContext(ctx)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", wr.FormDataContentType())
	req.URL.RawQuery = (values).Encode()
	return req, nil
}

func parseResponseBody(body io.ReadCloser, intf interface{}, d debug) error {
	response, err := ioutil.ReadAll(body)
	if err != nil {
		return err
	}

	if d.Debug() {
		d.Debugln("parseResponseBody", string(response))
	}

	return json.Unmarshal(response, intf)
}

func postLocalWithMultipartResponse(ctx context.Context, client httpClient, path, fpath, fieldname string, values url.Values, intf interface{}, d debug) error {
	fullpath, err := filepath.Abs(fpath)
	if err != nil {
		return err
	}
	file, err := os.Open(fullpath)
	if err != nil {
		return err
	}
	defer file.Close()
	return postWithMultipartResponse(ctx, client, path, filepath.Base(fpath), fieldname, values, file, intf, d)
}

func postWithMultipartResponse(ctx context.Context, client httpClient, path, name, fieldname string, values url.Values, r io.Reader, intf interface{}, d debug) error {
	req, err := fileUploadReq(ctx, APIURL+path, fieldname, name, values, r)
	if err != nil {
		return err
	}
	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusTooManyRequests {
		retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
		if err != nil {
			return err
		}
		return &RateLimitedError{time.Duration(retry) * time.Second}
	}

	// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
	if resp.StatusCode != http.StatusOK {
		logResponse(resp, d)
		return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
	}

	return parseResponseBody(resp.Body, intf, d)
}

func doPost(ctx context.Context, client httpClient, req *http.Request, intf interface{}, d debug) error {
	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusTooManyRequests {
		retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
		if err != nil {
			return err
		}
		return &RateLimitedError{time.Duration(retry) * time.Second}
	}

	// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
	if resp.StatusCode != http.StatusOK {
		logResponse(resp, d)
		return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
	}

	return parseResponseBody(resp.Body, intf, d)
}

// post JSON.
func postJSON(ctx context.Context, client httpClient, endpoint, token string, json []byte, intf interface{}, d debug) error {
	reqBody := bytes.NewBuffer(json)
	req, err := http.NewRequest("POST", endpoint, reqBody)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	return doPost(ctx, client, req, intf, d)
}

// post a url encoded form.
func postForm(ctx context.Context, client httpClient, endpoint string, values url.Values, intf interface{}, d debug) error {
	reqBody := strings.NewReader(values.Encode())
	req, err := http.NewRequest("POST", endpoint, reqBody)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	return doPost(ctx, client, req, intf, d)
}

// post to a slack web method.
func postSlackMethod(ctx context.Context, client httpClient, path string, values url.Values, intf interface{}, d debug) error {
	return postForm(ctx, client, APIURL+path, values, intf, d)
}

// get a slack web method.
func getSlackMethod(ctx context.Context, client httpClient, path string, values url.Values, intf interface{}, d debug) error {
	return getResource(ctx, client, APIURL+path, values, intf, d)
}

func getResource(ctx context.Context, client httpClient, endpoint string, values url.Values, intf interface{}, d debug) error {
	req, err := http.NewRequest("GET", endpoint, nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.URL.RawQuery = values.Encode()

	return doPost(ctx, client, req, intf, d)
}

func parseAdminResponse(ctx context.Context, client httpClient, method string, teamName string, values url.Values, intf interface{}, d debug) error {
	endpoint := fmt.Sprintf(WEBAPIURLFormat, teamName, method, time.Now().Unix())
	return postForm(ctx, client, endpoint, values, intf, d)
}

func logResponse(resp *http.Response, d debug) error {
	if d.Debug() {
		text, err := httputil.DumpResponse(resp, true)
		if err != nil {
			return err
		}
		d.Debugln(string(text))
	}

	return nil
}

func okJSONHandler(rw http.ResponseWriter, r *http.Request) {
	rw.Header().Set("Content-Type", "application/json")
	response, _ := json.Marshal(SlackResponse{
		Ok: true,
	})
	rw.Write(response)
}

type errorString string

func (t errorString) Error() string {
	return string(t)
}

// timerReset safely reset a timer, see time.Timer.Reset for details.
func timerReset(t *time.Timer, d time.Duration) {
	if !t.Stop() {
		<-t.C
	}
	t.Reset(d)
}
<commit_msg>change pipe setting in postWithMultipartResponse and error handling #389<commit_after>package slack

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// SlackResponse handles parsing out errors from the web api.
type SlackResponse struct {
	Ok    bool   `json:"ok"`
	Error string `json:"error"`
}

func (t SlackResponse) Err() error {
	if t.Ok {
		return nil
	}

	// handle pure text based responses like chat.post
	// which while they have a slack response in their data structure
	// it doesn't actually get set during parsing.
	if strings.TrimSpace(t.Error) == "" {
		return nil
	}

	return errors.New(t.Error)
}

// StatusCodeError represents an http response error.
// type httpStatusCode interface { HTTPStatusCode() int } to handle it.
type statusCodeError struct {
	Code   int
	Status string
}

func (t statusCodeError) Error() string {
	// TODO: this is a bad error string, should clean it up with a breaking changes
	// merger.
	return fmt.Sprintf("Slack server error: %s.", t.Status)
}

func (t statusCodeError) HTTPStatusCode() int {
	return t.Code
}

type RateLimitedError struct {
	RetryAfter time.Duration
}

func (e *RateLimitedError) Error() string {
	return fmt.Sprintf("Slack rate limit exceeded, retry after %s", e.RetryAfter)
}

func fileUploadReq(ctx context.Context, path string, values url.Values, r io.Reader) (*http.Request, error) {
	req, err := http.NewRequest("POST", path, r)

	req = req.WithContext(ctx)
	if err != nil {
		return nil, err
	}
	req.URL.RawQuery = (values).Encode()
	return req, nil
}

func parseResponseBody(body io.ReadCloser, intf interface{}, d debug) error {
	response, err := ioutil.ReadAll(body)
	if err != nil {
		return err
	}

	if d.Debug() {
		d.Debugln("parseResponseBody", string(response))
	}

	return json.Unmarshal(response, intf)
}

func postLocalWithMultipartResponse(ctx context.Context, client httpClient, path, fpath, fieldname string, values url.Values, intf interface{}, d debug) error {
	fullpath, err := filepath.Abs(fpath)
	if err != nil {
		return err
	}
	file, err := os.Open(fullpath)
	if err != nil {
		return err
	}
	defer file.Close()
	return postWithMultipartResponse(ctx, client, path, filepath.Base(fpath), fieldname, values, file, intf, d)
}

func postWithMultipartResponse(ctx context.Context, client httpClient, path, name, fieldname string, values url.Values, r io.Reader, intf interface{}, d debug) error {
	pipeReader, pipeWriter := io.Pipe()
	wr := multipart.NewWriter(pipeWriter)
	errc := make(chan error)
	go func() {
		defer pipeWriter.Close()
		ioWriter, err := wr.CreateFormFile(fieldname, name)
		if err != nil {
			errc <- err
			return
		}
		_, err = io.Copy(ioWriter, r)
		if err != nil {
			errc <- err
			return
		}
		if err = wr.Close(); err != nil {
			errc <- err
			return
		}
	}()
	req, err := fileUploadReq(ctx, APIURL+path, values, pipeReader)
	if err != nil {
		return err
	}
	req.Header.Add("Content-Type", wr.FormDataContentType())
	req = req.WithContext(ctx)
	resp, err := client.Do(req)

	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusTooManyRequests {
		retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
		if err != nil {
			return err
		}
		return &RateLimitedError{time.Duration(retry) * time.Second}
	}

	// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
	if resp.StatusCode != http.StatusOK {
		logResponse(resp, d)
		return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
	}
	select {
	case err = <-errc:
		return err
	default:
		return parseResponseBody(resp.Body, intf, d)
	}
}

func doPost(ctx context.Context, client httpClient, req *http.Request, intf interface{}, d debug) error {
	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusTooManyRequests {
		retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
		if err != nil {
			return err
		}
		return &RateLimitedError{time.Duration(retry) * time.Second}
	}

	// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
	if resp.StatusCode != http.StatusOK {
		logResponse(resp, d)
		return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
	}

	return parseResponseBody(resp.Body, intf, d)
}

// post JSON.
func postJSON(ctx context.Context, client httpClient, endpoint, token string, json []byte, intf interface{}, d debug) error {
	reqBody := bytes.NewBuffer(json)
	req, err := http.NewRequest("POST", endpoint, reqBody)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	return doPost(ctx, client, req, intf, d)
}

// post a url encoded form.
func postForm(ctx context.Context, client httpClient, endpoint string, values url.Values, intf interface{}, d debug) error {
	reqBody := strings.NewReader(values.Encode())
	req, err := http.NewRequest("POST", endpoint, reqBody)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	return doPost(ctx, client, req, intf, d)
}

// post to a slack web method.
func postSlackMethod(ctx context.Context, client httpClient, path string, values url.Values, intf interface{}, d debug) error {
	return postForm(ctx, client, APIURL+path, values, intf, d)
}

// get a slack web method.
func getSlackMethod(ctx context.Context, client httpClient, path string, values url.Values, intf interface{}, d debug) error {
	return getResource(ctx, client, APIURL+path, values, intf, d)
}

func getResource(ctx context.Context, client httpClient, endpoint string, values url.Values, intf interface{}, d debug) error {
	req, err := http.NewRequest("GET", endpoint, nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.URL.RawQuery = values.Encode()

	return doPost(ctx, client, req, intf, d)
}

func parseAdminResponse(ctx context.Context, client httpClient, method string, teamName string, values url.Values, intf interface{}, d debug) error {
	endpoint := fmt.Sprintf(WEBAPIURLFormat, teamName, method, time.Now().Unix())
	return postForm(ctx, client, endpoint, values, intf, d)
}

func logResponse(resp *http.Response, d debug) error {
	if d.Debug() {
		text, err := httputil.DumpResponse(resp, true)
		if err != nil {
			return err
		}
		d.Debugln(string(text))
	}

	return nil
}

func okJSONHandler(rw http.ResponseWriter, r *http.Request) {
	rw.Header().Set("Content-Type", "application/json")
	response, _ := json.Marshal(SlackResponse{
		Ok: true,
	})
	rw.Write(response)
}

type errorString string

func (t errorString) Error() string {
	return string(t)
}

// timerReset safely reset a timer, see time.Timer.Reset for details.
func timerReset(t *time.Timer, d time.Duration) {
	if !t.Stop() {
		<-t.C
	}
	t.Reset(d)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/hashicorp/consul/api"
	// "github.com/wushilin/stream"
	"gopkg.in/alecthomas/kingpin.v2"
	// "regexp"
	"strings"
)

type listCommand struct {
	Command
	filterExp string
}

func listRegisterCli(app *kingpin.Application, opts *appOpts) {
	l := &listCommand{}
	l.opts = opts
	list := app.Command("list", "List Consul entities")
	list.Flag("regex", "Filter by regular expression").Short('r').StringVar(&l.filterExp)
	list.Command("service", "List Consult services").Action(l.listServiceHandler)
	list.Command("dc", "List Consul DataCenters").Action(l.listDCHandler)
}

func (l *listCommand) listServiceHandler(context *kingpin.ParseContext) error {
	allServices := make(map[string]map[string][]string)
	if consultClients, err := l.GetConsulClients(); err != nil {
		return err
	} else {
		short := make([]string, 0)
		long := make([]string, 0)
		long = append(long, "Datacenter\tService\tTags")
		long = append(long, "")

		for dc, client := range consultClients {
			if services, _, err := client.Catalog().Services(&api.QueryOptions{}); err != nil {
				return err
			} else {
				for service, tags := range services {
					short = append(short, dc+"\t"+service)
					long = append(long, dc+"\t"+service+"\t"+strings.Join(tags, ","))
				}
				allServices[dc] = services
			}
		}
		l.Output(allServices, long, short)
	}
	return nil
}

func (l *listCommand) listDCHandler(context *kingpin.ParseContext) error {
	dcs, err := l.listDCs()
	if err != nil {
		return err
	}
	l.Output(dcs, dcs, dcs)
	return nil
}

func (l *listCommand) listDCs() ([]string, error) {
	client, err := l.GetConsulClient()
	if err != nil {
		return nil, err
	}

	dcs, qErr := client.Catalog().Datacenters()
	if qErr != nil {
		return nil, qErr
	}

	return dcs, nil
}
<commit_msg>Add list node subcommand<commit_after>package main

import (
	"github.com/hashicorp/consul/api"
	// "github.com/wushilin/stream"
	"gopkg.in/alecthomas/kingpin.v2"
	// "regexp"
	"strings"
)

type listCommand struct {
	Command
	filterExp string
}

func listRegisterCli(app *kingpin.Application, opts *appOpts) {
	l := &listCommand{}
	l.opts = opts
	list := app.Command("list", "List Consul entities")
	list.Flag("regex", "Filter by regular expression").Short('r').StringVar(&l.filterExp)
	list.Command("service", "List Consult services").Action(l.listServiceHandler)
	list.Command("dc", "List Consul DataCenters").Action(l.listDCHandler)
	list.Command("node", "List Consul nodes").Action(l.listNodeHandler)
}

func (l *listCommand) listServiceHandler(context *kingpin.ParseContext) error {
	allServices := make(map[string]map[string][]string)
	if consultClients, err := l.GetConsulClients(); err != nil {
		return err
	} else {
		short := make([]string, 0)
		long := make([]string, 0)
		long = append(long, "Datacenter\tService\tTags")
		long = append(long, "")

		for dc, client := range consultClients {
			if services, _, err := client.Catalog().Services(&api.QueryOptions{}); err != nil {
				return err
			} else {
				for service, tags := range services {
					short = append(short, dc+"\t"+service)
					long = append(long, dc+"\t"+service+"\t"+strings.Join(tags, ","))
				}
				allServices[dc] = services
			}
		}
		l.Output(allServices, long, short)
	}
	return nil
}

func (l *listCommand) listDCHandler(context *kingpin.ParseContext) error {
	dcs, err := l.listDCs()
	if err != nil {
		return err
	}
	l.Output(dcs, dcs, dcs)
	return nil
}

func (l *listCommand) listDCs() ([]string, error) {
	client, err := l.GetConsulClient()
	if err != nil {
		return nil, err
	}

	dcs, qErr := client.Catalog().Datacenters()
	if qErr != nil {
		return nil, qErr
	}

	return dcs, nil
}

func (l *listCommand) listNodeHandler(context *kingpin.ParseContext) error {
	if results, err := l.listNodes(); err != nil {
		return err
	} else {
		short := make([]string, 0)
		long := make([]string, 2)
		long[0] = "Datacenter\tNode\tAddress"
		long[1] = ""

		for dc, nodes := range results {
			for _, node := range nodes {
				long = append(long, dc+"\t"+node.Node+"\t"+node.Address)
				short = append(short, dc+"\t"+node.Node)
			}
		}

		l.Output(results, long, short)
		return nil
	}
}

func (l *listCommand) listNodes() (map[string][]*api.Node, error) {
	if clients, err := l.GetConsulClients(); err != nil {
		return nil, err
	} else {
		results := make(map[string][]*api.Node)
		for dc, client := range clients {
			if nodes, _, err := client.Catalog().Nodes(&api.QueryOptions{}); err != nil {
				return nil, err
			} else {
				results[dc] = nodes
			}
		}
		return results, nil
	}
}
<|endoftext|>


<commit_before>package magick

// #include <magick/api.h>
import "C"

func (im *Image) IsOrphan() bool {
	return im.image.next == nil && im.image.previous == nil
}

func (im *Image) NFrames() int {
	if im.parent != nil {
		return 1
	}
	return int(C.GetImageListLength(im.image))
}

func (im *Image) FrameIndex() int {
	if im.parent != nil {
		return 0
	}
	return int(C.GetImageIndexInList(im.image))
}

func (im *Image) Duration() int {
	if im.parent != nil {
		return im.Delay()
	}
	duration := 0
	for cur := C.GetFirstImageInList(im.image); cur != nil; cur = (*C.Image)(cur.next) {
		duration += int(cur.delay)
	}
	return duration
}

func (im *Image) Frame(idx int) (*Image, error) {
	if im.IsOrphan() && idx == 0 {
		return im, nil
	}
	image := C.GetImageFromList(im.image, magickLong(idx))
	if image == nil {
		return nil, ErrNoSuchFrame
	}
	return newImage(image, im), nil
}

func (im *Image) First() *Image {
	first, _ := im.Frame(0)
	return first
}

func (im *Image) Last() *Image {
	last, _ := im.Frame(im.NFrames() - 1)
	return last
}

func (im *Image) Prev() *Image {
	prev := C.GetPreviousImageInList(im.image)
	if prev == nil {
		return nil
	}
	return newImage(prev, im)
}

func (im *Image) Next() *Image {
	next := C.GetNextImageInList(im.image)
	if next == nil {
		return nil
	}
	return newImage(next, im)
}

func (im *Image) Reverse() {
	C.ReverseImageList(&im.image)
}

/*func (im *Image) InsertAfter(image *Image) error {
	cloned, err := image.Clone()
	if err != nil {
		return err
	}
	first := cloned.First()
	first.prev = im
	if im.next != nil {
		im.next.prev = cloned.Last()
	}
	im.next = first
	return nil
}

func (im *Image) InsertBefore(image *Image) error {
	cloned, err := image.CloneAll()
	if err != nil {
		return err
	}
	last := cloned.Last()
	last.next = im
	if im.prev != nil {
		im.prev.next = cloned.First()
	}
	image.prev = last
	return nil
}
*/

func (im *Image) Prepend(image *Image) error {
	// TODO: Don't clone, refcount
	cloned, err := image.Clone()
	if err != nil {
		return err
	}
	dontFree(cloned)
	C.PrependImageToList(&im.image, cloned.image)
	return nil
}

func (im *Image) Append(image *Image) error {
	// TODO: Don't clone, refcount
	cloned, err := image.Clone()
	if err != nil {
		return err
	}
	dontFree(cloned)
	C.AppendImageToList(&im.image, cloned.image)
	return nil
}

func (im *Image) RemoveIndex(idx int) bool {
	if frame, _ := im.Frame(idx); frame != nil {
		return frame.Remove()
	}
	return false
}

func (im *Image) RemoveFirst() bool {
	return im.RemoveIndex(0)
}

func (im *Image) RemoveLast() bool {
	return im.RemoveIndex(im.NFrames() - 1)
}

func (im *Image) Remove() bool {
	if im.parent != nil && !im.parent.IsOrphan() {
		// Don't use DeleteImageFromList, since it calls DestroyImage,
		// bypassing our refcounting.
		if im.image == im.parent.image {
			im.parent.image = (*C.Image)(im.parent.image.next)
		}
		if p := (*C.Image)(im.image.previous); p != nil {
			p.next = im.image.next
		}
		if n := (*C.Image)(im.image.next); n != nil {
			n.previous = im.image.previous
		}
		im.image.previous = nil
		im.image.next = nil
		im.parent = nil
		// im already holds a reference, remove the reference that
		// the parent had.
		unrefImage(im.image)
		return true
	}
	return false
}

func (im *Image) Apply(f func(*Image) (*Image, error)) (*Image, error) {
	if im.IsOrphan() || im.parent != nil {
		return f(im)
	}
	var ex C.ExceptionInfo
	C.GetExceptionInfo(&ex)
	defer C.DestroyExceptionInfo(&ex)
	cur, free := im.coalescedCImage(&ex)
	if cur == nil {
		return nil, exError(&ex, "coalescing")
	}
	if free {
		defer C.DestroyImageList(cur)
	}
	buf := &Image{
		image: cur,
	}
	first, err := f(buf)
	if err != nil {
		return nil, err
	}
	prev := first.image
	for cur := (*C.Image)(im.image.next); cur != nil; cur = (*C.Image)(cur.next) {
		buf.image = cur
		res, err := f(buf)
		if err != nil {
			return nil, err
		}
		dontFree(res)
		img := res.image
		prev.next = (*C.struct__Image)(img)
		img.previous = (*C.struct__Image)(img)
		prev = img
	}
	return first, nil
}
<commit_msg>Don't return a 0 FrameIndex for images with parent<commit_after>package magick

// #include <magick/api.h>
import "C"

func (im *Image) IsOrphan() bool {
	return im.image.next == nil && im.image.previous == nil
}

func (im *Image) NFrames() int {
	if im.parent != nil {
		return 1
	}
	return int(C.GetImageListLength(im.image))
}

func (im *Image) FrameIndex() int {
	return int(C.GetImageIndexInList(im.image))
}

func (im *Image) Duration() int {
	if im.parent != nil {
		return im.Delay()
	}
	duration := 0
	for cur := C.GetFirstImageInList(im.image); cur != nil; cur = (*C.Image)(cur.next) {
		duration += int(cur.delay)
	}
	return duration
}

func (im *Image) Frame(idx int) (*Image, error) {
	if im.IsOrphan() && idx == 0 {
		return im, nil
	}
	image := C.GetImageFromList(im.image, magickLong(idx))
	if image == nil {
		return nil, ErrNoSuchFrame
	}
	return newImage(image, im), nil
}

func (im *Image) First() *Image {
	first, _ := im.Frame(0)
	return first
}

func (im *Image) Last() *Image {
	last, _ := im.Frame(im.NFrames() - 1)
	return last
}

func (im *Image) Prev() *Image {
	prev := C.GetPreviousImageInList(im.image)
	if prev == nil {
		return nil
	}
	return newImage(prev, im)
}

func (im *Image) Next() *Image {
	next := C.GetNextImageInList(im.image)
	if next == nil {
		return nil
	}
	return newImage(next, im)
}

func (im *Image) Reverse() {
	C.ReverseImageList(&im.image)
}

/*func (im *Image) InsertAfter(image *Image) error {
	cloned, err := image.Clone()
	if err != nil {
		return err
	}
	first := cloned.First()
	first.prev = im
	if im.next != nil {
		im.next.prev = cloned.Last()
	}
	im.next = first
	return nil
}

func (im *Image) InsertBefore(image *Image) error {
	cloned, err := image.CloneAll()
	if err != nil {
		return err
	}
	last := cloned.Last()
	last.next = im
	if im.prev != nil {
		im.prev.next = cloned.First()
	}
	image.prev = last
	return nil
}
*/

func (im *Image) Prepend(image *Image) error {
	// TODO: Don't clone, refcount
	cloned, err := image.Clone()
	if err != nil {
		return err
	}
	dontFree(cloned)
	C.PrependImageToList(&im.image, cloned.image)
	return nil
}

func (im *Image) Append(image *Image) error {
	// TODO: Don't clone, refcount
	cloned, err := image.Clone()
	if err != nil {
		return err
	}
	dontFree(cloned)
	C.AppendImageToList(&im.image, cloned.image)
	return nil
}

func (im *Image) RemoveIndex(idx int) bool {
	if frame, _ := im.Frame(idx); frame != nil {
		return frame.Remove()
	}
	return false
}

func (im *Image) RemoveFirst() bool {
	return im.RemoveIndex(0)
}

func (im *Image) RemoveLast() bool {
	return im.RemoveIndex(im.NFrames() - 1)
}

func (im *Image) Remove() bool {
	if im.parent != nil && !im.parent.IsOrphan() {
		// Don't use DeleteImageFromList, since it calls DestroyImage,
		// bypassing our refcounting.
		if im.image == im.parent.image {
			im.parent.image = (*C.Image)(im.parent.image.next)
		}
		if p := (*C.Image)(im.image.previous); p != nil {
			p.next = im.image.next
		}
		if n := (*C.Image)(im.image.next); n != nil {
			n.previous = im.image.previous
		}
		im.image.previous = nil
		im.image.next = nil
		im.parent = nil
		// im already holds a reference, remove the reference that
		// the parent had.
		unrefImage(im.image)
		return true
	}
	return false
}

func (im *Image) Apply(f func(*Image) (*Image, error)) (*Image, error) {
	if im.IsOrphan() || im.parent != nil {
		return f(im)
	}
	var ex C.ExceptionInfo
	C.GetExceptionInfo(&ex)
	defer C.DestroyExceptionInfo(&ex)
	cur, free := im.coalescedCImage(&ex)
	if cur == nil {
		return nil, exError(&ex, "coalescing")
	}
	if free {
		defer C.DestroyImageList(cur)
	}
	buf := &Image{
		image: cur,
	}
	first, err := f(buf)
	if err != nil {
		return nil, err
	}
	prev := first.image
	for cur := (*C.Image)(im.image.next); cur != nil; cur = (*C.Image)(cur.next) {
		buf.image = cur
		res, err := f(buf)
		if err != nil {
			return nil, err
		}
		dontFree(res)
		img := res.image
		prev.next = (*C.struct__Image)(img)
		img.previous = (*C.struct__Image)(img)
		prev = img
	}
	return first, nil
}
<|endoftext|>


<commit_before>package boardgame

import (
	"encoding/json"
	"github.com/jkomoros/boardgame/errors"
	"time"
)

//MoveType represents a type of a move in a game, and information about that
//MoveType. New Moves are constructed by calling its NewMove() method. Fields
//are hidden to prevent modifying them once a game has been SetUp. New ones
//cannot be created directly; they are created via
//GameManager.AddMoveType(moveTypeConfig).
type MoveType struct {
	name                string
	helpText            string
	constructor         func() Move
	legalPhases         []int
	isFixUp             bool
	validator           *readerValidator
	customConfiguration PropertyCollection
	manager             *GameManager
}

//MoveTypeConfig is a collection of information used to create a MoveType.
type MoveTypeConfig struct {
	//Name is the name for this type of move. No other Move structs
	//in use in this game should have the same name, but it should be human-
	//friendly. For example, "Place Token" is a reasonable name, as long as no
	//other types of Move-structs will return that name in this game. Required.
	Name string
	//HelpText is a human-readable sentence describing what the move does.
	//HelpText should be the same for all moves of the same type, and
	//should not vary with the Move's specific properties. For example, the
	//HelpText for "Place Token" might be "Places the current user's token
	//in the specified slot on the board."
	HelpText string
	//Constructor should return a zero-valued Move of the given type. Normally
	//very simple: just a new(MyMoveType). Required. If you have a field that
	//is an enum.Var you'll need to initalize it with a variable for the
	//correct enum (generally necessitating a multi-line constructor),
	//otherwise your move will fail to register. If that field has a struct
	//tag of `enum:"ENUMNAME"` then so long as ENUMNAME is the name of a valid
	//enum in the game's Chest.Enums, it will auto-instantiate a enum.Var for
	//the correct enum for that field, allowing you to maintain a single-line
	//constructor.
	MoveConstructor func() Move

	//LegalPhases is the value that will be returned from
	//MoveType.LegalPhases. It is primarily used by moves.Base to see if the
	//move is legal in the current phase, as determined by
	//delegate.CurrentPhase(). See moves.Base for how this information is
	//used. If you use manager.AddMovesForPhase or
	//manager.AddOrderedMovesForPhase to install your moves, you likely can
	//leave this as nil and have it set correctly. If you want your move to be
	//valid in any phase but don't want them to modify LegalPhases, configure
	//this to be a zero-length slice instead of nil and they'll leave it
	//untouched.
	LegalPhases []int

	//If IsFixUp is true, the moveType will be a FixUp move--that is, players
	//may not propose it, only ProposeFixUp moves may.
	IsFixUp bool

	//CustomConfiguration is an optional PropertyCollection. Some move types--
	//especially in the `moves` package, stash configuration options here that
	//will change how all moves of this type behave. Individual moves would
	//reach through via Info().Type().CustomConfiguration() to retrieve the
	//values stored there. Different move types will store different types of
	//information there--to avoid a collision the convention is to use a
	//string name that starts with your fully qualified package name, then a
	//dot, then the propertyname, like so:
	//"github.com/jkomoros/boardgame/moves.MoveName". Those strings are often
	//encoded as package-private constants, and a
	//moves.CustomConfigurationOption functor factory is provided to set those
	//from outside the package. Generally you don't use this directly, but
	//moves.DefaultConfig() will help you set these for what specific moves in
	//that package expect.
	CustomConfiguration PropertyCollection
}

//NewMoveType takes a MoveTypeConfig and returns a MoveType associated with
//the given manager. The returned move type will not yet have been added to
//the manager in question. In general you don't call this directly, and
//instead use manager.AddMove, which accepts a MoveTypeConfig.
func (m *MoveTypeConfig) NewMoveType(manager *GameManager) (*MoveType, error) {
	if m == nil {
		return nil, errors.New("No config provided")
	}

	if m.Name == "" {
		return nil, errors.New("No name provided")
	}

	if m.MoveConstructor == nil {
		return nil, errors.New("No MoveConstructor provided")
	}

	exampleMove := m.MoveConstructor()

	if exampleMove == nil {
		return nil, errors.New("MoveConstructor returned nil")
	}

	readSetter := exampleMove.ReadSetter()

	if readSetter == nil {
		return nil, errors.New("MoveConstructor's readsetter returned nil")
	}

	var validator *readerValidator
	var err error

	//moves.Defaultconfig will call this without a manager. So return a half-
	//useful object in that case... but also an error so anyone else who
	//checks the error will ignore the half-useful move type.
	if manager != nil {
		validator, err = newReaderValidator(readSetter, readSetter, exampleMove, moveTypeIllegalPropTypes, manager.Chest(), false)

		if err != nil {
			return nil, errors.New("Couldn't create validator: " + err.Error())
		}
	} else {
		//moves.DefaultConfig hackily looks for exactly this error string.
		err = errors.New("No manager passed, so we can'd do validation")
	}

	return &MoveType{
		name:                m.Name,
		helpText:            m.HelpText,
		constructor:         m.MoveConstructor,
		isFixUp:             m.IsFixUp,
		legalPhases:         m.LegalPhases,
		customConfiguration: m.CustomConfiguration,
		validator:           validator,
		manager:             manager,
	}, err

}

//MoveInfo is an object that contains meta-information about a move.
type MoveInfo struct {
	moveType  *MoveType
	version   int
	initiator int
	timestamp time.Time
}

//Move's are how all modifications are made to Game States after
//initialization. Packages define structs that implement Move for all
//modifications. The Move should be JSON-able (that is, all persistable state
//should be in public fields), and it may not include Timers, Stacks, or
//EnumValues. Use moves.Base for a convenient composable base Move that will
//allow you to skip most of the boilerplate overhead.
type Move interface {

	//Info returns the MoveInfo objec that was affiliated with this object by
	//SetInfo.
	Info() *MoveInfo

	//Legal returns nil if this proposed move is legal, or an error if the
	//move is not legal. The error message may be shown directly to the end-
	//user so be sure to make it user friendly. proposer is set to the
	//notional player that is proposing the move. proposer might be a valid
	//player index, or AdminPlayerIndex (for example, if it is a FixUpMove it
	//will typically be AdminPlayerIndex). AdminPlayerIndex is always allowed
	//to make any move. It will never be ObserverPlayerIndex, because by
	//definition Observers may not make moves. If you want to check that the
	//person proposing is able to apply the move for the given player, and
	//that it is their turn, you would do something like test
	//m.TargetPlayerIndex.Equivalent(proposer),
	//m.TargetPlayerIndex.Equivalent(game.CurrentPlayer).
	Legal(state State, proposer PlayerIndex) error

	//Apply applies the move to the state. It is handed a copy of the state to
	//modify. If error is non-nil it will not be applied to the game. It
	//should not be called directly; use Game.ProposeMove.
	Apply(state MutableState) error

	//Sets the move to have reasonable defaults for the given state.For
	//example, if the Move has a TargetPlayerIndex property, a reasonable
	//default is state.CurrentPlayer().
	DefaultsForState(state State)

	//Description is a human-readable prose description of the effects that
	//this particular move will have, including any move configuration. For
	//example the Description for "Place Token" might be "Player 0 places a
	//token in position 3".
	Description() string

	//SetInfo will be called after the constructor is called to set the
	//information, including what type the move is. Splitting this out allows
	//the basic constructors not in the base classes to be very small, because
	//in most cases you'll compose a moves.Base.
	SetInfo(m *MoveInfo)

	//TopLevelStruct should return the value that was set via
	//SetTopLevelStruct. It returns the Move that is at the top of the
	//embedding chain (because structs that are embedded anonymously can only
	//access themselves and not their embedders). This is useful because in a
	//number of cases embeded moves (for example moves in the moves package)
	//need to consult a method on their embedder.
	TopLevelStruct() Move

	//SetTopLevelStruct is called right after the move is constructed.
	//Splitting this out allows the basic constructors not in the base classes
	//to be very small, because in most cases you'll compose a moves.Base.
	SetTopLevelStruct(m Move)

	//ValidConfiguration will be checked when the game manager is SetUp, and
	//if it returns an error the manager will fail to SetUp. Some Moves,
	//especially sub-classes of moves in the moves package, require set up
	//that can only be verified at run time (for example, verifying that the
	//embedder implements a certain inteface). This is a useful way to detect
	//those misconfigurations at the earliest moment. In most cases you never
	//need to implement this yourself; moves in the moves package that need it
	//will implement it.
	ValidConfiguration(exampleState MutableState) error

	ReadSetConfigurer
}

//StorageRecordForMove returns a MoveStorageRecord. Can't hang off of Move
//itself since Moves are provided by users of the library.
func StorageRecordForMove(move Move, currentPhase int) *MoveStorageRecord {

	blob, err := json.MarshalIndent(move, "", "\t")

	if err != nil {
		return nil
	}

	return &MoveStorageRecord{
		Name:      move.Info().Type().Name(),
		Version:   move.Info().version,
		Initiator: move.Info().initiator,
		Timestamp: move.Info().timestamp,
		Phase:     currentPhase,
		Blob:      blob,
	}
}

//Type returns the MoveType of this Move.
func (m *MoveInfo) Type() *MoveType {
	return m.moveType
}

//Version returns the version of this move--or the version that it will be
//when successfully committed.
func (m *MoveInfo) Version() int {
	return m.version
}

//Timestamp returns the time that the given move was made.
func (m *MoveInfo) Timestamp() time.Time {
	return m.timestamp
}

//Initiator returns the move version that initiated this causal chain: the
//PlayerMove that was applied that led to this chain of FixUp moves. The
//Initiator of a PlayerMove is its own version, so this value will be less
//than or equal to its own version. The value of Initator is unspecified until
//after the move has been successfully committed.
func (m *MoveInfo) Initiator() int {
	return m.initiator
}

var moveTypeIllegalPropTypes = map[PropertyType]bool{
	TypeStack: true,
	TypeTimer: true,
}

//Name returns the unique name for this type of move.
func (m *MoveType) Name() string {
	return m.name
}

//HelpText is a human-readable sentence describing what the move does.
func (m *MoveType) HelpText() string {
	return m.helpText
}

func (m *MoveType) IsFixUp() bool {
	return m.isFixUp
}

func (m *MoveType) LegalPhases() []int {
	return m.legalPhases
}

//CustomConfiguration returns a copy of the CustomConfiguration passed in via
//the MoveTyepConfig to create this MoveType. See the documentation on
//MoveTypeConfig.CustomConfiguration for more about what it does and what it
//can be used for.
func (m *MoveType) CustomConfiguration() PropertyCollection {
	result := make(PropertyCollection, len(m.customConfiguration))
	for key, val := range m.customConfiguration {
		result[key] = val
	}
	return result
}

//NewMove returns a new move of this type, with defaults set for the given
//state. If state is nil, then DefaultsForState will not be called.
func (m *MoveType) NewMove(state State) Move {
	move := m.constructor()
	if move == nil {
		return nil
	}

	info := &MoveInfo{
		moveType: m,
	}

	if state != nil {
		info.version = state.Version() + 1
	}

	move.SetInfo(info)
	move.SetTopLevelStruct(move)

	readSetConfigurer := move.ReadSetConfigurer()

	if readSetConfigurer == nil {
		//This shouldn't happen because we verified that ReadSetter returned
		//non-nil when the movetype was registered.
		m.manager.Logger().Error("ReadSetConfigurer for move unexpectedly returned nil")
		return nil
	}

	//validator might be nil if we have a half-functioning MoveType. (Like
	//what will be returned, along with an error, when NewMoveType is called
	//during moves.DefaultConfig)
	if m.validator != nil {
		if err := m.validator.AutoInflate(readSetConfigurer, state); err != nil {
			m.manager.Logger().Error("AutoInflate had an error: " + err.Error())
			return nil
		}

		if err := m.validator.Valid(readSetConfigurer); err != nil {
			m.manager.Logger().Error("Move was not valid: " + err.Error())
			return nil
		}
	}

	if state != nil {
		move.DefaultsForState(state)
	}
	return move
}

//We implement a private stub of moves.Base in this package just for the
//convience of our own test structs.
type baseMove struct {
	info           MoveInfo
	topLevelStruct Move
}

func (d *baseMove) SetInfo(m *MoveInfo) {
	d.info = *m
}

func (d *baseMove) Info() *MoveInfo {
	return &d.info
}

func (d *baseMove) SetTopLevelStruct(m Move) {
	d.topLevelStruct = m
}

func (d *baseMove) TopLevelStruct() Move {
	return d.topLevelStruct
}

//DefaultsForState doesn't do anything
func (d *baseMove) DefaultsForState(state State) {
	return
}

//Description defaults to returning the Type's HelpText()
func (d *baseMove) Description() string {
	return d.Info().Type().HelpText()
}

func (d *baseMove) ValidConfiguration(exampleState MutableState) error {
	return nil
}
<commit_msg>Fixed some typos in the docs for CustomConfiguration. Part of #563.<commit_after>package boardgame

import (
	"encoding/json"
	"github.com/jkomoros/boardgame/errors"
	"time"
)

//MoveType represents a type of a move in a game, and information about that
//MoveType. New Moves are constructed by calling its NewMove() method. Fields
//are hidden to prevent modifying them once a game has been SetUp. New ones
//cannot be created directly; they are created via
//GameManager.AddMoveType(moveTypeConfig).
type MoveType struct {
	name                string
	helpText            string
	constructor         func() Move
	legalPhases         []int
	isFixUp             bool
	validator           *readerValidator
	customConfiguration PropertyCollection
	manager             *GameManager
}

//MoveTypeConfig is a collection of information used to create a MoveType.
type MoveTypeConfig struct {
	//Name is the name for this type of move. No other Move structs
	//in use in this game should have the same name, but it should be human-
	//friendly. For example, "Place Token" is a reasonable name, as long as no
	//other types of Move-structs will return that name in this game. Required.
	Name string
	//HelpText is a human-readable sentence describing what the move does.
	//HelpText should be the same for all moves of the same type, and
	//should not vary with the Move's specific properties. For example, the
	//HelpText for "Place Token" might be "Places the current user's token
	//in the specified slot on the board."
	HelpText string
	//Constructor should return a zero-valued Move of the given type. Normally
	//very simple: just a new(MyMoveType). Required. If you have a field that
	//is an enum.Var you'll need to initalize it with a variable for the
	//correct enum (generally necessitating a multi-line constructor),
	//otherwise your move will fail to register. If that field has a struct
	//tag of `enum:"ENUMNAME"` then so long as ENUMNAME is the name of a valid
	//enum in the game's Chest.Enums, it will auto-instantiate a enum.Var for
	//the correct enum for that field, allowing you to maintain a single-line
	//constructor.
	MoveConstructor func() Move

	//LegalPhases is the value that will be returned from
	//MoveType.LegalPhases. It is primarily used by moves.Base to see if the
	//move is legal in the current phase, as determined by
	//delegate.CurrentPhase(). See moves.Base for how this information is
	//used. If you use manager.AddMovesForPhase or
	//manager.AddOrderedMovesForPhase to install your moves, you likely can
	//leave this as nil and have it set correctly. If you want your move to be
	//valid in any phase but don't want them to modify LegalPhases, configure
	//this to be a zero-length slice instead of nil and they'll leave it
	//untouched.
	LegalPhases []int

	//If IsFixUp is true, the moveType will be a FixUp move--that is, players
	//may not propose it, only ProposeFixUp moves may.
	IsFixUp bool

	//CustomConfiguration is an optional PropertyCollection. Some move types--
	//especially in the `moves` package--stash configuration options here that
	//will change how all moves of this type behave. Individual moves would
	//reach through via Info().Type().CustomConfiguration() to retrieve the
	//values stored there. Different move types will store different types of
	//information there--to avoid a collision the convention is to use a
	//string name that starts with your fully qualified package name, then a
	//dot, then the propertyname, like so:
	//"github.com/jkomoros/boardgame/moves.MoveName". Those strings are often
	//encoded as package-private constants, and a
	//interfaces.CustomConfigurationOption functor factory is provided to set
	//those from outside the package. Generally you don't use this directly,
	//but auto.Config() will help you set these for what specific
	//moves in that package expect.
	CustomConfiguration PropertyCollection
}

//NewMoveType takes a MoveTypeConfig and returns a MoveType associated with
//the given manager. The returned move type will not yet have been added to
//the manager in question. In general you don't call this directly, and
//instead use manager.AddMove, which accepts a MoveTypeConfig.
func (m *MoveTypeConfig) NewMoveType(manager *GameManager) (*MoveType, error) {
	if m == nil {
		return nil, errors.New("No config provided")
	}

	if m.Name == "" {
		return nil, errors.New("No name provided")
	}

	if m.MoveConstructor == nil {
		return nil, errors.New("No MoveConstructor provided")
	}

	exampleMove := m.MoveConstructor()

	if exampleMove == nil {
		return nil, errors.New("MoveConstructor returned nil")
	}

	readSetter := exampleMove.ReadSetter()

	if readSetter == nil {
		return nil, errors.New("MoveConstructor's readsetter returned nil")
	}

	var validator *readerValidator
	var err error

	//moves.Defaultconfig will call this without a manager. So return a half-
	//useful object in that case... but also an error so anyone else who
	//checks the error will ignore the half-useful move type.
	if manager != nil {
		validator, err = newReaderValidator(readSetter, readSetter, exampleMove, moveTypeIllegalPropTypes, manager.Chest(), false)

		if err != nil {
			return nil, errors.New("Couldn't create validator: " + err.Error())
		}
	} else {
		//moves.DefaultConfig hackily looks for exactly this error string.
		err = errors.New("No manager passed, so we can'd do validation")
	}

	return &MoveType{
		name:                m.Name,
		helpText:            m.HelpText,
		constructor:         m.MoveConstructor,
		isFixUp:             m.IsFixUp,
		legalPhases:         m.LegalPhases,
		customConfiguration: m.CustomConfiguration,
		validator:           validator,
		manager:             manager,
	}, err

}

//MoveInfo is an object that contains meta-information about a move.
type MoveInfo struct {
	moveType  *MoveType
	version   int
	initiator int
	timestamp time.Time
}

//Move's are how all modifications are made to Game States after
//initialization. Packages define structs that implement Move for all
//modifications. The Move should be JSON-able (that is, all persistable state
//should be in public fields), and it may not include Timers, Stacks, or
//EnumValues. Use moves.Base for a convenient composable base Move that will
//allow you to skip most of the boilerplate overhead.
type Move interface {

	//Info returns the MoveInfo objec that was affiliated with this object by
	//SetInfo.
	Info() *MoveInfo

	//Legal returns nil if this proposed move is legal, or an error if the
	//move is not legal. The error message may be shown directly to the end-
	//user so be sure to make it user friendly. proposer is set to the
	//notional player that is proposing the move. proposer might be a valid
	//player index, or AdminPlayerIndex (for example, if it is a FixUpMove it
	//will typically be AdminPlayerIndex). AdminPlayerIndex is always allowed
	//to make any move. It will never be ObserverPlayerIndex, because by
	//definition Observers may not make moves. If you want to check that the
	//person proposing is able to apply the move for the given player, and
	//that it is their turn, you would do something like test
	//m.TargetPlayerIndex.Equivalent(proposer),
	//m.TargetPlayerIndex.Equivalent(game.CurrentPlayer).
	Legal(state State, proposer PlayerIndex) error

	//Apply applies the move to the state. It is handed a copy of the state to
	//modify. If error is non-nil it will not be applied to the game. It
	//should not be called directly; use Game.ProposeMove.
	Apply(state MutableState) error

	//Sets the move to have reasonable defaults for the given state.For
	//example, if the Move has a TargetPlayerIndex property, a reasonable
	//default is state.CurrentPlayer().
	DefaultsForState(state State)

	//Description is a human-readable prose description of the effects that
	//this particular move will have, including any move configuration. For
	//example the Description for "Place Token" might be "Player 0 places a
	//token in position 3".
	Description() string

	//SetInfo will be called after the constructor is called to set the
	//information, including what type the move is. Splitting this out allows
	//the basic constructors not in the base classes to be very small, because
	//in most cases you'll compose a moves.Base.
	SetInfo(m *MoveInfo)

	//TopLevelStruct should return the value that was set via
	//SetTopLevelStruct. It returns the Move that is at the top of the
	//embedding chain (because structs that are embedded anonymously can only
	//access themselves and not their embedders). This is useful because in a
	//number of cases embeded moves (for example moves in the moves package)
	//need to consult a method on their embedder.
	TopLevelStruct() Move

	//SetTopLevelStruct is called right after the move is constructed.
	//Splitting this out allows the basic constructors not in the base classes
	//to be very small, because in most cases you'll compose a moves.Base.
	SetTopLevelStruct(m Move)

	//ValidConfiguration will be checked when the game manager is SetUp, and
	//if it returns an error the manager will fail to SetUp. Some Moves,
	//especially sub-classes of moves in the moves package, require set up
	//that can only be verified at run time (for example, verifying that the
	//embedder implements a certain inteface). This is a useful way to detect
	//those misconfigurations at the earliest moment. In most cases you never
	//need to implement this yourself; moves in the moves package that need it
	//will implement it.
	ValidConfiguration(exampleState MutableState) error

	ReadSetConfigurer
}

//StorageRecordForMove returns a MoveStorageRecord. Can't hang off of Move
//itself since Moves are provided by users of the library.
func StorageRecordForMove(move Move, currentPhase int) *MoveStorageRecord {

	blob, err := json.MarshalIndent(move, "", "\t")

	if err != nil {
		return nil
	}

	return &MoveStorageRecord{
		Name:      move.Info().Type().Name(),
		Version:   move.Info().version,
		Initiator: move.Info().initiator,
		Timestamp: move.Info().timestamp,
		Phase:     currentPhase,
		Blob:      blob,
	}
}

//Type returns the MoveType of this Move.
func (m *MoveInfo) Type() *MoveType {
	return m.moveType
}

//Version returns the version of this move--or the version that it will be
//when successfully committed.
func (m *MoveInfo) Version() int {
	return m.version
}

//Timestamp returns the time that the given move was made.
func (m *MoveInfo) Timestamp() time.Time {
	return m.timestamp
}

//Initiator returns the move version that initiated this causal chain: the
//PlayerMove that was applied that led to this chain of FixUp moves. The
//Initiator of a PlayerMove is its own version, so this value will be less
//than or equal to its own version. The value of Initator is unspecified until
//after the move has been successfully committed.
func (m *MoveInfo) Initiator() int {
	return m.initiator
}

var moveTypeIllegalPropTypes = map[PropertyType]bool{
	TypeStack: true,
	TypeTimer: true,
}

//Name returns the unique name for this type of move.
func (m *MoveType) Name() string {
	return m.name
}

//HelpText is a human-readable sentence describing what the move does.
func (m *MoveType) HelpText() string {
	return m.helpText
}

func (m *MoveType) IsFixUp() bool {
	return m.isFixUp
}

func (m *MoveType) LegalPhases() []int {
	return m.legalPhases
}

//CustomConfiguration returns a copy of the CustomConfiguration passed in via
//the MoveTyepConfig to create this MoveType. See the documentation on
//MoveTypeConfig.CustomConfiguration for more about what it does and what it
//can be used for.
func (m *MoveType) CustomConfiguration() PropertyCollection {
	result := make(PropertyCollection, len(m.customConfiguration))
	for key, val := range m.customConfiguration {
		result[key] = val
	}
	return result
}

//NewMove returns a new move of this type, with defaults set for the given
//state. If state is nil, then DefaultsForState will not be called.
func (m *MoveType) NewMove(state State) Move {
	move := m.constructor()
	if move == nil {
		return nil
	}

	info := &MoveInfo{
		moveType: m,
	}

	if state != nil {
		info.version = state.Version() + 1
	}

	move.SetInfo(info)
	move.SetTopLevelStruct(move)

	readSetConfigurer := move.ReadSetConfigurer()

	if readSetConfigurer == nil {
		//This shouldn't happen because we verified that ReadSetter returned
		//non-nil when the movetype was registered.
		m.manager.Logger().Error("ReadSetConfigurer for move unexpectedly returned nil")
		return nil
	}

	//validator might be nil if we have a half-functioning MoveType. (Like
	//what will be returned, along with an error, when NewMoveType is called
	//during moves.DefaultConfig)
	if m.validator != nil {
		if err := m.validator.AutoInflate(readSetConfigurer, state); err != nil {
			m.manager.Logger().Error("AutoInflate had an error: " + err.Error())
			return nil
		}

		if err := m.validator.Valid(readSetConfigurer); err != nil {
			m.manager.Logger().Error("Move was not valid: " + err.Error())
			return nil
		}
	}

	if state != nil {
		move.DefaultsForState(state)
	}
	return move
}

//We implement a private stub of moves.Base in this package just for the
//convience of our own test structs.
type baseMove struct {
	info           MoveInfo
	topLevelStruct Move
}

func (d *baseMove) SetInfo(m *MoveInfo) {
	d.info = *m
}

func (d *baseMove) Info() *MoveInfo {
	return &d.info
}

func (d *baseMove) SetTopLevelStruct(m Move) {
	d.topLevelStruct = m
}

func (d *baseMove) TopLevelStruct() Move {
	return d.topLevelStruct
}

//DefaultsForState doesn't do anything
func (d *baseMove) DefaultsForState(state State) {
	return
}

//Description defaults to returning the Type's HelpText()
func (d *baseMove) Description() string {
	return d.Info().Type().HelpText()
}

func (d *baseMove) ValidConfiguration(exampleState MutableState) error {
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"sync"

	"github.com/BurntSushi/toml"
	"github.com/mailgun/oxy/forward"
	"github.com/mailgun/oxy/roundrobin"
	"github.com/peterbourgon/g2s"
	"github.com/thoas/stats"
)

type App struct {
	Tasks []string
	Fwd   *forward.Forwarder     `json:"-"`
	Lb    *roundrobin.RoundRobin `json:"-"`
}
type Apps struct {
	sync.RWMutex
	Apps map[string]App
}

var apps Apps

type Config struct {
	Port     string
	Xproxy   string
	Marathon string
	Statsd   string
	Prefix   string
	TLS      bool
	Cert     string
	Key      string
}

var config Config
var statsd g2s.Statter

func moxy_proxy(w http.ResponseWriter, r *http.Request) {
	app := strings.Split(r.Host, ".")[0]
	if s, ok := apps.Apps[app]; ok {
		if config.Statsd != "" {
			go func(app string) {
				statsd.Counter(1.0, config.Prefix+app, 1)
			}(app)
		}
		// let us forward this request to a running container
		if config.Xproxy != "" {
			w.Header().Add("X-Proxy", config.Xproxy)
		}
		s.Lb.ServeHTTP(w, r)
		return
	}
	fmt.Fprintln(w, "moxy")
}

func moxy_callback(w http.ResponseWriter, r *http.Request) {
	log.Println("callback received from Marathon")
	select {
	case callbackqueue <- true: // Add reload to our queue channel, unless it is full of course.
		w.WriteHeader(202)
		fmt.Fprintln(w, "queued")
		return
	default:
		w.WriteHeader(202)
		fmt.Fprintln(w, "queue is full")
		return
	}
}

func moxy_apps(w http.ResponseWriter, r *http.Request) {
	apps.RLock()
	defer apps.RUnlock()
	b, _ := json.MarshalIndent(apps, "", "  ")
	w.Write(b)
	return
}

func main() {
	configtoml := flag.String("f", "moxy.toml", "Path to config. (default moxy.toml)")
	flag.Parse()
	file, err := ioutil.ReadFile(*configtoml)
	if err != nil {
		log.Fatal(err)
	}
	err = toml.Unmarshal(file, &config)
	if err != nil {
		log.Fatal("Problem parsing config: ", err)
	}
	if config.Statsd != "" {
		statsd, _ = g2s.Dial("udp", config.Statsd)
	}
	moxystats := stats.New()
	mux := http.NewServeMux()
	mux.HandleFunc("/moxy_callback", moxy_callback)
	mux.HandleFunc("/moxy_apps", moxy_apps)
	mux.HandleFunc("/moxy_stats", func(w http.ResponseWriter, req *http.Request) {
		stats := moxystats.Data()
		b, _ := json.MarshalIndent(stats, "", "  ")
		w.Write(b)
		return
	})
	mux.HandleFunc("/", moxy_proxy)
	// In case we want to log req/resp.
	//trace, _ := trace.New(redirect, os.Stdout)
	handler := moxystats.Handler(mux)
	s := &http.Server{
		Addr:    ":" + config.Port,
		Handler: handler,
	}
	callbackworker()
	callbackqueue <- true
	if config.TLS {
		log.Println("Starting moxy tls on :" + config.Port)
		err := s.ListenAndServeTLS(config.Cert, config.Key)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		log.Println("Starting moxy on :" + config.Port)
		err := s.ListenAndServe()
		if err != nil {
			log.Fatal(err)
		}
	}
}
<commit_msg>added x-proxy to all requests and removed another mutex lock<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"sync"

	"github.com/BurntSushi/toml"
	"github.com/mailgun/oxy/forward"
	"github.com/mailgun/oxy/roundrobin"
	"github.com/peterbourgon/g2s"
	"github.com/thoas/stats"
)

type App struct {
	Tasks []string
	Fwd   *forward.Forwarder     `json:"-"`
	Lb    *roundrobin.RoundRobin `json:"-"`
}
type Apps struct {
	sync.RWMutex
	Apps map[string]App
}

var apps Apps

type Config struct {
	Port     string
	Xproxy   string
	Marathon string
	Statsd   string
	Prefix   string
	TLS      bool
	Cert     string
	Key      string
}

var config Config
var statsd g2s.Statter

func moxy_proxy(w http.ResponseWriter, r *http.Request) {
	app := strings.Split(r.Host, ".")[0]
	if config.Xproxy != "" {
		w.Header().Add("X-Proxy", config.Xproxy)
	}
	if s, ok := apps.Apps[app]; ok {
		if config.Statsd != "" {
			go func(app string) {
				statsd.Counter(1.0, config.Prefix+app, 1)
			}(app)
		}
		// let us forward this request to a running container
		s.Lb.ServeHTTP(w, r)
		return
	}
	fmt.Fprintln(w, "moxy")
}

func moxy_callback(w http.ResponseWriter, r *http.Request) {
	log.Println("callback received from Marathon")
	if config.Xproxy != "" {
		w.Header().Add("X-Proxy", config.Xproxy)
	}
	select {
	case callbackqueue <- true: // Add reload to our queue channel, unless it is full of course.
		w.WriteHeader(202)
		fmt.Fprintln(w, "queued")
		return
	default:
		w.WriteHeader(202)
		fmt.Fprintln(w, "queue is full")
		return
	}
}

func moxy_apps(w http.ResponseWriter, r *http.Request) {
	if config.Xproxy != "" {
		w.Header().Add("X-Proxy", config.Xproxy)
	}
	b, _ := json.MarshalIndent(apps, "", "  ")
	w.Write(b)
	return
}

func main() {
	configtoml := flag.String("f", "moxy.toml", "Path to config. (default moxy.toml)")
	flag.Parse()
	file, err := ioutil.ReadFile(*configtoml)
	if err != nil {
		log.Fatal(err)
	}
	err = toml.Unmarshal(file, &config)
	if err != nil {
		log.Fatal("Problem parsing config: ", err)
	}
	if config.Statsd != "" {
		statsd, _ = g2s.Dial("udp", config.Statsd)
	}
	moxystats := stats.New()
	mux := http.NewServeMux()
	mux.HandleFunc("/moxy_callback", moxy_callback)
	mux.HandleFunc("/moxy_apps", moxy_apps)
	mux.HandleFunc("/moxy_stats", func(w http.ResponseWriter, req *http.Request) {
		stats := moxystats.Data()
		b, _ := json.MarshalIndent(stats, "", "  ")
		w.Write(b)
		return
	})
	mux.HandleFunc("/", moxy_proxy)
	// In case we want to log req/resp.
	//trace, _ := trace.New(redirect, os.Stdout)
	handler := moxystats.Handler(mux)
	s := &http.Server{
		Addr:    ":" + config.Port,
		Handler: handler,
	}
	callbackworker()
	callbackqueue <- true
	if config.TLS {
		log.Println("Starting moxy tls on :" + config.Port)
		err := s.ListenAndServeTLS(config.Cert, config.Key)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		log.Println("Starting moxy on :" + config.Port)
		err := s.ListenAndServe()
		if err != nil {
			log.Fatal(err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"github.com/mehrdadrad/myping/cli"
	"github.com/mehrdadrad/myping/icmp"
	"github.com/mehrdadrad/myping/icmp/telia"
	"net"
	"regexp"
	"strings"
)

type Provider interface {
	Set(host, version string)
	GetDefaultNode() string
	GetNodes() map[string]string
	ChangeNode(node string)
	Ping() (string, error)
}

var providers = map[string]Provider{"telia": new(telia.Provider)}

func validateProvider(p string) (string, error) {
	match, _ := regexp.MatchString("(telia|level3)", p)
	p = strings.ToLower(p)
	if match {
		return p, nil
	} else {
		return "", errors.New("provider not support")
	}
}

func main() {
	var (
		err    error
		cPName string = "local"
	)

	rep := make(chan string, 1)
	cmd := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(cmd, nxt)

	r, _ := regexp.Compile(`(ping|connect|node|local) (.*)`)

	for {
		select {
		case req := <-cmd:
			subReq := r.FindStringSubmatch(req)
			if len(subReq) == 0 {
				println("syntax error")
				nxt <- struct{}{}
				continue
			}
			switch {
			case subReq[1] == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", subReq[2])
				if err != nil {
					println("cannot resolve", subReq[2], ": Unknown host")
					nxt <- struct{}{}
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				nxt <- struct{}{}
			case subReq[1] == "ping":
				providers[cPName].Set(subReq[2], "ipv4")
				m, _ := providers[cPName].Ping()
				println(m)
				nxt <- struct{}{}
			case subReq[1] == "node":
				providers[cPName].ChangeNode(subReq[2])
				c.SetPrompt(cPName + "/" + subReq[2])
				nxt <- struct{}{}
			case subReq[1] == "local":
				cPName = "local"
				c.SetPrompt(cPName)
				nxt <- struct{}{}
			case subReq[1] == "connect":
				var pName string
				if pName, err = validateProvider(subReq[2]); err != nil {
					println("provider not available")
					nxt <- struct{}{}
					continue
				}
				cPName = pName
				c.SetPrompt(cPName + "/" + providers[cPName].GetDefaultNode())
				nxt <- struct{}{}
			}
		}
	}
}
<commit_msg>switch to lg package<commit_after>package main

import (
	"errors"
	"github.com/mehrdadrad/mylg/cli"
	"github.com/mehrdadrad/mylg/icmp"
	"github.com/mehrdadrad/mylg/lg"
	"net"
	"regexp"
	"strings"
)

type Provider interface {
	Set(host, version string)
	GetDefaultNode() string
	GetNodes() map[string]string
	ChangeNode(node string)
	Ping() (string, error)
}

var providers = map[string]Provider{"telia": new(lg.Telia), "level3": new(lg.Level3)}

func validateProvider(p string) (string, error) {
	match, _ := regexp.MatchString("(telia|level3)", p)
	p = strings.ToLower(p)
	if match {
		return p, nil
	} else {
		return "", errors.New("provider not support")
	}
}

func main() {
	var (
		err    error
		cPName string = "local"
	)

	rep := make(chan string, 1)
	cmd := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(cmd, nxt)

	r, _ := regexp.Compile(`(ping|connect|node|local) (.*)`)

	for {
		select {
		case req := <-cmd:
			subReq := r.FindStringSubmatch(req)
			if len(subReq) == 0 {
				println("syntax error")
				nxt <- struct{}{}
				continue
			}
			switch {
			case subReq[1] == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", subReq[2])
				if err != nil {
					println("cannot resolve", subReq[2], ": Unknown host")
					nxt <- struct{}{}
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				nxt <- struct{}{}
			case subReq[1] == "ping":
				providers[cPName].Set(subReq[2], "ipv4")
				m, _ := providers[cPName].Ping()
				println(m)
				nxt <- struct{}{}
			case subReq[1] == "node":
				providers[cPName].ChangeNode(subReq[2])
				c.SetPrompt(cPName + "/" + subReq[2])
				nxt <- struct{}{}
			case subReq[1] == "local":
				cPName = "local"
				c.SetPrompt(cPName)
				nxt <- struct{}{}
			case subReq[1] == "connect":
				var pName string
				if pName, err = validateProvider(subReq[2]); err != nil {
					println("provider not available")
					nxt <- struct{}{}
					continue
				}
				cPName = pName
				c.SetPrompt(cPName + "/" + providers[cPName].GetDefaultNode())
				nxt <- struct{}{}
			}
		}
	}
}
<|endoftext|>