<commit_before>// Copyright 2016 Comcast Cable Communications Management, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// End Copyright

package money

import (
	"fmt"
	"strconv"
	"strings"
	"time"
)

const (
	HEADER = "Money"
)

type Money struct {
	spanId       int64
	traceId      string
	parentId     int64
	spanName     string
	startTime    time.Time
	spanDuration int64
	errorCode    int
	spanSuccess  bool
}

func (mny *Money) showme() {
	fmt.Printf("spanId:       %d\n", mny.spanId)
	fmt.Printf("traceId:      %s\n", mny.traceId)
	fmt.Printf("parentId:     %d\n", mny.parentId)
	fmt.Printf("spanName:     %s\n", mny.spanName)
	fmt.Printf("startTime:    %v\n", mny.startTime)
	fmt.Printf("spanDuration: %v\n", mny.spanDuration)
	fmt.Printf("errorCode:    %d\n", mny.errorCode)
	fmt.Printf("spanSuccess:  %v\n", mny.spanSuccess)
}

func StringToObject(headerValue string) *Money {
	var mny Money

	pairs := strings.Split(strings.TrimSuffix(headerValue, ";"), ";")
	for p := 0; p < len(pairs); p++ {
		kv := strings.SplitN(pairs[p], "=", 2)

		if len(kv) == 2 {
			key := strings.TrimSpace(kv[0])
			val := strings.TrimSpace(kv[1])

			switch key {
			case "span-id":
				i, err := strconv.ParseInt(val, 10, 64)
				if err != nil {
					log.Error("Unable to convert Money span-id string value to int64: %s", val)
				}
				mny.spanId = int64(i)

			case "trace-id":
				mny.traceId = val

			case "parent-id":
				i, err := strconv.ParseInt(val, 10, 64)
				if err != nil {
					log.Error("Unable to convert Money parent-id string value to int64: %s", val)
				}
				mny.parentId = int64(i)

			case "span-name":
				mny.spanName = val

			case "start-time":
				t, err := time.Parse(time.RFC3339Nano, val)
				if err != nil {
					log.Error("Unable to convert Money start-time string value to time: %s", val)
				}
				mny.startTime = t

			case "span-duration":
				i, err := strconv.ParseInt(val, 10, 64)
				if err != nil {
					log.Error("Unable to convert Money span-duration string value to int64: %s", val)
				}
				mny.spanDuration = i

			case "error-code":
				i, err := strconv.ParseInt(val, 10, 0)
				if err != nil {
					log.Error("Unable to convert Money error-code string value to int: %s", val)
				}
				mny.errorCode = int(i)

			case "span-success":
				b, err := strconv.ParseBool(val)
				if err != nil {
					log.Error("Unable to convert Money span-success string value to bool: %s", val)
				}
				mny.spanSuccess = b

			case "http-response":
				log.Debug("Money key ignored: %s", key)

			case "response-duration":
				log.Debug("Money key ignored: %s", key)

			default:
				log.Debug("Money key unknown: %s", key)
			}
		} else {
			log.Error("Money header, bad key/value pair: %v.  Header: %v", kv, headerValue)
		}
	}

	return &mny
}

func (mny *Money) ToString() string {
	var result string

	result = "span-id=" + strconv.FormatInt(int64(mny.spanId), 10)
	result += ";trace-id=" + mny.traceId
	result += ";parent-id=" + strconv.FormatInt(int64(mny.parentId), 10)
	result += ";span-name=" + mny.spanName
	result += ";start-time=" + mny.startTime.Format(time.RFC3339Nano)
	result += ";span-duration=" + strconv.FormatInt(int64(mny.spanDuration), 10)
	result += ";error-code=" + strconv.FormatInt(int64(mny.errorCode), 10)
	result += ";span-success=" + strconv.FormatBool(mny.spanSuccess)

	return result
}

func newSpanId(parentid int64) int64 {
	return parentid + 1
}

func (mny *Money) AddResults(errorCode int, spanSuccess bool) *Money {
	mny.errorCode = errorCode
	mny.spanSuccess = spanSuccess
	mny.spanDuration = int64(time.Since(mny.startTime) / time.Microsecond)

	return mny
}

func NewChild(parentHeader, spanName string) *Money {
	pMNY := StringToObject(parentHeader)
	cMNY := new(Money)

	cMNY.spanId = newSpanId(pMNY.spanId)
	cMNY.traceId = pMNY.traceId
	cMNY.parentId = pMNY.spanId
	cMNY.spanName = spanName
	cMNY.startTime = time.Now().UTC()

	return cMNY
}
<commit_msg>set functions added<commit_after>// Copyright 2016 Comcast Cable Communications Management, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// End Copyright

package money

import (
	"fmt"
	"strconv"
	"strings"
	"time"
)

const (
	HEADER = "Money"
)

type Money struct {
	spanId       int64
	traceId      string
	parentId     int64
	spanName     string
	startTime    time.Time
	spanDuration int64
	errorCode    int
	spanSuccess  bool
}

func (mny *Money) showme() {
	fmt.Printf("spanId:       %d\n", mny.spanId)
	fmt.Printf("traceId:      %s\n", mny.traceId)
	fmt.Printf("parentId:     %d\n", mny.parentId)
	fmt.Printf("spanName:     %s\n", mny.spanName)
	fmt.Printf("startTime:    %v\n", mny.startTime)
	fmt.Printf("spanDuration: %v\n", mny.spanDuration)
	fmt.Printf("errorCode:    %d\n", mny.errorCode)
	fmt.Printf("spanSuccess:  %v\n", mny.spanSuccess)
}

func (m *Money) setSpanId(val int64)        {m.spanId = val}
func (m *Money) setTraceId(val string)      {m.traceId = val}
func (m *Money) setParentId(val int64)      {m.parentId = val}
func (m *Money) setSpanName(val string)     {m.spanName = val}
func (m *Money) setStartTime(val time.Time) {m.startTime = val}
func (m *Money) setSpanDuration(val int64)  {m.spanDuration = val}
func (m *Money) setErrorCode(val int)       {m.errorCode = val}
func (m *Money) setSpanSuccess(val bool)    {m.spanSuccess = val}

func StringToObject(headerValue string) *Money {
	var mny Money

	pairs := strings.Split(strings.TrimSuffix(headerValue, ";"), ";")
	for p := 0; p < len(pairs); p++ {
		kv := strings.SplitN(pairs[p], "=", 2)

		if len(kv) == 2 {
			key := strings.TrimSpace(kv[0])
			val := strings.TrimSpace(kv[1])

			switch key {
			case "span-id":
				i, err := strconv.ParseInt(val, 10, 64)
				if err != nil {
					log.Error("Unable to convert Money span-id string value to int64: %s", val)
				}
				mny.spanId = int64(i)

			case "trace-id":
				mny.traceId = val

			case "parent-id":
				i, err := strconv.ParseInt(val, 10, 64)
				if err != nil {
					log.Error("Unable to convert Money parent-id string value to int64: %s", val)
				}
				mny.parentId = int64(i)

			case "span-name":
				mny.spanName = val

			case "start-time":
				t, err := time.Parse(time.RFC3339Nano, val)
				if err != nil {
					log.Error("Unable to convert Money start-time string value to time: %s", val)
				}
				mny.startTime = t

			case "span-duration":
				i, err := strconv.ParseInt(val, 10, 64)
				if err != nil {
					log.Error("Unable to convert Money span-duration string value to int64: %s", val)
				}
				mny.spanDuration = i

			case "error-code":
				i, err := strconv.ParseInt(val, 10, 0)
				if err != nil {
					log.Error("Unable to convert Money error-code string value to int: %s", val)
				}
				mny.errorCode = int(i)

			case "span-success":
				b, err := strconv.ParseBool(val)
				if err != nil {
					log.Error("Unable to convert Money span-success string value to bool: %s", val)
				}
				mny.spanSuccess = b

			case "http-response":
				log.Debug("Money key ignored: %s", key)

			case "response-duration":
				log.Debug("Money key ignored: %s", key)

			default:
				log.Debug("Money key unknown: %s", key)
			}
		} else {
			log.Error("Money header, bad key/value pair: %v.  Header: %v", kv, headerValue)
		}
	}

	return &mny
}

func (mny *Money) ToString() string {
	var result string

	result = "span-id=" + strconv.FormatInt(int64(mny.spanId), 10)
	result += ";trace-id=" + mny.traceId
	result += ";parent-id=" + strconv.FormatInt(int64(mny.parentId), 10)
	result += ";span-name=" + mny.spanName
	result += ";start-time=" + mny.startTime.Format(time.RFC3339Nano)
	result += ";span-duration=" + strconv.FormatInt(int64(mny.spanDuration), 10)
	result += ";error-code=" + strconv.FormatInt(int64(mny.errorCode), 10)
	result += ";span-success=" + strconv.FormatBool(mny.spanSuccess)

	return result
}

func newSpanId(parentid int64) int64 {
	return parentid + 1
}

func (mny *Money) AddResults(errorCode int, spanSuccess bool) *Money {
	mny.errorCode = errorCode
	mny.spanSuccess = spanSuccess
	mny.spanDuration = int64(time.Since(mny.startTime) / time.Microsecond)

	return mny
}

func NewChild(parentHeader, spanName string) *Money {
	pMNY := StringToObject(parentHeader)
	cMNY := new(Money)

	cMNY.spanId = newSpanId(pMNY.spanId)
	cMNY.traceId = pMNY.traceId
	cMNY.parentId = pMNY.spanId
	cMNY.spanName = spanName
	cMNY.startTime = time.Now().UTC()

	return cMNY
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.5"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.Parse()

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	var wg sync.WaitGroup
	wg.Add(1)
	defer wg.Wait()

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		defer wg.Done()
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.6 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.6"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.Parse()

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	var wg sync.WaitGroup
	wg.Add(1)
	defer wg.Wait()

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		defer wg.Done()
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.50"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.17", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.51 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.51"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.18", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"

	"github.com/cloudcredo/cloudfocker/focker"
	"github.com/codegangsta/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "fock"
	app.Version = "0.0.1"
	app.Usage = "Cloud Focker - fock the Cloud, run apps locally!"
	app.Action = func(c *cli.Context) {
		cli.ShowAppHelp(c)
	}

	app.Commands = []cli.Command{
		{
			Name:  "docker",
			Usage: "print the local Docker info",
			Action: func(c *cli.Context) {
				focker.DockerVersion(os.Stdout)
			},
		},
		{
			Name:  "this",
			Usage: "download the Cloud Foundry base image",
			Action: func(c *cli.Context) {
				focker.ImportRootfsImage(os.Stdout)
			},
		},
		{
			Name:  "up",
			Usage: "stage and run the application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if err := focker.RunStager(os.Stdout); err != nil {
					log.Fatalf(" %s", err)
				}
				focker.RunRuntime(os.Stdout)
			},
		},
		{
			Name:  "build",
			Usage: "build a runnable image of the application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.BuildRuntimeImage(os.Stdout)
			},
		},
		{
			Name:  "off",
			Usage: "stop the application container and remove it",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.StopRuntime(os.Stdout)
			},
		},
		{
			Name:  "buildpacks",
			Usage: "show the buildpacks installed on the local system",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.ListBuildpacks(os.Stdout)
			},
		},
		{
			Name:  "add-buildpack",
			Usage: "add-buildpack [URL] - add a buildpack from a GitHub URL to the local system",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if url := c.Args().First(); url != "" {
					focker.AddBuildpack(os.Stdout, url)
				} else {
					fmt.Println("Please supply a GitHub URL to download")
				}
			},
		},
		{
			Name:  "delete-buildpack",
			Usage: "delete-buildpack [BUILDPACK] - delete a buildpack from the local system",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if buildpack := c.Args().First(); buildpack != "" {
					focker.DeleteBuildpack(os.Stdout, buildpack)
				} else {
					fmt.Println("Please supply a buildpack to delete")
				}
			},
		},
		{
			Name:  "stage",
			Usage: "only execute the staging phase for the application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if internal := c.Args().First(); internal == "internal" {
					//this is focker being called inside the staging container
					focker.StageApp(os.Stdout)
				} else {
					//this is focker being called by the user, outside of the staging container
					if err := focker.RunStager(os.Stdout); err != nil {
						log.Fatalf(" %s", err)
					}
				}
			},
		},
		{
			Name:  "run",
			Usage: "only run the current staged application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.RunRuntime(os.Stdout)
			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>Stage before we build an image<commit_after>package main

import (
	"fmt"
	"log"
	"os"

	"github.com/cloudcredo/cloudfocker/focker"
	"github.com/codegangsta/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "fock"
	app.Version = "0.0.1"
	app.Usage = "Cloud Focker - fock the Cloud, run apps locally!"
	app.Action = func(c *cli.Context) {
		cli.ShowAppHelp(c)
	}

	app.Commands = []cli.Command{
		{
			Name:  "docker",
			Usage: "print the local Docker info",
			Action: func(c *cli.Context) {
				focker.DockerVersion(os.Stdout)
			},
		},
		{
			Name:  "this",
			Usage: "download the Cloud Foundry base image",
			Action: func(c *cli.Context) {
				focker.ImportRootfsImage(os.Stdout)
			},
		},
		{
			Name:  "up",
			Usage: "stage and run the application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if err := focker.RunStager(os.Stdout); err != nil {
					log.Fatalf(" %s", err)
				}
				focker.RunRuntime(os.Stdout)
			},
		},
		{
			Name:  "build",
			Usage: "build a runnable image of the application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if err := focker.RunStager(os.Stdout); err != nil {
					log.Fatalf(" %s", err)
				}
				focker.BuildRuntimeImage(os.Stdout)
			},
		},
		{
			Name:  "off",
			Usage: "stop the application container and remove it",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.StopRuntime(os.Stdout)
			},
		},
		{
			Name:  "buildpacks",
			Usage: "show the buildpacks installed on the local system",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.ListBuildpacks(os.Stdout)
			},
		},
		{
			Name:  "add-buildpack",
			Usage: "add-buildpack [URL] - add a buildpack from a GitHub URL to the local system",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if url := c.Args().First(); url != "" {
					focker.AddBuildpack(os.Stdout, url)
				} else {
					fmt.Println("Please supply a GitHub URL to download")
				}
			},
		},
		{
			Name:  "delete-buildpack",
			Usage: "delete-buildpack [BUILDPACK] - delete a buildpack from the local system",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if buildpack := c.Args().First(); buildpack != "" {
					focker.DeleteBuildpack(os.Stdout, buildpack)
				} else {
					fmt.Println("Please supply a buildpack to delete")
				}
			},
		},
		{
			Name:  "stage",
			Usage: "only execute the staging phase for the application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				if internal := c.Args().First(); internal == "internal" {
					//this is focker being called inside the staging container
					focker.StageApp(os.Stdout)
				} else {
					//this is focker being called by the user, outside of the staging container
					if err := focker.RunStager(os.Stdout); err != nil {
						log.Fatalf(" %s", err)
					}
				}
			},
		},
		{
			Name:  "run",
			Usage: "only run the current staged application",
			Action: func(c *cli.Context) {
				focker := focker.NewFocker()
				focker.RunRuntime(os.Stdout)
			},
		},
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package form

import (
	"math"
	"reflect"
	"testing"
)

func TestCreateTypeMap(t *testing.T) {
	for n, test := range [...]struct {
		Input  reflect.Type
		Output typeMap
	}{
		{ // 1
			Input: reflect.TypeOf(struct {
				A int
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 2
			Input: reflect.TypeOf(struct {
				A int `form:"B"`
			}{}),
			Output: typeMap{
				"B": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 3
			Input: reflect.TypeOf(struct {
				A int `form:",required"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Required: true,
					Index:    []int{0},
				},
			},
		},
		{ // 4
			Input: reflect.TypeOf(struct {
				A int `form:",post"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Post:  true,
					Index: []int{0},
				},
			},
		},
		{ // 5
			Input: reflect.TypeOf(struct {
				A int `form:",post,required"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Post:     true,
					Required: true,
					Index:    []int{0},
				},
			},
		},
		{ // 6
			Input: reflect.TypeOf(struct {
				A int `form:",required,post"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Post:     true,
					Required: true,
					Index:    []int{0},
				},
			},
		},
		{ // 7
			Input: reflect.TypeOf(struct {
				A int `min:"-20"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  -20,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 8
			Input: reflect.TypeOf(struct {
				A int `max:"-20"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  -20,
					},
					Index: []int{0},
				},
			},
		},
		{ // 9
			Input: reflect.TypeOf(struct {
				A int8
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 8,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 10
			Input: reflect.TypeOf(struct {
				A int16
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 16,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 11
			Input: reflect.TypeOf(struct {
				A int32
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 32,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 12
			Input: reflect.TypeOf(struct {
				A int64
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 13
			Input: reflect.TypeOf(struct {
				A uint
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 14
			Input: reflect.TypeOf(struct {
				A uint `min:"10"`
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						min:  10,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 15
			Input: reflect.TypeOf(struct {
				A uint `min:"-1"`
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 16
			Input: reflect.TypeOf(struct {
				A uint `max:"100"`
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  100,
					},
					Index: []int{0},
				},
			},
		},
		{ // 17
			Input: reflect.TypeOf(struct {
				A uint8
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 8,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 18
			Input: reflect.TypeOf(struct {
				A uint16
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 16,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 19
			Input: reflect.TypeOf(struct {
				A uint32
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 32,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 20
			Input: reflect.TypeOf(struct {
				A uint
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 21
			Input: reflect.TypeOf(struct {
				A float32
			}{}),
			Output: typeMap{
				"A": {
					processor: float{
						bits: 32,
						min:  -math.MaxFloat64,
						max:  math.MaxFloat64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 22
			Input: reflect.TypeOf(struct {
				A float64
			}{}),
			Output: typeMap{
				"A": {
					processor: float{
						bits: 64,
						min:  -math.MaxFloat64,
						max:  math.MaxFloat64,
					},
					Index: []int{0},
				},
			},
		},
	} {
		output := createTypeMap(test.Input)
		if !reflect.DeepEqual(output, test.Output) {
			t.Errorf("test %d: expecting output %v, got %v", n+1, test.Output, output)
		}
	}
}
<commit_msg>added float min/max tests<commit_after>package form

import (
	"math"
	"reflect"
	"testing"
)

func TestCreateTypeMap(t *testing.T) {
	for n, test := range [...]struct {
		Input  reflect.Type
		Output typeMap
	}{
		{ // 1
			Input: reflect.TypeOf(struct {
				A int
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 2
			Input: reflect.TypeOf(struct {
				A int `form:"B"`
			}{}),
			Output: typeMap{
				"B": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 3
			Input: reflect.TypeOf(struct {
				A int `form:",required"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Required: true,
					Index:    []int{0},
				},
			},
		},
		{ // 4
			Input: reflect.TypeOf(struct {
				A int `form:",post"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Post:  true,
					Index: []int{0},
				},
			},
		},
		{ // 5
			Input: reflect.TypeOf(struct {
				A int `form:",post,required"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Post:     true,
					Required: true,
					Index:    []int{0},
				},
			},
		},
		{ // 6
			Input: reflect.TypeOf(struct {
				A int `form:",required,post"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Post:     true,
					Required: true,
					Index:    []int{0},
				},
			},
		},
		{ // 7
			Input: reflect.TypeOf(struct {
				A int `min:"-20"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  -20,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 8
			Input: reflect.TypeOf(struct {
				A int `max:"-20"`
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  -20,
					},
					Index: []int{0},
				},
			},
		},
		{ // 9
			Input: reflect.TypeOf(struct {
				A int8
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 8,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 10
			Input: reflect.TypeOf(struct {
				A int16
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 16,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 11
			Input: reflect.TypeOf(struct {
				A int32
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 32,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 12
			Input: reflect.TypeOf(struct {
				A int64
			}{}),
			Output: typeMap{
				"A": {
					processor: inum{
						bits: 64,
						min:  math.MinInt64,
						max:  math.MaxInt64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 13
			Input: reflect.TypeOf(struct {
				A uint
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 14
			Input: reflect.TypeOf(struct {
				A uint `min:"10"`
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						min:  10,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 15
			Input: reflect.TypeOf(struct {
				A uint `min:"-1"`
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 16
			Input: reflect.TypeOf(struct {
				A uint `max:"100"`
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  100,
					},
					Index: []int{0},
				},
			},
		},
		{ // 17
			Input: reflect.TypeOf(struct {
				A uint8
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 8,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 18
			Input: reflect.TypeOf(struct {
				A uint16
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 16,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 19
			Input: reflect.TypeOf(struct {
				A uint32
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 32,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 20
			Input: reflect.TypeOf(struct {
				A uint
			}{}),
			Output: typeMap{
				"A": {
					processor: unum{
						bits: 64,
						max:  math.MaxUint64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 21
			Input: reflect.TypeOf(struct {
				A float32
			}{}),
			Output: typeMap{
				"A": {
					processor: float{
						bits: 32,
						min:  -math.MaxFloat64,
						max:  math.MaxFloat64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 22
			Input: reflect.TypeOf(struct {
				A float64
			}{}),
			Output: typeMap{
				"A": {
					processor: float{
						bits: 64,
						min:  -math.MaxFloat64,
						max:  math.MaxFloat64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 23
			Input: reflect.TypeOf(struct {
				A float64 `min:"-10"`
			}{}),
			Output: typeMap{
				"A": {
					processor: float{
						bits: 64,
						min:  -10,
						max:  math.MaxFloat64,
					},
					Index: []int{0},
				},
			},
		},
		{ // 24
			Input: reflect.TypeOf(struct {
				A float64 `max:"10"`
			}{}),
			Output: typeMap{
				"A": {
					processor: float{
						bits: 64,
						min:  -math.MaxFloat64,
						max:  10,
					},
					Index: []int{0},
				},
			},
		},
	} {
		output := createTypeMap(test.Input)
		if !reflect.DeepEqual(output, test.Output) {
			t.Errorf("test %d: expecting output %v, got %v", n+1, test.Output, output)
		}
	}
}
<|endoftext|>


<commit_before>package textformatter

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"

	"github.com/mgutz/ansi"
	"github.com/sirupsen/logrus"
	"golang.org/x/crypto/ssh/terminal"
)

const defaultTimestampFormat = time.RFC3339Nano

type ColorScheme struct {
	Debug  string
	Info   string
	Warn   string
	Error  string
	Fatal  string
	Panic  string
	Tag    string
	Prefix string
	Func   string
}

type colorFunc func(string) string

type compiledColorScheme struct {
	Debug  colorFunc
	Info   colorFunc
	Warn   colorFunc
	Error  colorFunc
	Fatal  colorFunc
	Panic  colorFunc
	Tag    colorFunc
	Prefix colorFunc
	Func   colorFunc
}

type Instance struct {
	// Use colors if TTY detected
	UseColors bool

	// Disable timestamp logging. useful when output is redirected to logging
	// system that already adds timestamps.
	DisableTimestamp bool

	// Print level names in `lowercase` instead of `UPPERCASE`
	LowercaseLevels bool

	// Enable logging the full timestamp when a TTY is attached instead of just
	// the time passed since beginning of execution.
	FullTimestamp bool

	// Timestamp format to use for display when a full timestamp is printed.
	TimestampFormat string

	colorScheme *compiledColorScheme
}

func nocolor(v string) string {
	return v
}

var (
	baseTimestamp time.Time    = time.Now()
	defaultColors *ColorScheme = &ColorScheme{
		Debug:  "black+h",
		Info:   "white",
		Warn:   "yellow+h",
		Error:  "red+h",
		Fatal:  "red+h",
		Panic:  "red+h",
		Tag:    "magenta",
		Prefix: "cyan",
		Func:   "cyan+h",
	}
	noColors *compiledColorScheme = &compiledColorScheme{
		Debug:  nocolor,
		Info:   nocolor,
		Warn:   nocolor,
		Error:  nocolor,
		Fatal:  nocolor,
		Panic:  nocolor,
		Tag:    nocolor,
		Prefix: nocolor,
		Func:   nocolor,
	}
	defaultCompiledColorScheme *compiledColorScheme = compileColorScheme(defaultColors)
)

func miniTS() float64 {
	return time.Since(baseTimestamp).Seconds()
}

func getCompiledColor(main string, fallback string) colorFunc {
	var style string
	if main != "" {
		style = main
	} else {
		style = fallback
	}
	return ansi.ColorFunc(style)
}

func compileColorScheme(s *ColorScheme) *compiledColorScheme {
	return &compiledColorScheme{
		Info:   getCompiledColor(s.Info, defaultColors.Info),
		Warn:   getCompiledColor(s.Warn, defaultColors.Warn),
		Error:  getCompiledColor(s.Error, defaultColors.Error),
		Fatal:  getCompiledColor(s.Fatal, defaultColors.Fatal),
		Panic:  getCompiledColor(s.Panic, defaultColors.Panic),
		Debug:  getCompiledColor(s.Debug, defaultColors.Debug),
		Tag:    getCompiledColor(s.Tag, defaultColors.Tag),
		Prefix: getCompiledColor(s.Prefix, defaultColors.Prefix),
		Func:   getCompiledColor(s.Func, defaultColors.Func),
	}
}

func (f *Instance) checkIfTerminal(w io.Writer) bool {
	switch v := w.(type) {
	case *os.File:
		return terminal.IsTerminal(int(v.Fd()))
	default:
		return false
	}
}

func (f *Instance) SetColorScheme(colorScheme *ColorScheme) {
	f.colorScheme = compileColorScheme(colorScheme)
}

func (f *Instance) Format(entry *logrus.Entry) ([]byte, error) {
	var buf *bytes.Buffer
	if entry.Buffer != nil {
		buf = entry.Buffer
	} else {
		buf = &bytes.Buffer{}
	}

	timestampFormat := f.TimestampFormat
	if timestampFormat == "" {
		timestampFormat = defaultTimestampFormat
	}
	var colors *compiledColorScheme
	if f.UseColors {
		if f.colorScheme == nil {
			f.colorScheme = defaultCompiledColorScheme
		}
		colors = f.colorScheme
	} else {
		colors = noColors
	}
	var levelColor colorFunc
	var levelText string
	switch entry.Level {
	case logrus.InfoLevel:
		levelColor = colors.Info
	case logrus.WarnLevel:
		levelColor = colors.Warn
	case logrus.ErrorLevel:
		levelColor = colors.Error
	case logrus.FatalLevel:
		levelColor = colors.Fatal
	case logrus.PanicLevel:
		levelColor = colors.Panic
	default:
		levelColor = colors.Debug
	}

	if entry.Level != logrus.WarnLevel {
		levelText = entry.Level.String()
	} else {
		levelText = "warn"
	}

	if !f.LowercaseLevels {
		levelText = strings.ToUpper(levelText)
	}

	if !f.DisableTimestamp {
		var ts string
		if !f.FullTimestamp {
			ts = fmt.Sprintf("[%f]", miniTS())
		} else {
			ts = entry.Time.Format(timestampFormat)
		}
		fmt.Fprint(buf, levelColor(ts), " ")
	}

	fmt.Fprint(buf, levelColor(fmt.Sprintf("%5s", levelText)), " ")

	tv := "-"
	if v, ok := entry.Data["__t"]; ok {
		if tv, ok = v.(string); !ok {
			tv = fmt.Sprintf("%#v", v)
		}
	}
	fmt.Fprint(buf, colors.Tag(fmt.Sprintf("% 16s", tv)), " ")

	if v, ok := entry.Data["__p"]; ok {
		switch v.(type) {
		case string, fmt.Stringer:
			fmt.Fprint(buf, colors.Prefix(fmt.Sprintf("%s", v)))
		default:
			fmt.Fprint(buf, colors.Prefix(fmt.Sprintf("%T", v)))
		}
	} else {
		fmt.Fprint(buf, colors.Prefix("__p<missing>"))
	}

	if v, ok := entry.Data["__f"]; ok {
		fmt.Fprint(buf, " ", colors.Func(fmt.Sprintf("%v", v)))
	}
	fmt.Fprint(buf, "\t", levelColor(entry.Message), "\t")

	if v, ok := entry.Data[logrus.ErrorKey]; ok {
		printField(buf, logrus.ErrorKey, v, colors.Prefix, levelColor)
	}

	keys := make([]string, 0, len(entry.Data))
	for k := range entry.Data {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, k := range keys {
		if k == "__p" || k == "__f" || k == "__t" || k == logrus.ErrorKey {
			continue
		}
		v := entry.Data[k]
		printField(buf, k, v, colors.Prefix, levelColor)
	}
	buf.WriteRune('\n')
	return buf.Bytes(), nil
}

func printField(buf *bytes.Buffer, k string, v interface{}, kcolor, vcolor colorFunc) {
	switch w := v.(type) {
	case fmt.Stringer:
		fmt.Fprintf(buf, " %s=%s", kcolor(k), vcolor(w.String()))
	case error:
		s := w.Error()
		r, n := utf8.DecodeRuneInString(s)
		fmt.Fprintf(buf, " %s=%s", kcolor(k), vcolor(fmt.Sprintf("%q", string(unicode.ToUpper(r))+s[n:]+"!")))
	default:
		fmt.Fprintf(buf, " %s=%s", kcolor(k), vcolor(fmt.Sprintf("%#v", v)))
	}
}
<commit_msg>Configurable magic fields names<commit_after>package textformatter

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"sync"
	"time"
	"unicode"
	"unicode/utf8"

	"github.com/mgutz/ansi"
	"github.com/sirupsen/logrus"
	"golang.org/x/crypto/ssh/terminal"
)

const defaultTimestampFormat = time.RFC3339Nano

type ColorScheme struct {
	Debug  string
	Info   string
	Warn   string
	Error  string
	Fatal  string
	Panic  string
	Tag    string
	Prefix string
	Func   string
}

type colorFunc func(string) string

type compiledColorScheme struct {
	Debug  colorFunc
	Info   colorFunc
	Warn   colorFunc
	Error  colorFunc
	Fatal  colorFunc
	Panic  colorFunc
	Tag    colorFunc
	Prefix colorFunc
	Func   colorFunc
}

type Instance struct {
	// Use colors if TTY detected
	UseColors bool

	// Disable timestamp logging. useful when output is redirected to logging
	// system that already adds timestamps.
	DisableTimestamp bool

	// Print level names in `lowercase` instead of `UPPERCASE`
	LowercaseLevels bool

	// Enable logging the full timestamp when a TTY is attached instead of just
	// the time passed since beginning of execution.
	FullTimestamp bool

	// Timestamp format to use for display when a full timestamp is printed.
	TimestampFormat string

	PrefixFieldName string
	TagFieldName    string
	FuncFieldName   string

	colorScheme *compiledColorScheme

	sync.Once
}

func nocolor(v string) string {
	return v
}

var (
	baseTimestamp time.Time    = time.Now()
	defaultColors *ColorScheme = &ColorScheme{
		Debug:  "black+h",
		Info:   "white",
		Warn:   "yellow+h",
		Error:  "red+h",
		Fatal:  "red+h",
		Panic:  "red+h",
		Tag:    "magenta",
		Prefix: "cyan",
		Func:   "cyan+h",
	}
	noColors *compiledColorScheme = &compiledColorScheme{
		Debug:  nocolor,
		Info:   nocolor,
		Warn:   nocolor,
		Error:  nocolor,
		Fatal:  nocolor,
		Panic:  nocolor,
		Tag:    nocolor,
		Prefix: nocolor,
		Func:   nocolor,
	}
	defaultCompiledColorScheme *compiledColorScheme = compileColorScheme(defaultColors)
)

func miniTS() float64 {
	return time.Since(baseTimestamp).Seconds()
}

func getCompiledColor(main string, fallback string) colorFunc {
	var style string
	if main != "" {
		style = main
	} else {
		style = fallback
	}
	return ansi.ColorFunc(style)
}

func compileColorScheme(s *ColorScheme) *compiledColorScheme {
	return &compiledColorScheme{
		Info:   getCompiledColor(s.Info, defaultColors.Info),
		Warn:   getCompiledColor(s.Warn, defaultColors.Warn),
		Error:  getCompiledColor(s.Error, defaultColors.Error),
		Fatal:  getCompiledColor(s.Fatal, defaultColors.Fatal),
		Panic:  getCompiledColor(s.Panic, defaultColors.Panic),
		Debug:  getCompiledColor(s.Debug, defaultColors.Debug),
		Tag:    getCompiledColor(s.Tag, defaultColors.Tag),
		Prefix: getCompiledColor(s.Prefix, defaultColors.Prefix),
		Func:   getCompiledColor(s.Func, defaultColors.Func),
	}
}

func (f *Instance) checkIfTerminal(w io.Writer) bool {
	switch v := w.(type) {
	case *os.File:
		return terminal.IsTerminal(int(v.Fd()))
	default:
		return false
	}
}

func (f *Instance) SetColorScheme(colorScheme *ColorScheme) {
	f.colorScheme = compileColorScheme(colorScheme)
}

func (f *Instance) Format(entry *logrus.Entry) ([]byte, error) {
	// init
	f.Once.Do(func() {
		if len(f.PrefixFieldName) == 0 {
			f.PrefixFieldName = "__p"
		}
		if len(f.TagFieldName) == 0 {
			f.TagFieldName = "__t"
		}
		if len(f.FuncFieldName) == 0 {
			f.FuncFieldName = "__f"
		}
		if len(f.TimestampFormat) == 0 {
			f.TimestampFormat = defaultTimestampFormat
		}
		if f.colorScheme == nil {
			if f.UseColors {
				f.colorScheme = defaultCompiledColorScheme
			} else {
				f.colorScheme = noColors
			}
		}
	})

	var buf *bytes.Buffer
	if entry.Buffer != nil {
		buf = entry.Buffer
	} else {
		buf = &bytes.Buffer{}
	}

	var levelColor colorFunc
	var levelText string
	switch entry.Level {
	case logrus.InfoLevel:
		levelColor = f.colorScheme.Info
	case logrus.WarnLevel:
		levelColor = f.colorScheme.Warn
	case logrus.ErrorLevel:
		levelColor = f.colorScheme.Error
	case logrus.FatalLevel:
		levelColor = f.colorScheme.Fatal
	case logrus.PanicLevel:
		levelColor = f.colorScheme.Panic
	default:
		levelColor = f.colorScheme.Debug
	}

	if entry.Level != logrus.WarnLevel {
		levelText = entry.Level.String()
	} else {
		levelText = "warn"
	}

	if !f.LowercaseLevels {
		levelText = strings.ToUpper(levelText)
	}

	if !f.DisableTimestamp {
		var ts string
		if !f.FullTimestamp {
			ts = fmt.Sprintf("[%f]", miniTS())
		} else {
			ts = entry.Time.Format(f.TimestampFormat)
		}
		fmt.Fprint(buf, levelColor(ts), " ")
	}

	fmt.Fprint(buf, levelColor(fmt.Sprintf("%5s", levelText)), " ")

	tv := "-"
	if v, ok := entry.Data[f.TagFieldName]; ok {
		if tv, ok = v.(string); !ok {
			tv = fmt.Sprintf("%#v", v)
		}
	}
	fmt.Fprint(buf, f.colorScheme.Tag(fmt.Sprintf("% 16s", tv)), " ")

	if v, ok := entry.Data[f.PrefixFieldName]; ok {
		switch v.(type) {
		case string, fmt.Stringer:
			fmt.Fprint(buf, f.colorScheme.Prefix(fmt.Sprintf("%s", v)))
		default:
			fmt.Fprint(buf, f.colorScheme.Prefix(fmt.Sprintf("%T", v)))
		}
	} else {
		fmt.Fprint(buf, f.colorScheme.Prefix(f.PrefixFieldName+"<missing>"))
	}

	if v, ok := entry.Data[f.FuncFieldName]; ok {
		fmt.Fprint(buf, " ", f.colorScheme.Func(fmt.Sprintf("%v", v)))
	}
	fmt.Fprint(buf, "\t", levelColor(entry.Message), "\t")

	if v, ok := entry.Data[logrus.ErrorKey]; ok {
		printField(buf, logrus.ErrorKey, v, f.colorScheme.Prefix, levelColor)
	}

	keys := make([]string, 0, len(entry.Data))
	for k := range entry.Data {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, k := range keys {
		if k == f.PrefixFieldName || k == f.TagFieldName || k == f.FuncFieldName || k == logrus.ErrorKey {
			continue
		}
		v := entry.Data[k]
		printField(buf, k, v, f.colorScheme.Prefix, levelColor)
	}
	buf.WriteRune('\n')
	return buf.Bytes(), nil
}

func printField(buf *bytes.Buffer, k string, v interface{}, kcolor, vcolor colorFunc) {
	switch w := v.(type) {
	case fmt.Stringer:
		fmt.Fprintf(buf, " %s=%s", kcolor(k), vcolor(w.String()))
	case error:
		s := w.Error()
		r, n := utf8.DecodeRuneInString(s)
		fmt.Fprintf(buf, " %s=%s", kcolor(k), vcolor(fmt.Sprintf("%q", string(unicode.ToUpper(r))+s[n:]+"!")))
	default:
		fmt.Fprintf(buf, " %s=%s", kcolor(k), vcolor(fmt.Sprintf("%#v", v)))
	}
}
<|endoftext|>


<commit_before>package logging

import (
	"fmt"
	"strings"
)

// Formatter objects are used by their Handlers to format events into a single
// string that the Handler can write (or not write) somewhere else.  The same
// Formatter object should not be used by multiple Handlers.
type Formatter interface {
	// Format takes the event object and formats it into a string for its
	// Handler to do something with.
	Format(event *Event) string
}

// FormatterFunc implements the Formatter interface through a single function.
type FormatterFunc func(e *Event) string

// Format implements Formatter by calling the format message.
func (f FormatterFunc) Format(e *Event) string { return f(e) }

// DefaultFormatter Sprintf's all of the information within its provided Event
// in an arbitrarily decided format that *I* just happen to like.
// Your mileage may vary.
type DefaultFormatter struct{}

// Format returns the event with the following layout:
//
//    yyyy-mm-dd HH:MM:SS:  Level:  LoggerName:  at FuncName in File, line Line:  fmt.Sprintf(Msg, Args...)
func (f DefaultFormatter) Format(event *Event) string {
	year, month, day := event.Time.Date()
	hour, minute, second := event.Time.Clock()
	levelString := event.Level.String()
	rightAlignedLevel := strings.Repeat(" ", 8-len(levelString)) + levelString
	return fmt.Sprintf(
		"%d-%02d-%02d %02d:%02d:%02d:  %s:  %s:  at %s in %s, line %d:  %s\n",
		year, month, day, hour, minute, second,
		rightAlignedLevel, event.Name, event.FuncName, event.File, event.Line,
		fmt.Sprintf(event.Msg, event.Args...))
}
<commit_msg>Put a newline before message in DefaultFormatter<commit_after>package logging

import (
	"fmt"
	"strings"
)

// Formatter objects are used by their Handlers to format events into a single
// string that the Handler can write (or not write) somewhere else.  The same
// Formatter object should not be used by multiple Handlers.
type Formatter interface {
	// Format takes the event object and formats it into a string for its
	// Handler to do something with.
	Format(event *Event) string
}

// FormatterFunc implements the Formatter interface through a single function.
type FormatterFunc func(e *Event) string

// Format implements Formatter by calling the format message.
func (f FormatterFunc) Format(e *Event) string { return f(e) }

// DefaultFormatter Sprintf's all of the information within its provided Event
// in an arbitrarily decided format that *I* just happen to like.
// Your mileage may vary.
type DefaultFormatter struct{}

// Format returns the event with the following layout:
//
//    yyyy-mm-dd HH:MM:SS:  Level:  LoggerName:  at FuncName in File, line Line:  fmt.Sprintf(Msg, Args...)
func (f DefaultFormatter) Format(event *Event) string {
	year, month, day := event.Time.Date()
	hour, minute, second := event.Time.Clock()
	levelString := event.Level.String()
	rightAlignedLevel := strings.Repeat(" ", 8-len(levelString)) + levelString
	return fmt.Sprintf(
		"%d-%02d-%02d %02d:%02d:%02d:  %s:  %s:  at %s in %s, line %d:\n\t%s\n",
		year, month, day, hour, minute, second,
		rightAlignedLevel, event.Name, event.FuncName, event.File, event.Line,
		fmt.Sprintf(event.Msg, event.Args...))
}
<|endoftext|>


<commit_before>package errorx

import (
	"encoding/json"
	"fmt"
)

const (
	Info    uint8 = 0
	Verbose uint8 = 1
	Debug   uint8 = 2
)

var verbosity uint8

type Errorx struct {
	errorCode    int    `json:"error_code"`
	errorMsg     string `json:"error_msg"`
	errorDetails string `json:"error_details,omitempty"`
	errorHint    string `json:"error_hint,omitempty"`
}

func New(code int, errorMsg ...string) *Errorx {
	e := Errorx{errorCode: code}

	msgCount := len(errorMsg)
	if msgCount > 0 {
		e.errorMsg = errorMsg[0]
	}
	if msgCount > 1 {
		e.errorDetails = errorMsg[1]
	}
	if msgCount > 2 {
		e.errorHint = errorMsg[2]
	}

	return &e
}

func SetVerbosity(v uint8) {
	if v > 3 {
		v = 2
	}
	verbosity = v
}

func (e Errorx) Code() int {
	return e.errorCode
}

func (e Errorx) Error() string {
	if verbosity == 0 || (e.errorDetails == "" && e.errorHint == "") {
		return fmt.Sprintf("Error %d: %s", e.errorCode, e.errorMsg)
	}
	if verbosity == 1 || e.errorHint == "" {
		return fmt.Sprintf("Error %d: %s - %s", e.errorCode, e.errorMsg, e.errorDetails)
	}
	return fmt.Sprintf("Error %d: %s - %s - %s", e.errorCode, e.errorMsg, e.errorDetails, e.errorHint)

}

func (e Errorx) Errorf(params ...interface{}) string {
	if verbosity == 0 || (e.errorDetails == "" && e.errorHint == "") {
		return fmt.Sprintf("Error %d: %s", e.errorCode, fmt.Sprintf(e.errorMsg, params...))
	}
	if verbosity == 1 || e.errorHint == "" {
		return fmt.Sprintf("Error %d: %s - %s", e.errorCode, fmt.Sprintf(e.errorMsg, params...), e.errorDetails)
	}
	return fmt.Sprintf("Error %d: %s - %s - %s", e.errorCode, fmt.Sprintf(e.errorMsg, params...), e.errorDetails, e.errorHint)
}

func (e Errorx) Json() ([]byte, error) {
	err := Errorx{errorCode: e.errorCode, errorMsg: e.errorMsg}
	if verbosity > 0 && e.errorDetails != "" {
		err.errorDetails = e.errorDetails
	}
	if verbosity > 1 && e.errorHint != "" {
		err.errorHint = e.errorHint
	}
	return json.Marshal(err)
}

func (e Errorx) Jsonf(params ...interface{}) ([]byte, error) {
	err := Errorx{errorCode: e.errorCode, errorMsg: fmt.Sprintf(e.errorMsg, params...)}
	if verbosity > 0 && e.errorDetails != "" {
		err.errorDetails = e.errorDetails
	}
	if verbosity > 1 && e.errorHint != "" {
		err.errorHint = e.errorHint
	}
	return json.Marshal(err)
}
<commit_msg>godoc<commit_after>package errorx

import (
	"encoding/json"
	"fmt"
)

const (
	Info    uint8 = 0
	Verbose uint8 = 1
	Debug   uint8 = 2
)

// verbosity variable stores global verbosity setting for errorx package
// based on it's value different level of error details will be provided
// by Error, Errorf, Json and Jsonf
var verbosity uint8

// Errorx is a more feature rich implementation of error interface inspired
// by PostgreSQL error style guide
type Errorx struct {
	errorCode    int    `json:"error_code"`
	errorMsg     string `json:"error_msg"`
	errorDetails string `json:"error_details,omitempty"`
	errorHint    string `json:"error_hint,omitempty"`
}

// New returns an error with error code and error messages provided in
// function params
func New(code int, errorMsg ...string) *Errorx {
	e := Errorx{errorCode: code}

	msgCount := len(errorMsg)
	if msgCount > 0 {
		e.errorMsg = errorMsg[0]
	}
	if msgCount > 1 {
		e.errorDetails = errorMsg[1]
	}
	if msgCount > 2 {
		e.errorHint = errorMsg[2]
	}

	return &e
}

// SetVerbosity changes global verbosity setting
func SetVerbosity(v uint8) {
	if v > 3 {
		v = 2
	}
	verbosity = v
}

// Code returns Errorx error code value. It's intended primarily to allow
// easy error comparison / matching
func (e Errorx) Code() int {
	return e.errorCode
}

// Error returns a string representation of errorx. It includes at least
// error code and message. Error details and hint are provided depending
// on verbosity level set
func (e Errorx) Error() string {
	if verbosity == 0 || (e.errorDetails == "" && e.errorHint == "") {
		return fmt.Sprintf("Error %d: %s", e.errorCode, e.errorMsg)
	}
	if verbosity == 1 || e.errorHint == "" {
		return fmt.Sprintf("Error %d: %s - %s", e.errorCode, e.errorMsg, e.errorDetails)
	}
	return fmt.Sprintf("Error %d: %s - %s - %s", e.errorCode, e.errorMsg, e.errorDetails, e.errorHint)

}

// Errorf is a variant of Error that formats according to errorMsg
// speficier and returns resulting string error details and hint
// will not be formated
func (e Errorx) Errorf(params ...interface{}) string {
	if verbosity == 0 || (e.errorDetails == "" && e.errorHint == "") {
		return fmt.Sprintf("Error %d: %s", e.errorCode, fmt.Sprintf(e.errorMsg, params...))
	}
	if verbosity == 1 || e.errorHint == "" {
		return fmt.Sprintf("Error %d: %s - %s", e.errorCode, fmt.Sprintf(e.errorMsg, params...), e.errorDetails)
	}
	return fmt.Sprintf("Error %d: %s - %s - %s", e.errorCode, fmt.Sprintf(e.errorMsg, params...), e.errorDetails, e.errorHint)
}

// Json returns a json representation (as []byte) of errorx and error
// if marshaling fails
func (e Errorx) Json() ([]byte, error) {
	err := Errorx{errorCode: e.errorCode, errorMsg: e.errorMsg}
	if verbosity > 0 && e.errorDetails != "" {
		err.errorDetails = e.errorDetails
	}
	if verbosity > 1 && e.errorHint != "" {
		err.errorHint = e.errorHint
	}
	return json.Marshal(err)
}

// Jsonf is a variant of Json that formats according to errorMsg
// speficier and returns resulting string error details and hint
// will not be formated
func (e Errorx) Jsonf(params ...interface{}) ([]byte, error) {
	err := Errorx{errorCode: e.errorCode, errorMsg: fmt.Sprintf(e.errorMsg, params...)}
	if verbosity > 0 && e.errorDetails != "" {
		err.errorDetails = e.errorDetails
	}
	if verbosity > 1 && e.errorHint != "" {
		err.errorHint = e.errorHint
	}
	return json.Marshal(err)
}
<|endoftext|>


<commit_before>package discordgo

import (
	"encoding/json"
)

// This file contains all the possible structs that can be
// handled by AddHandler/EventHandler.
// DO NOT ADD ANYTHING BUT EVENT HANDLER STRUCTS TO THIS FILE.
//go:generate go run tools/cmd/eventhandlers/main.go

// Connect is the data for a Connect event.
// This is a sythetic event and is not dispatched by Discord.
type Connect struct{}

// Disconnect is the data for a Disconnect event.
// This is a sythetic event and is not dispatched by Discord.
type Disconnect struct{}

// RateLimit is the data for a RateLimit event.
// This is a sythetic event and is not dispatched by Discord.
type RateLimit struct {
	*TooManyRequests
	URL string
}

// Event provides a basic initial struct for all websocket events.
type Event struct {
	Operation int             `json:"op"`
	Sequence  int64           `json:"s"`
	Type      string          `json:"t"`
	RawData   json.RawMessage `json:"d"`
	// Struct contains one of the other types in this file.
	Struct interface{} `json:"-"`
}

// A Ready stores all data for the websocket READY event.
type Ready struct {
	Version         int          `json:"v"`
	SessionID       string       `json:"session_id"`
	User            *User        `json:"user"`
	ReadState       []*ReadState `json:"read_state"`
	PrivateChannels []*Channel   `json:"private_channels"`
	Guilds          []*Guild     `json:"guilds"`

	// Undocumented fields
	Settings          *Settings            `json:"user_settings"`
	UserGuildSettings []*UserGuildSettings `json:"user_guild_settings"`
	Relationships     []*Relationship      `json:"relationships"`
	Presences         []*Presence          `json:"presences"`
	Notes             map[string]string    `json:"notes"`
}

// ChannelCreate is the data for a ChannelCreate event.
type ChannelCreate struct {
	*Channel
}

// ChannelUpdate is the data for a ChannelUpdate event.
type ChannelUpdate struct {
	*Channel
}

// ChannelDelete is the data for a ChannelDelete event.
type ChannelDelete struct {
	*Channel
}

// ChannelPinsUpdate stores data for a ChannelPinsUpdate event.
type ChannelPinsUpdate struct {
	LastPinTimestamp string `json:"last_pin_timestamp"`
	ChannelID        string `json:"channel_id"`
}

// GuildCreate is the data for a GuildCreate event.
type GuildCreate struct {
	*Guild
}

// GuildUpdate is the data for a GuildUpdate event.
type GuildUpdate struct {
	*Guild
}

// GuildDelete is the data for a GuildDelete event.
type GuildDelete struct {
	*Guild
}

// GuildBanAdd is the data for a GuildBanAdd event.
type GuildBanAdd struct {
	User    *User  `json:"user"`
	GuildID string `json:"guild_id"`
}

// GuildBanRemove is the data for a GuildBanRemove event.
type GuildBanRemove struct {
	User    *User  `json:"user"`
	GuildID string `json:"guild_id"`
}

// GuildMemberAdd is the data for a GuildMemberAdd event.
type GuildMemberAdd struct {
	*Member
}

// GuildMemberUpdate is the data for a GuildMemberUpdate event.
type GuildMemberUpdate struct {
	*Member
}

// GuildMemberRemove is the data for a GuildMemberRemove event.
type GuildMemberRemove struct {
	*Member
}

// GuildRoleCreate is the data for a GuildRoleCreate event.
type GuildRoleCreate struct {
	*GuildRole
}

// GuildRoleUpdate is the data for a GuildRoleUpdate event.
type GuildRoleUpdate struct {
	*GuildRole
}

// A GuildRoleDelete is the data for a GuildRoleDelete event.
type GuildRoleDelete struct {
	RoleID  int64 `json:"role_id,string"`
	GuildID int64 `json:"guild_id,string"`
}

// A GuildEmojisUpdate is the data for a guild emoji update event.
type GuildEmojisUpdate struct {
	GuildID int64    `json:"guild_id,string"`
	Emojis  []*Emoji `json:"emojis"`
}

// A GuildMembersChunk is the data for a GuildMembersChunk event.
type GuildMembersChunk struct {
	GuildID int64     `json:"guild_id,string"`
	Members []*Member `json:"members"`
}

// GuildIntegrationsUpdate is the data for a GuildIntegrationsUpdate event.
type GuildIntegrationsUpdate struct {
	GuildID int64 `json:"guild_id,string"`
}

// MessageAck is the data for a MessageAck event.
type MessageAck struct {
	MessageID int64 `json:"message_id,string"`
	ChannelID int64 `json:"channel_id,string"`
}

// MessageCreate is the data for a MessageCreate event.
type MessageCreate struct {
	*Message
}

// MessageUpdate is the data for a MessageUpdate event.
type MessageUpdate struct {
	*Message
}

// MessageDelete is the data for a MessageDelete event.
type MessageDelete struct {
	*Message
}

// MessageReactionAdd is the data for a MessageReactionAdd event.
type MessageReactionAdd struct {
	*MessageReaction
}

// MessageReactionRemove is the data for a MessageReactionRemove event.
type MessageReactionRemove struct {
	*MessageReaction
}

// MessageReactionRemoveAll is the data for a MessageReactionRemoveAll event.
type MessageReactionRemoveAll struct {
	*MessageReaction
}

// PresencesReplace is the data for a PresencesReplace event.
type PresencesReplace []*Presence

// PresenceUpdate is the data for a PresenceUpdate event.
type PresenceUpdate struct {
	Presence
	GuildID int64   `json:"guild_id,string"`
	Roles   IDSlice `json:"roles,string"`
}

// Resumed is the data for a Resumed event.
type Resumed struct {
	Trace []string `json:"_trace"`
}

// RelationshipAdd is the data for a RelationshipAdd event.
type RelationshipAdd struct {
	*Relationship
}

// RelationshipRemove is the data for a RelationshipRemove event.
type RelationshipRemove struct {
	*Relationship
}

// TypingStart is the data for a TypingStart event.
type TypingStart struct {
	UserID    int64 `json:"user_id,string"`
	ChannelID int64 `json:"channel_id,string"`
	Timestamp int   `json:"timestamp"`
}

// UserUpdate is the data for a UserUpdate event.
type UserUpdate struct {
	*User
}

// UserSettingsUpdate is the data for a UserSettingsUpdate event.
type UserSettingsUpdate map[string]interface{}

// UserGuildSettingsUpdate is the data for a UserGuildSettingsUpdate event.
type UserGuildSettingsUpdate struct {
	*UserGuildSettings
}

// UserNoteUpdate is the data for a UserNoteUpdate event.
type UserNoteUpdate struct {
	ID   int64  `json:"id,string"`
	Note string `json:"note"`
}

// VoiceServerUpdate is the data for a VoiceServerUpdate event.
type VoiceServerUpdate struct {
	Token    string `json:"token"`
	GuildID  int64  `json:"guild_id,string"`
	Endpoint string `json:"endpoint"`
}

// VoiceStateUpdate is the data for a VoiceStateUpdate event.
type VoiceStateUpdate struct {
	*VoiceState
}

// MessageDeleteBulk is the data for a MessageDeleteBulk event
type MessageDeleteBulk struct {
	Messages  IDSlice `json:"ids,string"`
	ChannelID int64   `json:"channel_id,string"`
}
<commit_msg>Update some structs to integer ids<commit_after>package discordgo

import (
	"encoding/json"
)

// This file contains all the possible structs that can be
// handled by AddHandler/EventHandler.
// DO NOT ADD ANYTHING BUT EVENT HANDLER STRUCTS TO THIS FILE.
//go:generate go run tools/cmd/eventhandlers/main.go

// Connect is the data for a Connect event.
// This is a sythetic event and is not dispatched by Discord.
type Connect struct{}

// Disconnect is the data for a Disconnect event.
// This is a sythetic event and is not dispatched by Discord.
type Disconnect struct{}

// RateLimit is the data for a RateLimit event.
// This is a sythetic event and is not dispatched by Discord.
type RateLimit struct {
	*TooManyRequests
	URL string
}

// Event provides a basic initial struct for all websocket events.
type Event struct {
	Operation int             `json:"op"`
	Sequence  int64           `json:"s"`
	Type      string          `json:"t"`
	RawData   json.RawMessage `json:"d"`
	// Struct contains one of the other types in this file.
	Struct interface{} `json:"-"`
}

// A Ready stores all data for the websocket READY event.
type Ready struct {
	Version         int          `json:"v"`
	SessionID       string       `json:"session_id"`
	User            *User        `json:"user"`
	ReadState       []*ReadState `json:"read_state"`
	PrivateChannels []*Channel   `json:"private_channels"`
	Guilds          []*Guild     `json:"guilds"`

	// Undocumented fields
	Settings          *Settings            `json:"user_settings"`
	UserGuildSettings []*UserGuildSettings `json:"user_guild_settings"`
	Relationships     []*Relationship      `json:"relationships"`
	Presences         []*Presence          `json:"presences"`
	Notes             map[string]string    `json:"notes"`
}

// ChannelCreate is the data for a ChannelCreate event.
type ChannelCreate struct {
	*Channel
}

// ChannelUpdate is the data for a ChannelUpdate event.
type ChannelUpdate struct {
	*Channel
}

// ChannelDelete is the data for a ChannelDelete event.
type ChannelDelete struct {
	*Channel
}

// ChannelPinsUpdate stores data for a ChannelPinsUpdate event.
type ChannelPinsUpdate struct {
	LastPinTimestamp string `json:"last_pin_timestamp"`
	ChannelID        int64  `json:"channel_id,string"`
}

// GuildCreate is the data for a GuildCreate event.
type GuildCreate struct {
	*Guild
}

// GuildUpdate is the data for a GuildUpdate event.
type GuildUpdate struct {
	*Guild
}

// GuildDelete is the data for a GuildDelete event.
type GuildDelete struct {
	*Guild
}

// GuildBanAdd is the data for a GuildBanAdd event.
type GuildBanAdd struct {
	User    *User `json:"user"`
	GuildID int64 `json:"guild_id,string"`
}

// GuildBanRemove is the data for a GuildBanRemove event.
type GuildBanRemove struct {
	User    *User `json:"user"`
	GuildID int64 `json:"guild_id,string"`
}

// GuildMemberAdd is the data for a GuildMemberAdd event.
type GuildMemberAdd struct {
	*Member
}

// GuildMemberUpdate is the data for a GuildMemberUpdate event.
type GuildMemberUpdate struct {
	*Member
}

// GuildMemberRemove is the data for a GuildMemberRemove event.
type GuildMemberRemove struct {
	*Member
}

// GuildRoleCreate is the data for a GuildRoleCreate event.
type GuildRoleCreate struct {
	*GuildRole
}

// GuildRoleUpdate is the data for a GuildRoleUpdate event.
type GuildRoleUpdate struct {
	*GuildRole
}

// A GuildRoleDelete is the data for a GuildRoleDelete event.
type GuildRoleDelete struct {
	RoleID  int64 `json:"role_id,string"`
	GuildID int64 `json:"guild_id,string"`
}

// A GuildEmojisUpdate is the data for a guild emoji update event.
type GuildEmojisUpdate struct {
	GuildID int64    `json:"guild_id,string"`
	Emojis  []*Emoji `json:"emojis"`
}

// A GuildMembersChunk is the data for a GuildMembersChunk event.
type GuildMembersChunk struct {
	GuildID int64     `json:"guild_id,string"`
	Members []*Member `json:"members"`
}

// GuildIntegrationsUpdate is the data for a GuildIntegrationsUpdate event.
type GuildIntegrationsUpdate struct {
	GuildID int64 `json:"guild_id,string"`
}

// MessageAck is the data for a MessageAck event.
type MessageAck struct {
	MessageID int64 `json:"message_id,string"`
	ChannelID int64 `json:"channel_id,string"`
}

// MessageCreate is the data for a MessageCreate event.
type MessageCreate struct {
	*Message
}

// MessageUpdate is the data for a MessageUpdate event.
type MessageUpdate struct {
	*Message
}

// MessageDelete is the data for a MessageDelete event.
type MessageDelete struct {
	*Message
}

// MessageReactionAdd is the data for a MessageReactionAdd event.
type MessageReactionAdd struct {
	*MessageReaction
}

// MessageReactionRemove is the data for a MessageReactionRemove event.
type MessageReactionRemove struct {
	*MessageReaction
}

// MessageReactionRemoveAll is the data for a MessageReactionRemoveAll event.
type MessageReactionRemoveAll struct {
	*MessageReaction
}

// PresencesReplace is the data for a PresencesReplace event.
type PresencesReplace []*Presence

// PresenceUpdate is the data for a PresenceUpdate event.
type PresenceUpdate struct {
	Presence
	GuildID int64   `json:"guild_id,string"`
	Roles   IDSlice `json:"roles,string"`
}

// Resumed is the data for a Resumed event.
type Resumed struct {
	Trace []string `json:"_trace"`
}

// RelationshipAdd is the data for a RelationshipAdd event.
type RelationshipAdd struct {
	*Relationship
}

// RelationshipRemove is the data for a RelationshipRemove event.
type RelationshipRemove struct {
	*Relationship
}

// TypingStart is the data for a TypingStart event.
type TypingStart struct {
	UserID    int64 `json:"user_id,string"`
	ChannelID int64 `json:"channel_id,string"`
	Timestamp int   `json:"timestamp"`
}

// UserUpdate is the data for a UserUpdate event.
type UserUpdate struct {
	*User
}

// UserSettingsUpdate is the data for a UserSettingsUpdate event.
type UserSettingsUpdate map[string]interface{}

// UserGuildSettingsUpdate is the data for a UserGuildSettingsUpdate event.
type UserGuildSettingsUpdate struct {
	*UserGuildSettings
}

// UserNoteUpdate is the data for a UserNoteUpdate event.
type UserNoteUpdate struct {
	ID   int64  `json:"id,string"`
	Note string `json:"note"`
}

// VoiceServerUpdate is the data for a VoiceServerUpdate event.
type VoiceServerUpdate struct {
	Token    string `json:"token"`
	GuildID  int64  `json:"guild_id,string"`
	Endpoint string `json:"endpoint"`
}

// VoiceStateUpdate is the data for a VoiceStateUpdate event.
type VoiceStateUpdate struct {
	*VoiceState
}

// MessageDeleteBulk is the data for a MessageDeleteBulk event
type MessageDeleteBulk struct {
	Messages  IDSlice `json:"ids,string"`
	ChannelID int64   `json:"channel_id,string"`
}
<|endoftext|>


<commit_before>package dns

import (
	"fmt"
	"sync"

	"github.com/giantswarm/kocho/swarm"

	"github.com/crackcomm/cloudflare"
	"github.com/juju/errgo"
	"golang.org/x/net/context"
)

type CloudFlareConfig struct {
	Email, Token string
}

func NewCloudFlareDNS(config CloudFlareConfig) *CloudFlareDNS {
	if config.Email == "" || config.Token == "" {
		panic("Cloudflare DNS requires email and token missing")
	}
	return &CloudFlareDNS{
		CloudFlareConfig: config,
	}
}

// CloudFlareDNS represents a client to the CloudFlare API.
type CloudFlareDNS struct {
	CloudFlareConfig

	mutex   sync.Mutex
	_client *cloudflare.Client
}

// CreateSwarmEntries creates DNS entries, given a Swarm and Entries to create.
func (cli *CloudFlareDNS) createSwarmEntries(s *swarm.Swarm, e *Entries) error {
	ctx := context.TODO()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	privateDns, err := s.GetPrivateDNS()
	if err != nil {
		return fmt.Errorf("Couldn't get private dns for swarm: %s - %v", s.Name, err)
	}
	instances, err := s.GetInstances()
	if err != nil {
		return fmt.Errorf("Failed fetch list of instances for swarm: %s - %v", s.Name, err)
	}
	if len(instances) < 1 {
		return fmt.Errorf("Couldn't get swarm instances of: %s - %v", s.Name, err)
	}

	if s.Type != "primary" {
		publicDns, err := s.GetPublicDNS()
		if err != nil {
			return fmt.Errorf("Couldn't get public dns for swarm: %s - %v", s.Name, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Catchall, publicDns); err != nil {
			return fmt.Errorf("Couldn't create catchall dns entry: %s %s - %v", e.Catchall, publicDns, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Public, publicDns); err != nil {
			return fmt.Errorf("Couldn't create public dns entry: %s %s - %v", e.Public, publicDns, err)
		}
	}

	if err := cli.createRecord(ctx, zone.ID, e.CatchallPrivate, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private catchall dns entry: %s %s - %v", e.CatchallPrivate, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Private, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private dns entry: %s %s - %v", e.Private, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Fleet, instances[0].PublicDNSName); err != nil {
		return fmt.Errorf("Couldn't create fleet dns entry: %s %s - %v", e.Fleet, instances[0].PublicDNSName, err)
	}
	return nil
}

// DeleteEntries deletes DNS entries, given a stack name, and list of Entries to delete.
func (cli *CloudFlareDNS) deleteEntries(name string, e *Entries) error {
	ctx := context.TODO()

	client := cli.client()

	// First we need to find our zone
	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	records, err := client.Records.List(ctx, zone.ID)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	for _, record := range records {
		entriesRecord := record.Name == e.Catchall ||
			record.Name == e.CatchallPrivate ||
			record.Name == e.Public ||
			record.Name == e.Private ||
			record.Name == e.Fleet
		if entriesRecord {
			if err := client.Records.Delete(ctx, zone.ID, record.ID); err != nil {
				return errgo.Mask(err, errgo.Any)
			}
		}
	}
	return nil
}

// Update updates DNS records, given a swarm name, CNAME, dns content, and Entries.
func (cli *CloudFlareDNS) update(swarmName, cname, dns string, e *Entries) error {
	ctx := context.TODO()
	client := cli.client()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	client.Records.Patch(ctx, &cloudflare.Record{
		ZoneID:  zone.ID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})

	return nil
}

func (api *CloudFlareDNS) client() *cloudflare.Client {
	api.mutex.Lock()
	defer api.mutex.Unlock()

	if api._client != nil {
		return api._client
	}

	options := cloudflare.Options{
		Email: api.Email,
		Key:   api.Token,
	}
	api._client = cloudflare.New(&options)
	return api._client
}

func (cli *CloudFlareDNS) createRecord(ctx context.Context, zoneID, cname, dns string) error {
	err := cli.client().Records.Create(ctx, &cloudflare.Record{
		ZoneID:  zoneID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})
	return errgo.Mask(err, errgo.Any)
}

func (cli *CloudFlareDNS) findZone(ctx context.Context, domain string) (*cloudflare.Zone, error) {
	client := cli.client()
	zones, err := client.Zones.List(ctx)
	if err != nil {
		return nil, errgo.Mask(err, errgo.Any)
	}

	for _, z := range zones {
		if z.Name == domain {
			return z, nil
		}
	}
	return nil, errgo.Newf("no zone for domain %s found", domain)
}
<commit_msg>dns: Added godoc for CloudFalre structs<commit_after>package dns

import (
	"fmt"
	"sync"

	"github.com/giantswarm/kocho/swarm"

	"github.com/crackcomm/cloudflare"
	"github.com/juju/errgo"
	"golang.org/x/net/context"
)

// CloudFlareConfig provides the static configuration for a CloudFlareDNS service.
type CloudFlareConfig struct {
	Email, Token string
}

// NewCloudFlareDNS creates a new CloudFlareDNS object based on the given config.
// If the config is invalid, a panic will be raised.
func NewCloudFlareDNS(config CloudFlareConfig) *CloudFlareDNS {
	if config.Email == "" || config.Token == "" {
		panic("Cloudflare DNS requires email and token missing")
	}
	return &CloudFlareDNS{
		CloudFlareConfig: config,
	}
}

// CloudFlareDNS represents a client to the CloudFlare API.
type CloudFlareDNS struct {
	CloudFlareConfig

	mutex   sync.Mutex
	_client *cloudflare.Client
}

// CreateSwarmEntries creates DNS entries, given a Swarm and Entries to create.
func (cli *CloudFlareDNS) createSwarmEntries(s *swarm.Swarm, e *Entries) error {
	ctx := context.TODO()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	privateDns, err := s.GetPrivateDNS()
	if err != nil {
		return fmt.Errorf("Couldn't get private dns for swarm: %s - %v", s.Name, err)
	}
	instances, err := s.GetInstances()
	if err != nil {
		return fmt.Errorf("Failed fetch list of instances for swarm: %s - %v", s.Name, err)
	}
	if len(instances) < 1 {
		return fmt.Errorf("Couldn't get swarm instances of: %s - %v", s.Name, err)
	}

	if s.Type != "primary" {
		publicDns, err := s.GetPublicDNS()
		if err != nil {
			return fmt.Errorf("Couldn't get public dns for swarm: %s - %v", s.Name, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Catchall, publicDns); err != nil {
			return fmt.Errorf("Couldn't create catchall dns entry: %s %s - %v", e.Catchall, publicDns, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Public, publicDns); err != nil {
			return fmt.Errorf("Couldn't create public dns entry: %s %s - %v", e.Public, publicDns, err)
		}
	}

	if err := cli.createRecord(ctx, zone.ID, e.CatchallPrivate, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private catchall dns entry: %s %s - %v", e.CatchallPrivate, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Private, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private dns entry: %s %s - %v", e.Private, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Fleet, instances[0].PublicDNSName); err != nil {
		return fmt.Errorf("Couldn't create fleet dns entry: %s %s - %v", e.Fleet, instances[0].PublicDNSName, err)
	}
	return nil
}

// DeleteEntries deletes DNS entries, given a stack name, and list of Entries to delete.
func (cli *CloudFlareDNS) deleteEntries(name string, e *Entries) error {
	ctx := context.TODO()

	client := cli.client()

	// First we need to find our zone
	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	records, err := client.Records.List(ctx, zone.ID)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	for _, record := range records {
		entriesRecord := record.Name == e.Catchall ||
			record.Name == e.CatchallPrivate ||
			record.Name == e.Public ||
			record.Name == e.Private ||
			record.Name == e.Fleet
		if entriesRecord {
			if err := client.Records.Delete(ctx, zone.ID, record.ID); err != nil {
				return errgo.Mask(err, errgo.Any)
			}
		}
	}
	return nil
}

// Update updates DNS records, given a swarm name, CNAME, dns content, and Entries.
func (cli *CloudFlareDNS) update(swarmName, cname, dns string, e *Entries) error {
	ctx := context.TODO()
	client := cli.client()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	client.Records.Patch(ctx, &cloudflare.Record{
		ZoneID:  zone.ID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})

	return nil
}

func (api *CloudFlareDNS) client() *cloudflare.Client {
	api.mutex.Lock()
	defer api.mutex.Unlock()

	if api._client != nil {
		return api._client
	}

	options := cloudflare.Options{
		Email: api.Email,
		Key:   api.Token,
	}
	api._client = cloudflare.New(&options)
	return api._client
}

func (cli *CloudFlareDNS) createRecord(ctx context.Context, zoneID, cname, dns string) error {
	err := cli.client().Records.Create(ctx, &cloudflare.Record{
		ZoneID:  zoneID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})
	return errgo.Mask(err, errgo.Any)
}

func (cli *CloudFlareDNS) findZone(ctx context.Context, domain string) (*cloudflare.Zone, error) {
	client := cli.client()
	zones, err := client.Zones.List(ctx)
	if err != nil {
		return nil, errgo.Mask(err, errgo.Any)
	}

	for _, z := range zones {
		if z.Name == domain {
			return z, nil
		}
	}
	return nil, errgo.Newf("no zone for domain %s found", domain)
}
<|endoftext|>


<commit_before>package dns

import (
	"fmt"
	"sync"

	"github.com/giantswarm/kocho/swarm"

	"github.com/crackcomm/cloudflare"
	"github.com/juju/errgo"
	"golang.org/x/net/context"
)

// CloudFlareConfig provides the static configuration for a CloudFlareDNS service.
type CloudFlareConfig struct {
	Email, Token string
}

// NewCloudFlareDNS creates a new CloudFlareDNS object based on the given config.
// If the config is invalid, a panic will be raised.
func NewCloudFlareDNS(config CloudFlareConfig) *CloudFlareDNS {
	if config.Email == "" || config.Token == "" {
		panic("Cloudflare DNS requires email and token")
	}
	return &CloudFlareDNS{
		CloudFlareConfig: config,
	}
}

// CloudFlareDNS represents a client to the CloudFlare API.
type CloudFlareDNS struct {
	CloudFlareConfig

	mutex   sync.Mutex
	_client *cloudflare.Client
}

// CreateSwarmEntries creates DNS entries, given a Swarm and Entries to create.
func (cli *CloudFlareDNS) createSwarmEntries(s *swarm.Swarm, e *Entries) error {
	ctx := context.TODO()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	privateDns, err := s.GetPrivateDNS()
	if err != nil {
		return fmt.Errorf("Couldn't get private dns for swarm: %s - %v", s.Name, err)
	}
	instances, err := s.GetInstances()
	if err != nil {
		return fmt.Errorf("Failed fetch list of instances for swarm: %s - %v", s.Name, err)
	}
	if len(instances) < 1 {
		return fmt.Errorf("Couldn't get swarm instances of: %s - %v", s.Name, err)
	}

	if s.Type != "primary" {
		publicDns, err := s.GetPublicDNS()
		if err != nil {
			return fmt.Errorf("Couldn't get public dns for swarm: %s - %v", s.Name, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Catchall, publicDns); err != nil {
			return fmt.Errorf("Couldn't create catchall dns entry: %s %s - %v", e.Catchall, publicDns, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Public, publicDns); err != nil {
			return fmt.Errorf("Couldn't create public dns entry: %s %s - %v", e.Public, publicDns, err)
		}
	}

	if err := cli.createRecord(ctx, zone.ID, e.CatchallPrivate, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private catchall dns entry: %s %s - %v", e.CatchallPrivate, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Private, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private dns entry: %s %s - %v", e.Private, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Fleet, instances[0].PublicDNSName); err != nil {
		return fmt.Errorf("Couldn't create fleet dns entry: %s %s - %v", e.Fleet, instances[0].PublicDNSName, err)
	}
	return nil
}

// DeleteEntries deletes DNS entries, given a stack name, and list of Entries to delete.
func (cli *CloudFlareDNS) deleteEntries(name string, e *Entries) error {
	ctx := context.TODO()

	client := cli.client()

	// First we need to find our zone
	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	records, err := client.Records.List(ctx, zone.ID)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	for _, record := range records {
		entriesRecord := record.Name == e.Catchall ||
			record.Name == e.CatchallPrivate ||
			record.Name == e.Public ||
			record.Name == e.Private ||
			record.Name == e.Fleet
		if entriesRecord {
			if err := client.Records.Delete(ctx, zone.ID, record.ID); err != nil {
				return errgo.Mask(err, errgo.Any)
			}
		}
	}
	return nil
}

// Update updates DNS records, given a swarm name, CNAME, dns content, and Entries.
func (cli *CloudFlareDNS) update(swarmName, cname, dns string, e *Entries) error {
	ctx := context.TODO()
	client := cli.client()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	client.Records.Patch(ctx, &cloudflare.Record{
		ZoneID:  zone.ID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})

	return nil
}

func (api *CloudFlareDNS) client() *cloudflare.Client {
	api.mutex.Lock()
	defer api.mutex.Unlock()

	if api._client != nil {
		return api._client
	}

	options := cloudflare.Options{
		Email: api.Email,
		Key:   api.Token,
	}
	api._client = cloudflare.New(&options)
	return api._client
}

func (cli *CloudFlareDNS) createRecord(ctx context.Context, zoneID, cname, dns string) error {
	err := cli.client().Records.Create(ctx, &cloudflare.Record{
		ZoneID:  zoneID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})
	return errgo.Mask(err, errgo.Any)
}

func (cli *CloudFlareDNS) findZone(ctx context.Context, domain string) (*cloudflare.Zone, error) {
	client := cli.client()
	zones, err := client.Zones.List(ctx)
	if err != nil {
		return nil, errgo.Mask(err, errgo.Any)
	}

	for _, z := range zones {
		if z.Name == domain {
			return z, nil
		}
	}
	return nil, errgo.Newf("no zone for domain %s found", domain)
}
<commit_msg>dns: fixes godoc after making funcitons private<commit_after>package dns

import (
	"fmt"
	"sync"

	"github.com/giantswarm/kocho/swarm"

	"github.com/crackcomm/cloudflare"
	"github.com/juju/errgo"
	"golang.org/x/net/context"
)

// CloudFlareConfig provides the static configuration for a CloudFlareDNS service.
type CloudFlareConfig struct {
	Email, Token string
}

// NewCloudFlareDNS creates a new CloudFlareDNS object based on the given config.
// If the config is invalid, a panic will be raised.
func NewCloudFlareDNS(config CloudFlareConfig) *CloudFlareDNS {
	if config.Email == "" || config.Token == "" {
		panic("Cloudflare DNS requires email and token")
	}
	return &CloudFlareDNS{
		CloudFlareConfig: config,
	}
}

// CloudFlareDNS represents a client to the CloudFlare API.
type CloudFlareDNS struct {
	CloudFlareConfig

	mutex   sync.Mutex
	_client *cloudflare.Client
}

// createSwarmEntries creates DNS entries, given a Swarm and Entries to create.
func (cli *CloudFlareDNS) createSwarmEntries(s *swarm.Swarm, e *Entries) error {
	ctx := context.TODO()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	privateDns, err := s.GetPrivateDNS()
	if err != nil {
		return fmt.Errorf("Couldn't get private dns for swarm: %s - %v", s.Name, err)
	}
	instances, err := s.GetInstances()
	if err != nil {
		return fmt.Errorf("Failed fetch list of instances for swarm: %s - %v", s.Name, err)
	}
	if len(instances) < 1 {
		return fmt.Errorf("Couldn't get swarm instances of: %s - %v", s.Name, err)
	}

	if s.Type != "primary" {
		publicDns, err := s.GetPublicDNS()
		if err != nil {
			return fmt.Errorf("Couldn't get public dns for swarm: %s - %v", s.Name, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Catchall, publicDns); err != nil {
			return fmt.Errorf("Couldn't create catchall dns entry: %s %s - %v", e.Catchall, publicDns, err)
		}
		if err := cli.createRecord(ctx, zone.ID, e.Public, publicDns); err != nil {
			return fmt.Errorf("Couldn't create public dns entry: %s %s - %v", e.Public, publicDns, err)
		}
	}

	if err := cli.createRecord(ctx, zone.ID, e.CatchallPrivate, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private catchall dns entry: %s %s - %v", e.CatchallPrivate, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Private, privateDns); err != nil {
		return fmt.Errorf("Couldn't create private dns entry: %s %s - %v", e.Private, privateDns, err)
	}
	if err := cli.createRecord(ctx, zone.ID, e.Fleet, instances[0].PublicDNSName); err != nil {
		return fmt.Errorf("Couldn't create fleet dns entry: %s %s - %v", e.Fleet, instances[0].PublicDNSName, err)
	}
	return nil
}

// deleteEntries deletes DNS entries, given a stack name, and list of Entries to delete.
func (cli *CloudFlareDNS) deleteEntries(name string, e *Entries) error {
	ctx := context.TODO()

	client := cli.client()

	// First we need to find our zone
	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	records, err := client.Records.List(ctx, zone.ID)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	for _, record := range records {
		entriesRecord := record.Name == e.Catchall ||
			record.Name == e.CatchallPrivate ||
			record.Name == e.Public ||
			record.Name == e.Private ||
			record.Name == e.Fleet
		if entriesRecord {
			if err := client.Records.Delete(ctx, zone.ID, record.ID); err != nil {
				return errgo.Mask(err, errgo.Any)
			}
		}
	}
	return nil
}

// update updates DNS records, given a swarm name, CNAME, dns content, and Entries.
func (cli *CloudFlareDNS) update(swarmName, cname, dns string, e *Entries) error {
	ctx := context.TODO()
	client := cli.client()

	zone, err := cli.findZone(ctx, e.Zone)
	if err != nil {
		return errgo.Mask(err, errgo.Any)
	}

	client.Records.Patch(ctx, &cloudflare.Record{
		ZoneID:  zone.ID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})

	return nil
}

func (api *CloudFlareDNS) client() *cloudflare.Client {
	api.mutex.Lock()
	defer api.mutex.Unlock()

	if api._client != nil {
		return api._client
	}

	options := cloudflare.Options{
		Email: api.Email,
		Key:   api.Token,
	}
	api._client = cloudflare.New(&options)
	return api._client
}

func (cli *CloudFlareDNS) createRecord(ctx context.Context, zoneID, cname, dns string) error {
	err := cli.client().Records.Create(ctx, &cloudflare.Record{
		ZoneID:  zoneID,
		Type:    "CNAME",
		Name:    cname,
		Content: dns,
	})
	return errgo.Mask(err, errgo.Any)
}

func (cli *CloudFlareDNS) findZone(ctx context.Context, domain string) (*cloudflare.Zone, error) {
	client := cli.client()
	zones, err := client.Zones.List(ctx)
	if err != nil {
		return nil, errgo.Mask(err, errgo.Any)
	}

	for _, z := range zones {
		if z.Name == domain {
			return z, nil
		}
	}
	return nil, errgo.Newf("no zone for domain %s found", domain)
}
<|endoftext|>


<commit_before>package famigo

import (
	"fmt"
	"os"
)

type cpuState struct {
	Mem mem

	PPU ppu
	APU apu

	PC            uint16
	P, A, X, Y, S byte

	IRQ, BRK, NMI, RESET bool

	Steps uint64

	CurrentJoypad1 Joypad
	CurrentJoypad2 Joypad // empty for now

	JoypadReg1          Joypad
	JoypadReg2          Joypad
	ReloadingJoypads    bool
	JoypadReg1ReadCount byte
	JoypadReg2ReadCount byte
}

func (cs *cpuState) writeJoypadReg1(val byte) {
	if val&0x01 != 0 {
		cs.ReloadingJoypads = true
		cs.JoypadReg1ReadCount = 0
	} else if cs.ReloadingJoypads {
		cs.ReloadingJoypads = false
	}
}
func (cs *cpuState) getCurrentButtonState(jp *Joypad, readCount byte) bool {
	tbl := []bool{jp.A, jp.B, jp.Sel, jp.Start, jp.Up, jp.Down, jp.Left, jp.Right}
	return tbl[readCount]
}
func (cs *cpuState) readJoypadReg1() byte {
	jp := &cs.CurrentJoypad1
	if cs.ReloadingJoypads {
		return 0x40 | boolBit(jp.A, 0)
	} else if cs.JoypadReg1ReadCount > 7 {
		return 0x41
	}
	state := cs.getCurrentButtonState(jp, cs.JoypadReg1ReadCount)
	cs.JoypadReg1ReadCount++
	return 0x40 | boolBit(state, 1)
}

// writes for this reg handled by apu.writeFrameCounterReg
func (cs *cpuState) readJoypadReg2() byte {
	jp := &cs.CurrentJoypad2
	if cs.ReloadingJoypads {
		return 0x40 | boolBit(jp.A, 0)
	} else if cs.JoypadReg2ReadCount > 7 {
		return 0x41
	}
	state := cs.getCurrentButtonState(jp, cs.JoypadReg2ReadCount)
	cs.JoypadReg2ReadCount++
	return 0x40 | boolBit(state, 1)
}

func (cs *cpuState) runCycles(cycles uint) {
	for i := uint(0); i < cycles; i++ {
		for j := 0; j < 3; j++ {
			cs.PPU.runCycle(cs) // ppu clock is 3x cpu
		}
	}
}

func (cs *cpuState) debugStatusLine() string {
	fmt.Println()
	opcode := cs.read(cs.PC)
	b2, b3 := cs.read(cs.PC+1), cs.read(cs.PC+2)
	return fmt.Sprintf("Steps: %09d ", cs.Steps) +
		fmt.Sprintf("PC:%04x ", cs.PC) +
		fmt.Sprintf("*PC[0:2]:%02x%02x%02x ", opcode, b2, b3) +
		fmt.Sprintf("opcode:%v ", opcodeNames[opcode]) +
		fmt.Sprintf("S:%02x ", cs.S) +
		fmt.Sprintf("A:%02x ", cs.A) +
		fmt.Sprintf("P:%02x ", cs.P) +
		fmt.Sprintf("X:%02x ", cs.X) +
		fmt.Sprintf("Y:%02x ", cs.Y) +
		fmt.Sprintf("IRQ:%v ", cs.IRQ) +
		fmt.Sprintf("BRK:%v ", cs.BRK) +
		fmt.Sprintf("NMI:%v ", cs.NMI) +
		fmt.Sprintf("RESET:%v", cs.RESET)
}

const (
	flagNeg         = 0x80
	flagOverflow    = 0x40
	flagOnStack     = 0x10
	flagBrk         = 0x10
	flagDecimal     = 0x08 // unused
	flagIrqDisabled = 0x04
	flagZero        = 0x02
	flagCarry       = 0x01
)

func (cs *cpuState) handleInterrupts() {
	if cs.RESET {
		cs.RESET = false
		cs.PC = cs.read16(0xfffc)
	} else if cs.NMI {
		cs.NMI = false
		cs.push16(cs.PC)
		cs.push8(cs.P | flagOnStack)
		cs.P |= flagIrqDisabled
		cs.PC = cs.read16(0xfffa)
	} else if cs.IRQ && cs.interruptsEnabled() {
		cs.IRQ = false
		cs.push16(cs.PC)
		cs.push8(cs.P | flagBrk | flagOnStack)
		cs.P |= flagIrqDisabled
		cs.PC = cs.read16(0xfffe)
	} else if cs.BRK {
		cs.BRK = false
		cs.push16(cs.PC)
		cs.push8(cs.P | flagBrk | flagOnStack)
		cs.P |= flagIrqDisabled
		cs.PC = cs.read16(0xfffe)
	}
}

func (cs *cpuState) push16(val uint16) {
	cs.S -= 2
	cs.write16(0x100+uint16(cs.S), val)
}
func (cs *cpuState) push8(val byte) {
	cs.S--
	cs.write(0x100+uint16(cs.S), val)
}

func (cs *cpuState) pop16() uint16 {
	result := cs.read16(0x100 + uint16(cs.S))
	cs.S += 2
	return result
}
func (cs *cpuState) pop() byte {
	result := cs.read(0x100 + uint16(cs.S))
	cs.S++
	return result
}

func (cs *cpuState) interruptsEnabled() bool {
	return cs.P&flagIrqDisabled == 0
}

// Step steps the emulator one instruction
func (cs *cpuState) step() {

	cs.handleInterrupts()

	cs.Steps++

	cs.stepOpcode()
}

func newState(romBytes []byte) *cpuState {
	cartInfo, _ := ParseCartInfo(romBytes)
	prgStart := cartInfo.GetROMOffsetPrg()
	prgEnd := prgStart + cartInfo.GetROMSizePrg()
	chrStart := cartInfo.GetROMOffsetChr()
	chrEnd := chrStart + cartInfo.GetROMSizeChr()
	cs := cpuState{
		Mem: mem{
			MMC:    makeMMC(cartInfo),
			PrgROM: romBytes[prgStart:prgEnd],
			ChrROM: romBytes[chrStart:chrEnd],
		},
		RESET: true,
	}
	return &cs
}

// Joypad represents the buttons on a gamepad
type Joypad struct {
	Sel   bool
	Start bool
	Up    bool
	Down  bool
	Left  bool
	Right bool
	A     bool
	B     bool
}

func stepErr(args ...interface{}) {
	fmt.Println(args...)
	os.Exit(1)
}
<commit_msg>Or in correct bit in joypad regs, reset jp2 count<commit_after>package famigo

import (
	"fmt"
	"os"
)

type cpuState struct {
	Mem mem

	PPU ppu
	APU apu

	PC            uint16
	P, A, X, Y, S byte

	IRQ, BRK, NMI, RESET bool

	Steps uint64

	CurrentJoypad1 Joypad
	CurrentJoypad2 Joypad // empty for now

	JoypadReg1          Joypad
	JoypadReg2          Joypad
	ReloadingJoypads    bool
	JoypadReg1ReadCount byte
	JoypadReg2ReadCount byte
}

func (cs *cpuState) writeJoypadReg1(val byte) {
	if val&0x01 != 0 {
		cs.ReloadingJoypads = true
		cs.JoypadReg1ReadCount = 0
		cs.JoypadReg2ReadCount = 0
	} else if cs.ReloadingJoypads {
		cs.ReloadingJoypads = false
	}
}
func (cs *cpuState) getCurrentButtonState(jp *Joypad, readCount byte) bool {
	tbl := []bool{jp.A, jp.B, jp.Sel, jp.Start, jp.Up, jp.Down, jp.Left, jp.Right}
	return tbl[readCount]
}
func (cs *cpuState) readJoypadReg1() byte {
	jp := &cs.CurrentJoypad1
	if cs.ReloadingJoypads {
		return 0x40 | boolBit(jp.A, 0)
	} else if cs.JoypadReg1ReadCount > 7 {
		return 0x41
	}
	state := cs.getCurrentButtonState(jp, cs.JoypadReg1ReadCount)
	cs.JoypadReg1ReadCount++
	return 0x40 | boolBit(state, 0)
}

// writes for this reg handled by apu.writeFrameCounterReg
func (cs *cpuState) readJoypadReg2() byte {
	jp := &cs.CurrentJoypad2
	if cs.ReloadingJoypads {
		return 0x40 | boolBit(jp.A, 0)
	} else if cs.JoypadReg2ReadCount > 7 {
		return 0x41
	}
	state := cs.getCurrentButtonState(jp, cs.JoypadReg2ReadCount)
	cs.JoypadReg2ReadCount++
	return 0x40 | boolBit(state, 0)
}

func (cs *cpuState) runCycles(cycles uint) {
	for i := uint(0); i < cycles; i++ {
		for j := 0; j < 3; j++ {
			cs.PPU.runCycle(cs) // ppu clock is 3x cpu
		}
	}
}

func (cs *cpuState) debugStatusLine() string {
	fmt.Println()
	opcode := cs.read(cs.PC)
	b2, b3 := cs.read(cs.PC+1), cs.read(cs.PC+2)
	return fmt.Sprintf("Steps: %09d ", cs.Steps) +
		fmt.Sprintf("PC:%04x ", cs.PC) +
		fmt.Sprintf("*PC[0:2]:%02x%02x%02x ", opcode, b2, b3) +
		fmt.Sprintf("opcode:%v ", opcodeNames[opcode]) +
		fmt.Sprintf("S:%02x ", cs.S) +
		fmt.Sprintf("A:%02x ", cs.A) +
		fmt.Sprintf("P:%02x ", cs.P) +
		fmt.Sprintf("X:%02x ", cs.X) +
		fmt.Sprintf("Y:%02x ", cs.Y) +
		fmt.Sprintf("IRQ:%v ", cs.IRQ) +
		fmt.Sprintf("BRK:%v ", cs.BRK) +
		fmt.Sprintf("NMI:%v ", cs.NMI) +
		fmt.Sprintf("RESET:%v", cs.RESET)
}

const (
	flagNeg         = 0x80
	flagOverflow    = 0x40
	flagOnStack     = 0x10
	flagBrk         = 0x10
	flagDecimal     = 0x08 // unused
	flagIrqDisabled = 0x04
	flagZero        = 0x02
	flagCarry       = 0x01
)

func (cs *cpuState) handleInterrupts() {
	if cs.RESET {
		cs.RESET = false
		cs.PC = cs.read16(0xfffc)
	} else if cs.NMI {
		cs.NMI = false
		cs.push16(cs.PC)
		cs.push8(cs.P | flagOnStack)
		cs.P |= flagIrqDisabled
		cs.PC = cs.read16(0xfffa)
	} else if cs.IRQ && cs.interruptsEnabled() {
		cs.IRQ = false
		cs.push16(cs.PC)
		cs.push8(cs.P | flagBrk | flagOnStack)
		cs.P |= flagIrqDisabled
		cs.PC = cs.read16(0xfffe)
	} else if cs.BRK {
		cs.BRK = false
		cs.push16(cs.PC)
		cs.push8(cs.P | flagBrk | flagOnStack)
		cs.P |= flagIrqDisabled
		cs.PC = cs.read16(0xfffe)
	}
}

func (cs *cpuState) push16(val uint16) {
	cs.S -= 2
	cs.write16(0x100+uint16(cs.S), val)
}
func (cs *cpuState) push8(val byte) {
	cs.S--
	cs.write(0x100+uint16(cs.S), val)
}

func (cs *cpuState) pop16() uint16 {
	result := cs.read16(0x100 + uint16(cs.S))
	cs.S += 2
	return result
}
func (cs *cpuState) pop() byte {
	result := cs.read(0x100 + uint16(cs.S))
	cs.S++
	return result
}

func (cs *cpuState) interruptsEnabled() bool {
	return cs.P&flagIrqDisabled == 0
}

// Step steps the emulator one instruction
func (cs *cpuState) step() {

	cs.handleInterrupts()

	cs.Steps++

	cs.stepOpcode()
}

func newState(romBytes []byte) *cpuState {
	cartInfo, _ := ParseCartInfo(romBytes)
	prgStart := cartInfo.GetROMOffsetPrg()
	prgEnd := prgStart + cartInfo.GetROMSizePrg()
	chrStart := cartInfo.GetROMOffsetChr()
	chrEnd := chrStart + cartInfo.GetROMSizeChr()
	cs := cpuState{
		Mem: mem{
			MMC:    makeMMC(cartInfo),
			PrgROM: romBytes[prgStart:prgEnd],
			ChrROM: romBytes[chrStart:chrEnd],
		},
		RESET: true,
	}
	return &cs
}

// Joypad represents the buttons on a gamepad
type Joypad struct {
	Sel   bool
	Start bool
	Up    bool
	Down  bool
	Left  bool
	Right bool
	A     bool
	B     bool
}

func stepErr(args ...interface{}) {
	fmt.Println(args...)
	os.Exit(1)
}
<|endoftext|>