package controllers

import "k8s.io/client-go/tools/cache"

var (
	KeyFunc = cache.DeletionHandlingMetaNamespaceKeyFunc
)

package controllers

import (
	"reflect"

	"k8s.io/apimachinery/pkg/util/runtime"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/util/workqueue"
)

var (
	KeyFunc = cache.DeletionHandlingMetaNamespaceKeyFunc
)

type QueuingEventHandler struct {
	Queue workqueue.RateLimitingInterface
}

func (q *QueuingEventHandler) Enqueue(obj interface{}) {
	key, err := KeyFunc(obj)
	if err != nil {
		runtime.HandleError(err)
		return
	}
	q.Queue.Add(key)
}

func (q *QueuingEventHandler) OnAdd(obj interface{}) {
	q.Enqueue(obj)
}

func (q *QueuingEventHandler) OnUpdate(old, new interface{}) {
	if reflect.DeepEqual(old, new) {
		return
	}
	q.Enqueue(new)
}

func (q *QueuingEventHandler) OnDelete(obj interface{}) {
	q.Enqueue(obj)
}

type BlockingEventHandler struct {
	WorkFunc func(obj interface{})
}

func (b *BlockingEventHandler) Enqueue(obj interface{}) {
	b.WorkFunc(obj)
}

func (b *BlockingEventHandler) OnAdd(obj interface{}) {
	b.WorkFunc(obj)
}

func (b *BlockingEventHandler) OnUpdate(old, new interface{}) {
	if reflect.DeepEqual(old, new) {
		return
	}
	b.WorkFunc(new)
}

func (b *BlockingEventHandler) OnDelete(obj interface{}) {
	b.WorkFunc(obj)
}

Add QueueingEventHandler and BlockingEventHandler types


package cmd

import (
	"fmt"
	"log"

	"github.com/codegangsta/cli"
	"github.com/exercism/cli/api"
	"github.com/exercism/cli/config"
	"github.com/exercism/cli/user"
)

// Tracks lists available tracks.
func Tracks(ctx *cli.Context) {
	c, err := config.New(ctx.GlobalString("config"))
	if err != nil {
		log.Fatal(err)
	}
	client := api.NewClient(c)

	tracks, err := client.Tracks()
	if err != nil {
		log.Fatal(err)
	}

	curr := user.NewCurriculum(tracks)
	fmt.Println("\nActive language tracks:")
	curr.Report(user.TrackActive)
	fmt.Println("\nInactive language tracks:")
	curr.Report(user.TrackInactive)

	// TODO: implement `list` command to list problems in a track
	msg := `
Related commands:
    exercism fetch (see 'exercism help fetch')
	`
	fmt.Println(msg)
}

package cmd

import (
	"fmt"
	"log"

	"github.com/codegangsta/cli"
	"github.com/exercism/cli/api"
	"github.com/exercism/cli/config"
	"github.com/exercism/cli/user"
)

// Tracks lists available tracks.
func Tracks(ctx *cli.Context) {
	c, err := config.New(ctx.GlobalString("config"))
	if err != nil {
		log.Fatal(err)
	}
	client := api.NewClient(c)

	tracks, err := client.Tracks()
	if err != nil {
		log.Fatal(err)
	}

	curr := user.NewCurriculum(tracks)
	fmt.Println("\nActive language tracks:")
	curr.Report(user.TrackActive)
	fmt.Println("\nInactive language tracks:")
	curr.Report(user.TrackInactive)

	// TODO: implement `list` command to list problems in a track
	msg := `
Related commands:
    exercism fetch (see 'exercism help fetch')
    exercism lisp (see 'exercism help list')
	`
	fmt.Println(msg)
}

Add more helpful output to the user


// +build windows

package gps

import (
	"os/exec"
	"testing"
)

// setupUsingJunctions inflates fs onto the host file system, but uses Windows
// directory junctions for links.
func (fs filesystemState) setupUsingJunctions(t *testing.T) {
	fs.setupDirs(t)
	fs.setupFiles(t)
	fs.setupJunctions(t)
}

func (fs filesystemState) setupJunctions(t *testing.T) {
	for _, link := range fs.links {
		p := link.path.prepend(fs.root)
		// There is no way to make junctions in the standard library, so we'll just
		// do what the stdlib's os tests do: run mklink.
		output, err := exec.Command("cmd", "/c", "mklink", "/J", p.String(), link.to).CombinedOutput()
		if err != nil {
			t.Fatalf("failed to run mklink %v %v: %v %q", p.String(), link.to, err, output)
		}
	}
}

// +build windows

package gps

import (
	"os/exec"
	"testing"
)

// setupUsingJunctions inflates fs onto the host file system, but uses Windows
// directory junctions for links.
func (fs filesystemState) setupUsingJunctions(t *testing.T) {
	fs.setupDirs(t)
	fs.setupFiles(t)
	fs.setupJunctions(t)
}

func (fs filesystemState) setupJunctions(t *testing.T) {
	for _, link := range fs.links {
		from := link.path.prepend(fs.root)
		to := fsPath{link.to}.prepend(fs.root)
		// There is no way to make junctions in the standard library, so we'll just
		// do what the stdlib's os tests do: run mklink.
		//
		// Also, all junctions must point to absolute paths.
		output, err := exec.Command("cmd", "/c", "mklink", "/J", from.String(), to.String()).CombinedOutput()
		if err != nil {
			t.Fatalf("failed to run mklink %v %v: %v %q", from.String(), to.String(), err, output)
		}
	}
}

Create junction to an absolute path


package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"net"

	"github.com/skratchdot/open-golang/open"
)

func main() {
	var port int
	var host string
	flag.IntVar(&port, "port", 2489, "TCP port number")
	flag.StringVar(&host, "host", "localhost", "Remote hostname")
	flag.Parse()

	l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port))
	if err != nil {
		panic(err)
	}

	defer l.Close()
	for {
		conn, err := l.Accept()
		if err != nil {
			panic(err)
		}
		go handle(conn)
	}
}

func handle(conn net.Conn) {
	defer conn.Close()
	log.Printf("Request from %s", conn.RemoteAddr())
	line, err := bufio.NewReader(conn).ReadString('\000')

	if err != nil {
		log.Println(err)
		conn.Write([]byte(err.Error()))
		return
	}
	body := line[:len(line)-1]

	err = open.Run(string(body))
	if err != nil {
		log.Println(err)
		conn.Write([]byte(err.Error()))
		return
	}
}

package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"net"

	"github.com/skratchdot/open-golang/open"
)

func main() {
	var port int
	flag.IntVar(&port, "port", 2489, "TCP port number")
	flag.Parse()

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		panic(err)
	}

	defer l.Close()
	for {
		conn, err := l.Accept()
		if err != nil {
			panic(err)
		}
		go handle(conn)
	}
}

func handle(conn net.Conn) {
	defer conn.Close()
	log.Printf("Request from %s", conn.RemoteAddr())
	line, err := bufio.NewReader(conn).ReadString('\000')

	if err != nil {
		log.Println(err)
		conn.Write([]byte(err.Error()))
		return
	}
	body := line[:len(line)-1]

	err = open.Run(string(body))
	if err != nil {
		log.Println(err)
		conn.Write([]byte(err.Error()))
		return
	}
}

Enable to connect from remote


package stripe

import "encoding/json"

// DiscountParams is the set of parameters that can be used when deleting a discount.
type DiscountParams struct {
	Params `form:"*"`
}

// Discount is the resource representing a Stripe discount.
// For more details see https://stripe.com/docs/api#discounts.
type Discount struct {
	APIResource
	Coupon        *Coupon        `json:"coupon"`
	Customer      string         `json:"customer"`
	Deleted       bool           `json:"deleted"`
	End           int64          `json:"end"`
	ID            string         `json:"id"`
	Invoice       string         `json:"invoice"`
	InvoiceItem   string         `json:"invoice_item"`
	Object        string         `json:"object"`
	PromotionCode *PromotionCode `json:"promotion_code"`
	Start         int64          `json:"start"`
	Subscription  string         `json:"subscription"`
}

// UnmarshalJSON handles deserialization of a Discount.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (s *Discount) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		s.ID = id
		return nil
	}

	type discount Discount
	var v discount
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*s = Discount(v)
	return nil
}

package stripe

import "encoding/json"

// DiscountParams is the set of parameters that can be used when deleting a discount.
type DiscountParams struct {
	Params `form:"*"`
}

// Discount is the resource representing a Stripe discount.
// For more details see https://stripe.com/docs/api#discounts.
type Discount struct {
	APIResource
	CheckoutSession *CheckoutSession `json:"checkout_session"`
	Coupon          *Coupon          `json:"coupon"`
	Customer        string           `json:"customer"`
	Deleted         bool             `json:"deleted"`
	End             int64            `json:"end"`
	ID              string           `json:"id"`
	Invoice         string           `json:"invoice"`
	InvoiceItem     string           `json:"invoice_item"`
	Object          string           `json:"object"`
	PromotionCode   *PromotionCode   `json:"promotion_code"`
	Start           int64            `json:"start"`
	Subscription    string           `json:"subscription"`
}

// UnmarshalJSON handles deserialization of a Discount.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (s *Discount) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		s.ID = id
		return nil
	}

	type discount Discount
	var v discount
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*s = Discount(v)
	return nil
}

Add support for `CheckoutSession` on `Discount`


package bot

import (
	"os"
	"time"
)

// LogLevel for determining when to output a log entry
type LogLevel int

// Definitions of log levels in order from most to least verbose
const (
	Trace LogLevel = iota
	Debug
	Info
	Warn
	Error
	Fatal
)

// Log logs messages whenever the connector log level is
// less than the given level
func (b *robot) Log(l LogLevel, v ...interface{}) {
	if l >= b.level {
		var prefix string
		switch l {
		case Trace:
			prefix = "Trace:"
		case Debug:
			prefix = "Debug:"
		case Info:
			prefix = "Info:"
		case Warn:
			prefix = "Warning:"
		case Error:
			prefix = "Error:"
		case Fatal:
			prefix = "Fatal:"
		}
		b.logger.Println(prefix, v)
		if l == Fatal {
			time.Sleep(time.Second) // ample time for the log message to reach the file
			os.Exit(1)
		}
	}
}

// SetLogLevel updates the connector log level
func (b *robot) setLogLevel(l LogLevel) {
	b.lock.Lock()
	b.level = l
	b.lock.Unlock()
}

package bot

// LogLevel for determining when to output a log entry
type LogLevel int

// Definitions of log levels in order from most to least verbose
const (
	Trace LogLevel = iota
	Debug
	Info
	Warn
	Error
	Fatal
)

// Log logs messages whenever the connector log level is
// less than the given level
func (b *robot) Log(l LogLevel, v ...interface{}) {
	if l >= b.level {
		var prefix string
		switch l {
		case Trace:
			prefix = "Trace:"
		case Debug:
			prefix = "Debug:"
		case Info:
			prefix = "Info:"
		case Warn:
			prefix = "Warning:"
		case Error:
			prefix = "Error:"
		case Fatal:
			prefix = "Fatal:"
		}
		if l == Fatal {
			b.logger.Fatalln(prefix, v)
		} else {
			b.logger.Println(prefix, v)
		}
	}
}

// SetLogLevel updates the connector log level
func (b *robot) setLogLevel(l LogLevel) {
	b.lock.Lock()
	b.level = l
	b.lock.Unlock()
}

Use log.Fatalln to guarantee the final gasp is written to the log file


package slack

// https://api.slack.com/docs/attachments
// It is possible to create more richly-formatted messages using Attachments.
type AttachmentField struct {
	Title string `json:"title"`
	Value string `json:"value"`
	Short bool   `json:"short"`
}

type Attachment struct {
	Color    string `json:"color,omitempty"`
	Fallback string `json:"fallback"`

	AuthorName    string `json:"author_name,omitempty"`
	AuthorSubname string `json:"author_subname,omitempty"`
	AuthorLink    string `json:"author_link,omitempty"`
	AuthorIcon    string `json:"author_icon,omitempty"`

	Title     string `json:"title,omitempty"`
	TitleLink string `json:"title_link,omitempty"`
	Pretext   string `json:"pretext,omitempty"`
	Text      string `json:"text"`

	ImageURL string `json:"image_url,omitempty"`
	ThumbURL string `json:"thumb_url,omitempty"`

	Footer     string `json:"footer,omitempty"`
	FooterIcon string `json:"footer_icon,omitempty"`

	Fields     []*AttachmentField `json:"fields,omitempty"`
	MarkdownIn []string           `json:"mrkdwn_in,omitempty"`
}

package slack

// https://api.slack.com/docs/attachments
// It is possible to create more richly-formatted messages using Attachments.
type AttachmentField struct {
	Title string `json:"title"`
	Value string `json:"value"`
	Short bool   `json:"short"`
}

type Attachment struct {
	Color    string `json:"color,omitempty"`
	Fallback string `json:"fallback"`

	AuthorName    string `json:"author_name,omitempty"`
	AuthorSubname string `json:"author_subname,omitempty"`
	AuthorLink    string `json:"author_link,omitempty"`
	AuthorIcon    string `json:"author_icon,omitempty"`

	Title     string `json:"title,omitempty"`
	TitleLink string `json:"title_link,omitempty"`
	Pretext   string `json:"pretext,omitempty"`
	Text      string `json:"text"`

	ImageURL string `json:"image_url,omitempty"`
	ThumbURL string `json:"thumb_url,omitempty"`

	Footer     string `json:"footer,omitempty"`
	FooterIcon string `json:"footer_icon,omitempty"`
	TimeStamp  int64  `json:"ts,omitempty"`

	Fields     []*AttachmentField `json:"fields,omitempty"`
	MarkdownIn []string           `json:"mrkdwn_in,omitempty"`
}

Add unix timestamp field to Attachment struct


package main

import (
    "fmt"
    "os"
    "log"
    "io/ioutil"
    "github.com/ghodss/yaml"
)

func main() {
  byteArray, _ := ioutil.ReadAll(os.Stdin)
  y, err := yaml.YAMLToJSON(byteArray)
  if err != nil {
    log.Fatalf("error: %v", err)
  }
  fmt.Println(string(y))
}

package main

import (
    "fmt"
    "os"
    "io/ioutil"
    "github.com/ghodss/yaml"
    "encoding/json"
)

func main() {
  byteArray, _ := ioutil.ReadAll(os.Stdin)
  var o interface{}
  var y []byte

  err := json.Unmarshal(byteArray, &o)
  if err == nil {
    // JSON decoding succeeded, it's JSON
    y, err = yaml.JSONToYAML(byteArray)
  } else {
    // JSON decoding failed, it's probably YAML
    y, err = yaml.YAMLToJSON(byteArray)
  }

  if err != nil {
    fmt.Fprintf(os.Stderr, "ym: %v", err)
  }
  fmt.Println(string(y))
}

Convert from YAML to JSON and back.


package main

import "fmt"

func perrin() func() int {
	a, b, c := 3, 0, 2

	return func() int {
		a, b, c = b, c, a+b
		return a
	}
}

func perrin_max(max int) func() int {
	a, b, c := 3, 0, 2

	return func() int {
		if a >= max {
			return a
		}

		a, b, c = b, c, a+b
		return a
	}
}

func perrin_reset(max int) func() int {
	a, b, c := 3, 0, 2

	return func() int {
		if a >= max {
			a, b, c = 3, 0, 2
		}

		a, b, c = b, c, a+b
		return a
	}
}

func main() {

	p := perrin_max(100)
	for i := 3; i < 10000; i = p() {
		fmt.Println(i)
		if i == 119 {
			break
		}
	}
}

package goperrin

import "fmt"

func perrin() func() int {
	a, b, c := 3, 0, 2

	return func() int {
		a, b, c = b, c, a+b
		return a
	}
}

func perrin_max(max int) func() int {
	a, b, c := 3, 0, 2

	return func() int {
		if a >= max {
			return a
		}

		a, b, c = b, c, a+b
		return a
	}
}

func perrin_reset(max int) func() int {
	a, b, c := 3, 0, 2

	return func() int {
		if a >= max {
			a, b, c = 3, 0, 2
		}

		a, b, c = b, c, a+b
		return a
	}
}

Fix package namespace and remove main


// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"log"
	"sort"
	"time"
)

type Notifier interface {
	Notify(map[string]time.Time) error
}

type logNotifier struct{}

func (logNotifier) Notify(repos map[string]time.Time) error {
	keys := make([]string, 0, len(repos))
	for k := range repos {
		keys = append(keys, k)
	}
	sort.Sort(sort.StringSlice(keys))

	for _, k := range keys {
		log.Printf("%v\t: %v", k, repos[k])
	}
	return nil
}

type changesNotifier struct {
	Notifier

	last map[string]time.Time
}

func (d changesNotifier) Notify(repos map[string]time.Time) error {
	changes := make(map[string]time.Time)
	for k, v := range repos {
		if d.last[k] != v {
			changes[k] = v
			d.last[k] = v
		}
	}
	return d.Notifier.Notify(changes)
}

// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"log"
	"sort"
	"time"
)

type Notifier interface {
	Notify(map[string]time.Time) error
}

type logNotifier struct{}

func (logNotifier) Notify(repos map[string]time.Time) error {
	keys := make([]string, 0, len(repos))
	for k := range repos {
		keys = append(keys, k)
	}
	sort.Sort(sort.StringSlice(keys))

	for _, k := range keys {
		log.Printf("%v\t: %v", k, repos[k])
	}
	return nil
}

type changesNotifier struct {
	Notifier

	last map[string]time.Time
}

func (d changesNotifier) Notify(repos map[string]time.Time) error {
	changes := make(map[string]time.Time)
	for k, v := range repos {
		if d.last[k] != v {
			changes[k] = v
			d.last[k] = v
		}
	}

	if len(changes) == 0 {
		return nil
	}
	return d.Notifier.Notify(changes)
}

Update changesNotifier to only call underlying Notifier if repos is non-empty


package mc

import "errors"

var (
	ErrInvalidProjectFilePath = errors.New("path not in project")
	ErrFileNotUploaded        = errors.New("existing file not uploaded")
	ErrFileVersionNotUploaded = errors.New("existing file with new version not uploaded")
)

package mc

import "errors"

var (
	ErrInvalidProjectFilePath = errors.New("path not in project")
	ErrFileNotUploaded        = errors.New("existing file not uploaded")
	ErrFileVersionNotUploaded = errors.New("existing file has changes that haven't been uploaded")
)

Make ErrFileVersionNotUploaded error message more understandable.


package main

import (
	"os"
	"exec"
	"bytes"
	"io"
	"strings"
	"clingon"
)

type ShellEvaluator struct{}

func (eval *ShellEvaluator) Run(console *clingon.Console, command string) os.Error {
	out, err := system(command, exec.DevNull, exec.Pipe, exec.MergeWithStdout)
	if err != nil {
		return err
	}
	console.Print(out)
	return nil
}

func system(command string, args ...int) (out string, err os.Error) {

	runParams := [3]int{exec.DevNull, exec.PassThrough, exec.MergeWithStdout}

	if len(args) > 0 && len(args) <= 3 {
		for i := 0; i < len(args); i++ {
			runParams[i] = args[i]
		}
	}
	return run([]string{os.Getenv("SHELL"), "-c", command}, runParams[0], runParams[1], runParams[2])
}

func copy(a []string) []string {
	b := make([]string, len(a))
	for i, s := range a {
		b[i] = s
	}
	return b
}

func run(argv []string, stdin, stdout, stderr int) (out string, err os.Error) {

	if len(argv) < 1 {
		err = os.EINVAL
		goto Error
	}

	var cmd *exec.Cmd

	cmd, err = exec.Run(argv[0], argv, os.Environ(), "", stdin, stdout, stderr)

	if err != nil {
		goto Error
	}

	defer cmd.Close()

	var buf bytes.Buffer

	_, err = io.Copy(&buf, cmd.Stdout)
	out = buf.String()

	if err != nil {
		cmd.Wait(0)
		goto Error
	}

	w, err := cmd.Wait(0)

	if err != nil {
		goto Error
	}

	if !w.Exited() || w.ExitStatus() != 0 {
		err = w
		goto Error
	}

	return

Error:
	err = &runError{copy(argv), err}
	return
}

// A runError represents an error that occurred while running a command.
type runError struct {
	cmd []string
	err os.Error
}

func (e *runError) String() string { return strings.Join(e.cmd, " ") + ": " + e.err.String() }

package main

import (
	"bytes"
	"exec"
	"os"
	"clingon"
)

type ShellEvaluator struct{}

func (eval *ShellEvaluator) Run(console *clingon.Console, command string) os.Error {
	var buf bytes.Buffer

	cmd := exec.Command(os.Getenv("SHELL"), "-c", command)
	cmd.Stdout = &buf
	cmd.Stderr = &buf
	err := cmd.Run()

	console.Print(buf.String())

	return err
}

Update in response to Go weekly.2011-06-02


package main

import (
	"bytes"
	"os/exec"
)

const script = `
tell application "System Events"
  set frontApp to name of first application process whose frontmost is true

  set activeURL to ""
  if frontApp is "Google Chrome" then
    tell application "Google Chrome"
      set normalWindows to (windows whose mode is not "incognito")

            if length of normalWindows is greater than 0 then
                set activeURL to (get URL of active tab of (first item of normalWindows))
            end if
    end tell
  end if
end tell

if activeURL is not "" then
  activeURL
else
  frontApp
end if
`

func GetActivityName() (string, error) {
	cmd := exec.Command("osascript", "-")
	cmd.Stdin = bytes.NewBufferString(script)
	output, err := cmd.Output()

	return string(output), err
}

package main

import (
	"bytes"
	"os/exec"
	"strings"
)

const script = `
tell application "System Events"
  set frontApp to name of first application process whose frontmost is true

  set activeURL to ""
  if frontApp is "Google Chrome" then
    tell application "Google Chrome"
      set normalWindows to (windows whose mode is not "incognito")

            if length of normalWindows is greater than 0 then
                set activeURL to (get URL of active tab of (first item of normalWindows))
            end if
    end tell
  end if
end tell

if activeURL is not "" then
  activeURL
else
  frontApp
end if
`

func GetActivityName() (string, error) {
	cmd := exec.Command("osascript", "-")
	cmd.Stdin = bytes.NewBufferString(script)
	output, err := cmd.Output()

	return strings.Replace(string(output), "\n", "", -1), err
}

Fix a small bug with new line


package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"
	"sort"

	"github.com/eknkc/amber"
)

//template map
var templateMap map[string]*template.Template

//initialization of the template map
func init() {
	templateMap, _ = amber.CompileDir("views",
		amber.DirOptions{Ext: ".amber", Recursive: true},
		amber.Options{PrettyPrint: false, LineNumbers: false})
}

//complete web server function
func webServer() {
	//Sets path handler funcions
	http.HandleFunc("/", animeHandler)
	http.HandleFunc("/static/", staticHandler)

	//Sets url and port
	bind := fmt.Sprintf("%s:%s", "127.0.0.1", "422")
	if os.Getenv("OPENSHIFT_GO_IP") != "" &&
		os.Getenv("OPENSHIFT_GO_PORT") != "" {
		bind = fmt.Sprintf("%s:%s", os.Getenv("OPENSHIFT_GO_IP"),
			os.Getenv("OPENSHIFT_GO_PORT"))
	}

	//Listen and sert to port
	log.Printf("Web server listening on %s", bind)
	err := http.ListenAndServe(bind, nil)
	if err != nil {
		log.Fatal("webServer() => ListenAndServer() error:\t", err)
	}
}

// /anime path handler
func animeHandler(w http.ResponseWriter, r *http.Request) {
	data := getAnimeList()
	sort.Sort(data)
	templateMap["aList"].Execute(w, data)
}

// /static/* file server
func staticHandler(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, r.URL.Path[1:])
}

package main

import (
	"html/template"
	"net/http"
	"sort"

	"github.com/eknkc/amber"
	"google.golang.org/appengine"
)

//template map
var templateMap map[string]*template.Template

//initialization of the template map
func init() {
	templateMap, _ = amber.CompileDir("views",
		amber.DirOptions{Ext: ".amber", Recursive: true},
		amber.Options{PrettyPrint: false, LineNumbers: false})
}

//complete web server function
func webServer() {
	//Sets path handler funcions
	http.HandleFunc("/", animeHandler)
	http.HandleFunc("/static/", staticHandler)

	appengine.Main()
}

// /anime path handler
func animeHandler(w http.ResponseWriter, r *http.Request) {
	data := getAnimeList()
	sort.Sort(data)
	templateMap["aList"].Execute(w, data)
}

// /static/* file server
func staticHandler(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, r.URL.Path[1:])
}

Switch to google app engine


package request

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

func NewRequest(url, bearerToken string) (*http.Response, error) {
	client := &http.Client{}

	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	request.Header.Add("Authorization", "Bearer "+bearerToken)
	return client.Do(request)
}

func ReadResponseBody(response *http.Response) (string, error) {
	body, err := ioutil.ReadAll(response.Body)
	defer response.Body.Close()

	return strings.TrimSpace(string(body)), err
}

package request

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

func NewRequest(url, bearerToken string) (*http.Response, error) {
	client := &http.Client{}

	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	request.Header.Add("Authorization", "Bearer "+bearerToken)
	request.Header.Add("Accept", "application/json")

	return client.Do(request)
}

func ReadResponseBody(response *http.Response) (string, error) {
	body, err := ioutil.ReadAll(response.Body)
	defer response.Body.Close()

	return strings.TrimSpace(string(body)), err
}

Set the `Accept` header to allow JSON responses


// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tri

import "github.com/cpmech/gosl/plt"

func Draw(V [][]float64, C [][]int, style *plt.A) {
	if style == nil {
		style = &plt.A{C: "b", M: "o", Ms: 2}
	}
	type edgeType struct{ A, B int }
	drawnEdges := make(map[edgeType]bool)
	for _, cell := range C {
		for i := 0; i < 3; i++ {
			a, b := cell[i], cell[(i+1)%3]
			edge := edgeType{a, b}
			if b < a {
				edge.A, edge.B = edge.B, edge.A
			}
			if _, found := drawnEdges[edge]; !found {
				x := []float64{V[a][0], V[b][0]}
				y := []float64{V[a][1], V[b][1]}
				plt.Plot(x, y, nil)
				drawnEdges[edge] = true
			}
		}
	}
}

// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tri

import "github.com/cpmech/gosl/plt"

func Draw(V [][]float64, C [][]int, style *plt.A) {
	if style == nil {
		style = &plt.A{C: "b", M: "o", Ms: 2}
	}
	type edgeType struct{ A, B int }
	drawnEdges := make(map[edgeType]bool)
	for _, cell := range C {
		for i := 0; i < 3; i++ {
			a, b := cell[i], cell[(i+1)%3]
			edge := edgeType{a, b}
			if b < a {
				edge.A, edge.B = edge.B, edge.A
			}
			if _, found := drawnEdges[edge]; !found {
				x := []float64{V[a][0], V[b][0]}
				y := []float64{V[a][1], V[b][1]}
				plt.Plot(x, y, style)
				drawnEdges[edge] = true
			}
		}
	}
}

Fix use of style in tri.Draw


package inmem

import (
	"io"
	"fmt"
)

type ReceiverFrom interface {
	ReceiveFrom(Receiver) (int, error)
}

type SenderTo interface {
	SendTo(Sender) (int, error)
}

func Copy(dst Sender, src Receiver) (int, error) {
	if senderTo, ok := src.(SenderTo); ok {
		return senderTo.SendTo(dst)
	}
	if receiverFrom, ok := dst.(ReceiverFrom); ok {
		return receiverFrom.ReceiveFrom(src)
	}
	var (
		n int
	)
	for {
		msg, r, w, err := src.Receive(R|W)
		if err == io.EOF {
			break
		}
		if r != nil {
			// FIXME: spawn goroutines to shuttle messages for each
			// level of nested sender/receiver.
			r.Close()
			return n, fmt.Errorf("operation not supported")
		}
		if w != nil {
			// FIXME: spawn goroutines to shuttle messages for each
			// level of nested sender/receiver.
			w.Close()
			return n, fmt.Errorf("operation not supported")
		}
		if err != nil {
			return n, err
		}
		if _, _, err := dst.Send(msg, 0); err != nil {
			return n, err
		}
		n++
	}
	return n, nil
}

package inmem

import (
	"fmt"
)

type ReceiverFrom interface {
	ReceiveFrom(Receiver) (int, error)
}

type SenderTo interface {
	SendTo(Sender) (int, error)
}

func Copy(dst Sender, src Receiver) (int, error) {
	if senderTo, ok := src.(SenderTo); ok {
		return senderTo.SendTo(dst)
	}
	if receiverFrom, ok := dst.(ReceiverFrom); ok {
		return receiverFrom.ReceiveFrom(src)
	}
	var (
		n int
	)
	return n, fmt.Errorf("operation not supported")
}

Copy requires either SenderTo or ReceiverFrom


package main

type From struct {
	Image  string
	Tag    string
	Digest string
}

type Maintainer struct {
	Name string
}

type Run struct {
	Tokens []string
}

type Cmd struct {
	Tokens []string
}

type Lable struct {
	Labels map[string]string
}

type Expose struct {
	Ports []int
}

type Env struct {
	Variables map[string]string
}

type Add struct {
	Sources     []string
	Destination string
}

type Copy struct {
	Sources     []string
	Destination string
}

type Entrypoint struct {
	Tokens []string
}

type Volume struct {
	Points []string
}

type User struct {
	Name string
}

type Workdir struct {
	Path string
}

type Onbuild struct {
	// to be inplemented
}

package main

type Statement interface {
	statement()
}

type Dockerfile []*Statement

type From struct {
	Image  string
	Tag    string
	Digest string
}

type Maintainer struct {
	Name string
}

type Run struct {
	Tokens []string
}

type Cmd struct {
	Tokens []string
}

type Lable struct {
	Labels map[string]string
}

type Expose struct {
	Ports []int
}

type Env struct {
	Variables map[string]string
}

type Add struct {
	Sources     []string
	Destination string
}

type Copy struct {
	Sources     []string
	Destination string
}

type Entrypoint struct {
	Tokens []string
}

type Volume struct {
	Points []string
}

type User struct {
	Name string
}

type Workdir struct {
	Path string
}

type Onbuild struct {
	Statement *Statement
}

func (x *From) statement()       {}
func (x *Maintainer) statement() {}
func (x *Run) statement()        {}
func (x *Cmd) statement()        {}
func (x *Lable) statement()      {}
func (x *Expose) statement()     {}
func (x *Env) statement()        {}
func (x *Add) statement()        {}
func (x *Copy) statement()       {}
func (x *Entrypoint) statement() {}
func (x *Volume) statement()     {}
func (x *User) statement()       {}
func (x *Workdir) statement()    {}
func (x *Onbuild) statement()    {}

Make interfaces of the statements


package main

import(
	"io"
	"log"
	"net"
)

func main() {
	log.Print("Starting the server")
	listener, err := net.Listen("tcp", "127.0.0.1:8377")
	if err != nil {
		log.Fatal(err.Error())
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Print(err.Error())
			return
		}

		go handleConnection(conn)
	}
}

func handleConnection(conn net.Conn) {
	copied, err := io.Copy(conn, conn)
	if err != nil {
		log.Print(err.Error())
	} else {
		log.Print("Echoed ", copied, " bytes")
	}
	conn.Close()
	log.Print("Connection closed")
}

package main

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

func main() {
	_, err := exec.LookPath("pbcopy")
	if err != nil {
		log.Fatal(err.Error())
	}

	log.Print("Starting the server")
	listener, err := net.Listen("tcp", "127.0.0.1:8377")
	if err != nil {
		log.Fatal(err.Error())
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Print(err.Error())
			return
		}

		go handleConnection(conn)
	}
}

func handleConnection(conn net.Conn) {
	copied, err := io.Copy(conn, conn)
	if err != nil {
		log.Print(err.Error())
	} else {
		log.Print("Echoed ", copied, " bytes")
	}
	conn.Close()
	log.Print("Connection closed")
}

Check for presence of `pbcopy` executable at boot


package main

import "testing"

func TestNopFormatterDoesNothing(t *testing.T) {
	src := []byte{68, 68, 68}
	fmted, err := NopFormatter().Format(src)
	if err != nil {
		t.Fatal(err)
	}

	if !same(fmted, src) {
		t.Errorf("want %v, got: %v\n", src, fmted)
	}
}

func TestJSONFormatter(t *testing.T) {
	src := []byte(`{"json":false}`)
	want := []byte(`{
  "json": true
}`)

	f := &JSONFormatter{
		Prefix: "",
		Indent: "  ",
	}
	fmted, err := f.Format(src)
	if err != nil {
		t.Fatal(err)
	}

	if !same(fmted, want) {
		t.Errorf("want %v, got: %v\n", want, fmted)
	}
}

func same(a, b []byte) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

package main

import "testing"

func TestNopFormatterDoesNothing(t *testing.T) {
	src := []byte{68, 68, 68}
	fmted, err := NopFormatter().Format(src)
	if err != nil {
		t.Fatal(err)
	}

	if !same(fmted, src) {
		t.Errorf("want %v, got: %v\n", src, fmted)
	}
}

func TestJSONFormatter(t *testing.T) {
	src := []byte(`{"json":true}`)
	want := []byte(`{
  "json": true
}`)

	f := &JSONFormatter{
		Prefix: "",
		Indent: "  ",
	}
	fmted, err := f.Format(src)
	if err != nil {
		t.Fatal(err)
	}

	if !same(fmted, want) {
		t.Errorf("want %v, got: %v\n", want, fmted)
	}
}

func same(a, b []byte) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

Revert "Brake tests for demo purposes"


package feeder

import "socialapi/workers/sitemap/models"

type FileNameFetcher interface {
	Fetch(i *models.SitemapItem) string
}

type SimpleNameFetcher struct{}

func (s SimpleNameFetcher) Fetch(i *models.SitemapItem) string {
	// TODO implement this
	return "firstfile"
}

package feeder

import (
	"fmt"
	"math"
	"socialapi/workers/sitemap/models"
)

type FileNameFetcher interface {
	Fetch(i *models.SitemapItem) string
}

type SimpleNameFetcher struct{}

func (r SimpleNameFetcher) Fetch(i *models.SitemapItem) string {
	return "sitemap"
}

type ModNameFetcher struct{}

func (r ModNameFetcher) Fetch(i *models.SitemapItem) string {
	switch i.TypeConstant {
	case models.TYPE_ACCOUNT:
		return fetchAccountFileName(i.Id)
	case models.TYPE_CHANNEL_MESSAGE:
		return fetchChannelMessageName(i.Id)
	case models.TYPE_CHANNEL:
		return fetchChannelName(i.Id)
	}

	return ""
}

func fetchAccountFileName(id int64) string {
	return fmt.Sprintf("account_%d", id/int64(10000))
}

func fetchChannelMessageName(id int64) string {
	remainder := math.Mod(float64(id), float64(10000))
	return fmt.Sprintf("channel_message_%d", int64(remainder))
}

func fetchChannelName(id int64) string {
	remainder := math.Mod(float64(id), float64(10000))
	return fmt.Sprintf("channel_%d", int64(remainder))
}

Add ModNameFetcher for fething file names with respect to their id modulo


package core

import (
	"google.golang.org/grpc"
	"log"
	"os"
	msg "qpm.io/common/messages"
	"google.golang.org/grpc/credentials"
)

const (
	Version       = "0.0.1"
	PackageFile   = "qpm.json"
	SignatureFile = "qpm.asc"
	Vendor        = "vendor"
	Address       = "pkg.qpm.io:7000"
	LicenseFile   = "LICENSE"
)

type Context struct {
	Log    *log.Logger
	Client msg.QpmClient
}

func NewContext() *Context {
	log := log.New(os.Stderr, "QPM: ", log.LstdFlags)

	creds := credentials.NewClientTLSFromCert(nil, "")
	conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(creds))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}

	return &Context{
		Log:    log,
		Client: msg.NewQpmClient(conn),
	}
}

package core

import (
	"google.golang.org/grpc"
	"log"
	"os"
	msg "qpm.io/common/messages"
	"google.golang.org/grpc/credentials"
)

const (
	Version       = "0.0.1"
	PackageFile   = "qpm.json"
	SignatureFile = "qpm.asc"
	Vendor        = "vendor"
	Address       = "pkg.qpm.io:7000"
	LicenseFile   = "LICENSE"
)

type Context struct {
	Log    *log.Logger
	Client msg.QpmClient
}

func NewContext() *Context {
	log := log.New(os.Stderr, "QPM: ", log.LstdFlags)

	creds := credentials.NewClientTLSFromCert(nil, "")
	address := os.Getenv("SERVER")
	if address == "" {
		address = Address
	}
	conn, err := grpc.Dial(address, grpc.WithTransportCredentials(creds))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}

	return &Context{
		Log:    log,
		Client: msg.NewQpmClient(conn),
	}
}

Add an environment variable to override the server backend instance


package main

import (
	"os"

	"golang.org/x/net/context"

	"github.com/BeepBoopHQ/go-slackbot"
	"github.com/nlopes/slack"
)

func main() {
	bot := slackbot.New(os.Getenv("SLACK_TOKEN"))

	toMe := bot.Messages(slackbot.DirectMessage, slackbot.DirectMention).Subrouter()
	toMe.Hear("(?i)(hi|hello).*").MessageHandler(HelloHandler)
	bot.Hear("(?i)how are you(.*)").MessageHandler(HowAreYouHandler)
	bot.Run()
}

func HelloHandler(ctx context.Context, bot *slackbot.Bot, msg *slack.MessageEvent) {
	bot.ReplyAndType(msg, "Oh hello!")
}

func HowAreYouHandler(ctx context.Context, bot *slackbot.Bot, msg *slack.MessageEvent) {
	bot.ReplyAndType(msg, "A bit tired. You get it? A bit?")
}

package main

import (
	"os"

	"golang.org/x/net/context"

	"github.com/BeepBoopHQ/go-slackbot"
	"github.com/nlopes/slack"
)

func main() {
	bot := slackbot.New(os.Getenv("SLACK_TOKEN"))

	toMe := bot.Messages(slackbot.DirectMessage, slackbot.DirectMention).Subrouter()
	toMe.Hear("(?i)(hi|hello).*").MessageHandler(HelloHandler)
	bot.Hear("(?i)how are you(.*)").MessageHandler(HowAreYouHandler)
	bot.Hear("(?)attachment").MessageHandler(AttachmentsHandler)
	bot.Run()
}

func HelloHandler(ctx context.Context, bot *slackbot.Bot, msg *slack.MessageEvent) {
	bot.ReplyAndType(msg, "Oh hello!")
}

func HowAreYouHandler(ctx context.Context, bot *slackbot.Bot, msg *slack.MessageEvent) {
	bot.ReplyAndType(msg, "A bit tired. You get it? A bit?")
}

func AttachmentsHandler(ctx context.Context, bot *slackbot.Bot, msg *slack.MessageEvent) {
	txt := "Beep Beep Boop is a ridiculously simple hosting platform for your Slackbots."
	attachment := slack.Attachment{
		Pretext:   "We bring bots to life. :sunglasses: :thumbsup:",
		Title:     "Host, deploy and share your bot in seconds.",
		TitleLink: "https://beepboophq.com/",
		Text:      txt,
		Fallback:  txt,
		ImageURL:  "https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png",
		Color:     "#7CD197",
	}

	// supports multiple attachments
	attachments := []slack.Attachment{attachment}

	typingDelay := 4
	bot.ReplyAttachmentsAndType(msg, typingDelay, attachments)
}

Update Example to include attachment functionality.


package commons

import (
	"encoding/json"
	"log"
	"os"
)

type Manager interface {
	Commit() error
	GetSaveFilePath() (fullPath string, dirPath string, fileName string)
	GetConfig() interface{}
}

func LoadFromDB(manager Manager) {
	f, err := OpenSaveFile(manager, os.O_RDONLY)
	defer f.Close()
	Check(err)
	err = json.NewDecoder(f).Decode(manager.GetConfig())
	log.Println(err)
	Check(err)
}

func Commit(manager Manager) error {
	configFullPath, _, configFileName := manager.GetSaveFilePath()
	f, err := OpenSaveFile(manager, os.O_WRONLY)
	defer f.Close()

	if err != nil {
		log.Printf("Unable to open configuration file %s (%s) : %s", configFileName, configFullPath, err)
		return err
	}

	if err = json.NewEncoder(f).Encode(manager.GetConfig()); err != nil {
		log.Printf("Unable to write in configuration file %s (%s) : %s", configFileName, configFullPath, err)
	}

	return err
}

func OpenSaveFile(manager Manager, osFlag int) (*os.File, error) {
	configFullPath, _, _ := manager.GetSaveFilePath()

	return os.OpenFile(configFullPath, osFlag|os.O_CREATE|os.O_TRUNC, 0644)
}

package commons

import (
	"encoding/json"
	"log"
	"os"
)

type Manager interface {
	Commit() error
	GetSaveFilePath() (fullPath string, dirPath string, fileName string)
	GetConfig() interface{}
}

func LoadFromDB(manager Manager) {
	f, err := OpenSaveFile(manager, os.O_RDONLY)
	defer f.Close()
	Check(err)
	err = json.NewDecoder(f).Decode(manager.GetConfig())
	log.Println(err)
	Check(err)
}

func Commit(manager Manager) error {
	configFullPath, _, configFileName := manager.GetSaveFilePath()
	f, err := OpenSaveFile(manager, os.O_WRONLY)
	defer f.Close()

	if err != nil {
		log.Printf("Unable to open configuration file %s (%s) : %s", configFileName, configFullPath, err)
		return err
	}

	if err = json.NewEncoder(f).Encode(manager.GetConfig()); err != nil {
		log.Printf("Unable to write in configuration file %s (%s) : %s", configFileName, configFullPath, err)
	}

	return err
}

func OpenSaveFile(manager Manager, osFlag int) (*os.File, error) {
	configFullPath, _, _ := manager.GetSaveFilePath()

	return os.OpenFile(configFullPath, osFlag|os.O_CREATE, 0644)
}

Fix empty file at boot of backend


package integration_test

import (
	"io/ioutil"
	"os"
	"testing"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	bmtestutils "github.com/cloudfoundry/bosh-micro-cli/testutils"
)

var testCpiFilePath string

func TestIntegration(t *testing.T) {
	RegisterFailHandler(Fail)
	BeforeSuite(func() {
		err := bmtestutils.BuildExecutable()
		Expect(err).NotTo(HaveOccurred())

		testCpiFilePath, err = bmtestutils.DownloadTestCpiRelease("")
		Expect(err).NotTo(HaveOccurred())
	})

	var (
		homePath string
		oldHome  string
	)
	BeforeEach(func() {
		oldHome = os.Getenv("HOME")

		var err error
		homePath, err = ioutil.TempDir("", "micro-bosh-cli-integration")
		Expect(err).NotTo(HaveOccurred())
		os.Setenv("HOME", homePath)
	})

	AfterEach(func() {
		os.Setenv("HOME", oldHome)
		os.RemoveAll(homePath)
	})

	AfterSuite(func() {
		os.Remove(testCpiFilePath)
	})

	RunSpecs(t, "bosh-micro-cli Integration Suite")
}

package integration_test

import (
	"io/ioutil"
	"os"
	"testing"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	bmtestutils "github.com/cloudfoundry/bosh-micro-cli/testutils"
)

var testCpiFilePath string

func TestIntegration(t *testing.T) {
	RegisterFailHandler(Fail)
	BeforeSuite(func() {
		err := bmtestutils.BuildExecutable()
		Expect(err).NotTo(HaveOccurred())

		testCpiFilePath, err = bmtestutils.DownloadTestCpiRelease("")
		Expect(err).NotTo(HaveOccurred())
	})

	var (
		homePath string
		oldHome  string
	)
	BeforeEach(func() {
		oldHome = os.Getenv("HOME")

		var err error
		homePath, err = ioutil.TempDir("", "micro-bosh-cli-integration")
		Expect(err).NotTo(HaveOccurred())

		err = os.Setenv("HOME", homePath)
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		err := os.Setenv("HOME", oldHome)
		Expect(err).NotTo(HaveOccurred())

		err = os.RemoveAll(homePath)
		Expect(err).NotTo(HaveOccurred())
	})

	AfterSuite(func() {
		err := os.Remove(testCpiFilePath)
		Expect(err).NotTo(HaveOccurred())
	})

	RunSpecs(t, "bosh-micro-cli Integration Suite")
}

Check for errors for operations in BeforeEach and AfterEach/Suite.


package handlers

import (
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
)

const URLRouteGame = "/game/{id}"

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

type gameHandler struct {
	logger *logrus.Logger
}

func NewGameHandler(logger *logrus.Logger) http.Handler {
	return &gameHandler{
		logger: logger,
	}
}

func (h *gameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.logger.Info("game handler")

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		h.logger.Error(err)
	}

	// TODO: Implement handler.
}

package handlers

import (
	"net/http"

	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
)

const URLRouteGameByID = "/game/{id}"

const MethodGame = http.MethodDelete

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

type gameHandler struct {
	logger *logrus.Logger
}

type ErrGameHandler string

func NewGameHandler(logger *logrus.Logger) http.Handler {
	return &gameHandler{
		logger: logger,
	}
}

func (h *gameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.logger.Info("game handler start")

	vars := mux.Vars(r)
	h.logger.Infoln("vars", vars)

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		h.logger.Error(err)
	}

	// TODO: Implement handler.

	conn.Close()

	h.logger.Info("game handler end")
}

Create debug info for GameHandler


package vegeta

import (
	"bytes"
	"encoding/json"
	"fmt"
)

// Dumper is an interface defining Results dumping.
type Dumper interface {
	Dump(*Result) ([]byte, error)
}

// DumperFunc is an adapter to allow the use of ordinary functions as
// Dumpers. If f is a function with the appropriate signature, DumperFunc(f)
// is a Dumper object that calls f.
type DumperFunc func(*Result) ([]byte, error)

func (f DumperFunc) Dump(r *Result) ([]byte, error) { return f(r) }

// DumpCSV dumps a Result as a CSV record with six columns.
// The columns are: unix timestamp in ns since epoch, http status code,
// request latency in ns, bytes out, bytes in, and lastly the error.
var DumpCSV DumperFunc = func(r *Result) ([]byte, error) {
	var buf bytes.Buffer
	_, err := fmt.Fprintf(&buf, "%d,%d,%d,%d,%d,'%s'\n",
		r.Timestamp.UnixNano(),
		r.Code,
		r.Latency.Nanoseconds(),
		r.BytesOut,
		r.BytesIn,
		r.Error,
	)
	return buf.Bytes(), err
}

// DumpJSON dumps a Result as a JSON object.
var DumpJSON DumperFunc = func(r *Result) ([]byte, error) {
	var buf bytes.Buffer
	err := json.NewEncoder(&buf).Encode(r)
	return buf.Bytes(), err
}

package vegeta

import (
	"bytes"
	"encoding/json"
	"fmt"
)

// Dumper is an interface defining Results dumping.
type Dumper interface {
	Dump(*Result) ([]byte, error)
}

// DumperFunc is an adapter to allow the use of ordinary functions as
// Dumpers. If f is a function with the appropriate signature, DumperFunc(f)
// is a Dumper object that calls f.
type DumperFunc func(*Result) ([]byte, error)

func (f DumperFunc) Dump(r *Result) ([]byte, error) { return f(r) }

// DumpCSV dumps a Result as a CSV record with six columns.
// The columns are: unix timestamp in ns since epoch, http status code,
// request latency in ns, bytes out, bytes in, and lastly the error.
var DumpCSV DumperFunc = func(r *Result) ([]byte, error) {
	var buf bytes.Buffer
	_, err := fmt.Fprintf(&buf, "%d,%d,%d,%d,%d,\"%s\"\n",
		r.Timestamp.UnixNano(),
		r.Code,
		r.Latency.Nanoseconds(),
		r.BytesOut,
		r.BytesIn,
		r.Error,
	)
	return buf.Bytes(), err
}

// DumpJSON dumps a Result as a JSON object.
var DumpJSON DumperFunc = func(r *Result) ([]byte, error) {
	var buf bytes.Buffer
	err := json.NewEncoder(&buf).Encode(r)
	return buf.Bytes(), err
}

Use double quote for error wraping


package main

import (
	"io/ioutil"
	"os"

	slackreporter "github.com/ariarijp/horenso-reporter-slack/reporter"
	"github.com/bluele/slack"
)

func main() {
	token := os.Getenv("SLACK_TOKEN")
	groupName := os.Getenv("SLACK_GROUP")

	stdin, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	api := slack.New(token)
	r := slackreporter.GetReport(stdin)

	slackreporter.NotifyToGroup(*api, r, groupName)
}

package main

import (
	"io/ioutil"
	"os"

	slackreporter "github.com/ariarijp/horenso-reporter-slack/reporter"
	"github.com/bluele/slack"
)

func main() {
	token := os.Getenv("SLACK_TOKEN")
	groupName := os.Getenv("SLACK_GROUP")

	stdin, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	api := slack.New(token)
	r := slackreporter.GetReport(stdin)

	if *r.ExitCode != 0 {
		slackreporter.NotifyToGroup(*api, r, groupName)
	}
}

Change notify when exit code is not 0


package main // import "github.com/CenturyLinkLabs/panamax-kubernetes-adapter"

import (
	"github.com/CenturyLinkLabs/panamax-kubernetes-adapter/adapter"
	"github.com/CenturyLinkLabs/pmxadapter"
)

func main() {
	adapter := adapter.KubernetesAdapter{}
	server := pmxadapter.NewServer(adapter)

	server.Start()
}

package main // import "github.com/CenturyLinkLabs/panamax-kubernetes-adapter-go"

import (
	"github.com/CenturyLinkLabs/panamax-kubernetes-adapter-go/adapter"
	"github.com/CenturyLinkLabs/pmxadapter"
)

func main() {
	adapter := adapter.KubernetesAdapter{}
	server := pmxadapter.NewServer(adapter)

	server.Start()
}

Rename package to reflect its Github repo name.


package main

import (
	"os"

	"github.com/taylorskalyo/stno/action"

	"gopkg.in/urfave/cli.v1"
)

func main() {
	app := cli.NewApp()

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "journal, j",
			Usage: "Load the journal titled `JOURNAL`",
		},
		cli.StringFlag{
			Name:  "config, c",
			Usage: "Load configuration from `FILE`",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:   "add",
			Usage:  "add a journal entry",
			Action: action.Add,
		},
		{
			Name:   "query",
			Usage:  "filter and display journal entries",
			Action: action.Query,
		},
	}

	app.Run(os.Args)
}

package main

import (
	"os"

	"github.com/taylorskalyo/stno/action"

	"gopkg.in/urfave/cli.v1"
)

func main() {
	app := cli.NewApp()

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "journal, j",
			Usage: "load the journal titled `JOURNAL`",
		},
		cli.StringFlag{
			Name:  "config, c",
			Usage: "load configuration from `FILE`",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:   "add",
			Usage:  "Adds a journal entry",
			Action: action.Add,
		},
		{
			Name:   "query",
			Usage:  "Queries journal entries",
			Action: action.Query,
		},
	}

	app.Run(os.Args)
}

Update help text to match default style


package main

import (
	"os"
	"strings"
)

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	results := BeginMatrixTest(matrix)

	OutputResults(results)
}

package main

import (
	"os"
	"strings"
	"time"
)

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	time.Sleep(1 * time.Second)

	results := BeginMatrixTest(matrix)

	OutputResults(results)
}

Add a sleep because distributed systems are hard


package openflow

import "io"

const MinimumHeaderLength = 8

type Packetizable interface {
	io.ReadWriter
	Len() uint
}

type Message interface {
	Packetizable
	Header() *Header
}

type Header struct {
	Version uint8
	Type    MessageType
	Length  uint16
	Xid     uint32
}

func (h *Header) GetHeader() *Header {
	return h
}

func NewXidGenerator() func() uint32 {
	var xid uint32 = 0
	return func() uint32 {
		xid += 1
		return xid
	}
}

type MessageType uint8

package openflow

import "io"

const MinimumHeaderLength = 8

type Packetizable interface {
	io.ReadWriter
	Len() uint
}

type Message interface {
	Packetizable
	GetHeader() *Header
}

type Header struct {
	Version uint8
	Type    MessageType
	Length  uint16
	Xid     uint32
}

func (h *Header) GetHeader() *Header {
	return h
}

func NewXidGenerator() func() uint32 {
	var xid uint32 = 0
	return func() uint32 {
		xid += 1
		return xid
	}
}

type MessageType uint8

Apply Message interface protocol to Header struct


package tests

import (
	"net/url"

	"github.com/revel/revel/samples/upload/app/routes"

	"github.com/revel/revel"
)

type MultipleTest struct {
	revel.TestSuite
}

func (t *MultipleTest) TestThatMultipleFilesUploadWorks() {
	// Make sure it is not allowed to submit less than 2 files.
	t.PostFile(routes.Multiple.HandleUpload(), url.Values{}, url.Values{
		"file": {
			"github.com/revel/revel/samples/upload/public/img/favicon.png",
		},
	})
	t.AssertOk()
	t.AssertContains("You cannot submit less than 2 files")

	// Make sure upload of 2 files works.
	t.PostFile(routes.Multiple.HandleUpload(), url.Values{}, url.Values{
		"file[]": {
			"github.com/revel/revel/samples/upload/public/img/favicon.png",
			"github.com/revel/revel/samples/upload/public/img/glyphicons-halflings.png",
		},
	})
	revel.WARN.Println(string(t.ResponseBody))
	t.AssertOk()
	t.AssertContains("Successfully uploaded")
	t.AssertContains("favicon.png")
	t.AssertContains("glyphicons-halflings.png")
	t.AssertContains("image/png")
}

package tests

import (
	"net/url"

	"github.com/revel/revel/samples/upload/app/routes"

	"github.com/revel/revel"
)

type MultipleTest struct {
	revel.TestSuite
}

func (t *MultipleTest) TestThatMultipleFilesUploadWorks() {
	// Make sure it is not allowed to submit less than 2 files.
	t.PostFile(routes.Multiple.HandleUpload(), url.Values{}, url.Values{
		"file": {
			"github.com/revel/revel/samples/upload/public/img/favicon.png",
		},
	})
	t.AssertOk()
	t.AssertContains("You cannot submit less than 2 files")

	// Make sure upload of 2 files works.
	t.PostFile(routes.Multiple.HandleUpload(), url.Values{}, url.Values{
		"file[]": {
			"github.com/revel/revel/samples/upload/public/img/favicon.png",
			"github.com/revel/revel/samples/upload/public/img/glyphicons-halflings.png",
		},
	})
	t.AssertOk()
	t.AssertContains("Successfully uploaded")
	t.AssertContains("favicon.png")
	t.AssertContains("glyphicons-halflings.png")
	t.AssertContains("image/png")
}

Remove debug info from upload tests sample


package model

// Accounts is used to unmarshal the /me/accounts response
//
// https://developers.facebook.com/docs/graph-api/reference/v2.3/user/accounts#fields
type Accounts struct {
	Data []Page `json:"data"`
}

// Page represents a Facebook Page
//
// https://developers.facebook.com/docs/graph-api/reference/v2.3/page#readfields
type Page struct {
	ID          string   `json:"id"`
	Name        string   `json:"name"`
	Location    Location `json:"location,omitempty"`
	Phone       string   `json:"phone,omitempty"`
	Website     string   `json:"website,omitempty"`
	AccessToken string   `json:"access_token,omitempty"`
}

// Location holds the location information for a Facebook object, including the address
// and the geographical location.
//
// https://developers.facebook.com/docs/graph-api/reference/location/
type Location struct {
	Street  string `json:"street"`
	City    string `json:"city"`
	Country string `json:"country"`
}

package model

// Accounts is used to unmarshal the /me/accounts response
//
// https://developers.facebook.com/docs/graph-api/reference/v2.3/user/accounts#fields
type Accounts struct {
	Data []Page `json:"data"`
}

// Page represents a Facebook Page
//
// https://developers.facebook.com/docs/graph-api/reference/v2.3/page#readfields
type Page struct {
	ID          string   `json:"id"`
	Name        string   `json:"name"`
	Location    Location `json:"location,omitempty"`
	Phone       string   `json:"phone,omitempty"`
	Website     string   `json:"website,omitempty"`
	Emails      []string `json:"emails,omitempty"`
	AccessToken string   `json:"access_token,omitempty"`
}

// Location holds the location information for a Facebook object, including the address
// and the geographical location.
//
// https://developers.facebook.com/docs/graph-api/reference/location/
type Location struct {
	Street  string `json:"street"`
	City    string `json:"city"`
	Country string `json:"country"`
}

Add emails to Page model


package libgodelbrot

import (
	"image"
)

// Draw the Mandelbrot set.  This is the main entry point to libgodelbrot
func AutoRender(req *Request) (*image.NRGBA, error) {
	info, configErr := AutoConf(req)

	if configErr == nil {
		return Render(info)
	} else {
		return nil, configErr
	}
}

func Render(info *Info) (*image.NRGBA, error) {
	context, err := MakeRenderer(info)

	if err == nil {
		return context.Render()
	} else {
		return nil, err
	}
}

func AutoConf(req *Request) (*Info, error) {
	// Configure uses panic when it encounters an error condition.
	// Here we detect that panic and convert it to an error,
	// which is idiomatic for the API.
	anything, err := panic2err(func() interface{} {
		return configure(req)
	})

    if err == nil {
        return anything.(*Info), nil
    } else {
        return nil, err
    }
}

func MakeRenderer(desc *Info) (Renderer,  error) {
	// Renderer is a thin wrapper, we just pass on to the library internals
	return renderer(desc)
}

package libgodelbrot

import (
	"image"
)

func Render(info *Info) (*image.NRGBA, error) {
	context, err := MakeRenderer(info)

	if err == nil {
		return context.Render()
	} else {
		return nil, err
	}
}

func AutoConf(req *Request) (*Info, error) {
	// Configure uses panic when it encounters an error condition.
	// Here we detect that panic and convert it to an error,
	// which is idiomatic for the API.
	anything, err := panic2err(func() interface{} {
		return configure(req)
	})

    if err == nil {
        return anything.(*Info), nil
    } else {
        return nil, err
    }
}

func MakeRenderer(desc *Info) (Renderer,  error) {
	// Renderer is a thin wrapper, we just pass on to the library internals
	return renderer(desc)
}

Remove non-orthogonal helper method from API


package main

import (
	"testing"
)

func TestParseMaintainer(t *testing.T) {
	cases := []struct {
		in   []byte
		want *Maintainer
	}{
		{[]byte("JohnDoe"), &Maintainer{Name: "JohnDoe"}},
		{[]byte("John Doe"), &Maintainer{Name: "John Doe"}},
		{[]byte(" John Doe"), &Maintainer{Name: "John Doe"}},
		{[]byte("John Doe "), &Maintainer{Name: "John Doe"}},
	}
	for _, c := range cases {
		got, _ := ParseMaintainer(c.in)
		if got.Name != c.want.Name {
			t.Errorf(
				"ParseMaintainer(%q).Name == %q, want %q",
				c.in,
				got.Name,
				c.want.Name,
			)
		}
	}
}

func TestParseUser(t *testing.T) {
	cases := []struct {
		in   []byte
		want *User
	}{
		{[]byte("root"), &User{Name: "root"}},
		{[]byte(" root"), &User{Name: "root"}},
		{[]byte("root "), &User{Name: "root"}},
	}
	for _, c := range cases {
		got, _ := ParseUser(c.in)
		if got.Name != c.want.Name {
			t.Errorf(
				"ParseUser(%q).Name == %q, want %q",
				c.in,
				got.Name,
				c.want.Name,
			)
		}
	}
}

Add tests for USER parsing


// Copyright (c) 2016-2017 Eric Barkie. All rights reserved.
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.

package main

import (
	"fmt"
	"time"
)

func Examplemetar() {
	l := loop{Timestamp: time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)}
	fmt.Println(metar(l))

	// Output:
	// METAR 021504Z AUTO 00000KT M18/M18 A0000 RMK AO1 SLP000 T11781178
}

// Copyright (c) 2016-2017 Eric Barkie. All rights reserved.
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.

package main

import (
	"fmt"
	"time"
)

func ExampleMetar() {
	l := loop{Timestamp: time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)}
	fmt.Println(metar(l))

	// Output:
	// METAR 021504Z AUTO 00000KT M18/M18 A0000 RMK AO1 SLP000 T11781178
}

Make metar example actually run


package gamq

import (
	"testing"
)

const (
	TEST_QUEUE_NAME = "TestQueue"
)

func TestQueue_initialize_completesSuccessfully(t *testing.T) {
	underTest := Queue{Name: TEST_QUEUE_NAME}

	underTest.Initialize()

	// Queue should be named correctly
	if underTest.Name != TEST_QUEUE_NAME {
		t.Fail()
	}

	// Messages channel should be initialized
	if underTest.Messages == nil {
		t.Fail()
	}

	// Subscribers channel should be initialized
	if underTest.Subscribers == nil {
		t.Fail()
	}
}

package gamq

import (
	"bufio"
	"bytes"
	"testing"

	"github.com/onsi/gomega"
)

const (
	TEST_QUEUE_NAME = "TestQueue"
)

// Check that messages sent to a queue are eventually sent to consumers
func TestQueue_sendMessage_messageReceivedSuccessfully(t *testing.T) {
	// Need gomega for async testing
	gomega.RegisterTestingT(t)

	underTest := Queue{Name: TEST_QUEUE_NAME}
	testMessage := "Testing!"

	underTest.Initialize()

	writerBuffer := new(bytes.Buffer)
	dummyWriter := bufio.NewWriter(writerBuffer)
	dummyClient := Client{Name: "Test", Writer: dummyWriter}

	// Add the subscription
	underTest.Subscribers <- &dummyClient

	// Queue the message
	underTest.Messages <- &testMessage

	gomega.Eventually(func() string {
		return writerBuffer.String()
	}).Should(gomega.Equal(testMessage))
}

func TestQueue_initialize_completesSuccessfully(t *testing.T) {
	underTest := Queue{Name: TEST_QUEUE_NAME}

	underTest.Initialize()

	// Queue should be named correctly
	if underTest.Name != TEST_QUEUE_NAME {
		t.Fail()
	}

	// Messages channel should be initialized
	if underTest.Messages == nil {
		t.Fail()
	}

	// Subscribers channel should be initialized
	if underTest.Subscribers == nil {
		t.Fail()
	}
}

Add async test for queues.


package main

import (
	"os"

	"github.com/cloudfoundry-community/gcp-tools-release/src/stackdriver-nozzle/firehose"
	"github.com/cloudfoundry-community/go-cfclient"
	"github.com/cloudfoundry/sonde-go/events"
	"gopkg.in/alecthomas/kingpin.v2"
)

func main() {
	kingpin.Parse()

	apiEndpoint := os.Getenv("FIREHOSE_ENDPOINT")
	username := os.Getenv("FIREHOSE_USERNAME")
	password := os.Getenv("FIREHOSE_PASSWORD")
	_, skipSSLValidation := os.LookupEnv("FIREHOSE_SKIP_SSL")

	cfConfig := &cfclient.Config{
		ApiAddress:        apiEndpoint,
		Username:          username,
		Password:          password,
		SkipSslValidation: skipSSLValidation}

	cfClient := cfclient.NewClient(cfConfig)

	client := firehose.NewClient(cfConfig, cfClient, nil)

	err := client.StartListening(&StdOut{})
	if err != nil {
		panic(err)
	}
}

type StdOut struct{}

func (so *StdOut) HandleEvent(envelope *events.Envelope) error {
	println(envelope.String())
	return nil
}

package main

import (
	"os"

	"github.com/cloudfoundry-community/gcp-tools-release/src/stackdriver-nozzle/firehose"
	"github.com/cloudfoundry-community/go-cfclient"
	"github.com/cloudfoundry/sonde-go/events"
)

func main() {
	apiEndpoint := os.Getenv("FIREHOSE_ENDPOINT")
	username := os.Getenv("FIREHOSE_USERNAME")
	password := os.Getenv("FIREHOSE_PASSWORD")
	_, skipSSLValidation := os.LookupEnv("FIREHOSE_SKIP_SSL")

	cfConfig := &cfclient.Config{
		ApiAddress:        apiEndpoint,
		Username:          username,
		Password:          password,
		SkipSslValidation: skipSSLValidation}

	cfClient := cfclient.NewClient(cfConfig)

	client := firehose.NewClient(cfConfig, cfClient, nil)

	err := client.StartListening(&StdOut{})
	if err != nil {
		panic(err)
	}
}

type StdOut struct{}

func (so *StdOut) HandleEvent(envelope *events.Envelope) error {
	println(envelope.String())
	return nil
}

Remove last vestiges of kingpin


package hpack

import (
	"github.com/summerwind/h2spec/config"
	"github.com/summerwind/h2spec/spec"
	"golang.org/x/net/http2"
)

func IndexAddressSpace() *spec.TestGroup {
	tg := NewTestGroup("2.3.3", "Index Address Space")

	// Indices strictly greater than the sum of the lengths of both
	// tables MUST be treated as a decoding error.
	tg.AddTestCase(&spec.TestCase{
		Desc:        "Sends a header field representation with invalid index",
		Requirement: "The endpoint MUST treat this as a decoding error.",
		Run: func(c *config.Config, conn *spec.Conn) error {
			var streamID uint32 = 1

			err := conn.Handshake()
			if err != nil {
				return err
			}

			// Indexed header field representation with index 126
			indexedRep := []byte("\xFE")

			headers := spec.CommonHeaders(c)
			blockFragment := conn.EncodeHeaders(headers)
			blockFragment = append(blockFragment, indexedRep...)

			hp := http2.HeadersFrameParam{
				StreamID:      streamID,
				EndStream:     true,
				EndHeaders:    true,
				BlockFragment: blockFragment,
			}
			conn.WriteHeaders(hp)

			return spec.VerifyConnectionError(conn, http2.ErrCodeCompression)
		},
	})

	return tg
}

package hpack

import (
	"github.com/summerwind/h2spec/config"
	"github.com/summerwind/h2spec/spec"
	"golang.org/x/net/http2"
)

func IndexAddressSpace() *spec.TestGroup {
	tg := NewTestGroup("2.3.3", "Index Address Space")

	// Indices strictly greater than the sum of the lengths of both
	// tables MUST be treated as a decoding error.
	tg.AddTestCase(&spec.TestCase{
		Desc:        "Sends a header field representation with invalid index",
		Requirement: "The endpoint MUST treat this as a decoding error.",
		Run: func(c *config.Config, conn *spec.Conn) error {
			var streamID uint32 = 1

			err := conn.Handshake()
			if err != nil {
				return err
			}

			// Indexed header field representation with index 70
			indexedRep := []byte("\xC6")

			headers := spec.CommonHeaders(c)
			blockFragment := conn.EncodeHeaders(headers)
			blockFragment = append(blockFragment, indexedRep...)

			hp := http2.HeadersFrameParam{
				StreamID:      streamID,
				EndStream:     true,
				EndHeaders:    true,
				BlockFragment: blockFragment,
			}
			conn.WriteHeaders(hp)

			return spec.VerifyConnectionError(conn, http2.ErrCodeCompression)
		},
	})

	return tg
}

Use index 126 instead of 70


package mint

import "testing"

// Because is context printer.
func Because(t *testing.T, context string, wrapper func(*testing.T)) {
	Log("  Because:", context, "\n")
	wrapper(t)
}

// When is an alternative of `Because`
func When(t *testing.T, context string, wrapper func(*testing.T)) {
	Log("  When:", context, "\n")
	wrapper(t)
}

package mint

import "testing"

// Because is context printer.
func Because(t *testing.T, context string, wrapper func(*testing.T)) {
	Log("  Because ", context, "\n")
	wrapper(t)
}

// When is an alternative of `Because`
func When(t *testing.T, context string, wrapper func(*testing.T)) {
	Log("  When ", context, "\n")
	wrapper(t)
}

Change context message output a bit


package config

import "go.skia.org/infra/go/buildskia"

const (
	// BUILD_TYPE is the type of build we use throughout fiddle.
	BUILD_TYPE = buildskia.RELEASE_BUILD
)

var (
	// GN_FLAGS are the flags to pass to GN.
	GN_FLAGS = []string{"is_debug=false", "skia_use_egl=true", "extra_cflags_cc=[\"-Wno-error\"]"}

	// EGL_LIB_PATH is the path where the correct libEGL.so can be found.
	EGL_LIB_PATH = "/usr/lib/nvidia-367/"
)

package config

import "go.skia.org/infra/go/buildskia"

const (
	// BUILD_TYPE is the type of build we use throughout fiddle.
	BUILD_TYPE = buildskia.RELEASE_BUILD
)

var (
	// GN_FLAGS are the flags to pass to GN.
	GN_FLAGS = []string{"is_debug=false", "skia_use_egl=true", "extra_cflags_cc=[\"-Wno-error\" \"-DEGL_NO_IMAGE_EXTERNAL=1\"]"}

	// EGL_LIB_PATH is the path where the correct libEGL.so can be found.
	EGL_LIB_PATH = "/usr/lib/nvidia-367/"
)

Add flag to work around the GL calls in CreatePlatformGLTestContext_egl.cpp.


package main

const dockerUnitTemplate = `
[Unit]
Description={{.Name}}
After=docker.service

[Service]
EnvironmentFile=/etc/environment
User=core
TimeoutStartSec=0
ExecStartPre=/usr/bin/docker pull mmmhm/{{.Name}}:{{.Version}}
ExecStartPre=-/usr/bin/docker rm -f {{.Name}}-{{.Version}}-%i
ExecStart=/usr/bin/docker run --name {{.Name}}-{{.Version}}-%i -p 3000 {{.DockerHubUsername}}/{{.Name}}:{{.Version}}
ExecStartPost=/bin/sh -c "sleep 15; /usr/bin/etcdctl set /vulcand/upstreams/{{.Name}}/endpoints/{{.Name}}-{{.Version}}-%i http://$COREOS_PRIVATE_IPV4:$(echo $(/usr/bin/docker port {{.Name}}-{{.Version}}-%i 3000) | cut -d ':' -f 2)"
ExecStop=/bin/sh -c "/usr/bin/etcdctl rm '/vulcand/upstreams/{{.Name}}/endpoints/{{.Name}}-{{.Version}}-%i' ; /usr/bin/docker rm -f {{.Name}}-{{.Version}}-%i"
`

package main

const dockerUnitTemplate = `
[Unit]
Description={{.Name}}
After=docker.service

[Service]
EnvironmentFile=/etc/environment
User=core
TimeoutStartSec=0
ExecStartPre=/usr/bin/docker pull {{.DockerHubUsername}}/{{.Name}}:{{.Version}}
ExecStartPre=-/usr/bin/docker rm -f {{.Name}}-{{.Version}}-%i
ExecStart=/usr/bin/docker run --name {{.Name}}-{{.Version}}-%i -p 3000 {{.DockerHubUsername}}/{{.Name}}:{{.Version}}
ExecStartPost=/bin/sh -c "sleep 15; /usr/bin/etcdctl set /vulcand/upstreams/{{.Name}}/endpoints/{{.Name}}-{{.Version}}-%i http://$COREOS_PRIVATE_IPV4:$(echo $(/usr/bin/docker port {{.Name}}-{{.Version}}-%i 3000) | cut -d ':' -f 2)"
ExecStop=/bin/sh -c "/usr/bin/etcdctl rm '/vulcand/upstreams/{{.Name}}/endpoints/{{.Name}}-{{.Version}}-%i' ; /usr/bin/docker rm -f {{.Name}}-{{.Version}}-%i"
`

Fix bug with un-renamed Docker Hub username.


package thrift_nats

import (
	"errors"
	"time"

	"git.apache.org/thrift.git/lib/go/thrift"
	"github.com/nats-io/nats"
)

type natsServerTransport struct {
	conn      *nats.Conn
	accepted  chan struct{}
	transport thrift.TTransport
	listening bool
}

func newNATSServerTransport(conn *nats.Conn) *natsServerTransport {
	return &natsServerTransport{conn: conn}
}

func (n *natsServerTransport) Listen() error {
	n.listening = true
	return nil
}

func (n *natsServerTransport) Accept() (thrift.TTransport, error) {
	return nil, errors.New("Use AcceptNATS")
}

func (n *natsServerTransport) AcceptNATS(listenTo, replyTo string,
	timeout time.Duration) thrift.TTransport {

	return NewNATSTransport(n.conn, listenTo, replyTo, timeout)
}

func (n *natsServerTransport) IsListening() bool {
	return n.listening
}

func (n *natsServerTransport) Close() error {
	return nil
}

func (n *natsServerTransport) Interrupt() error {
	return nil
}

package thrift_nats

import (
	"errors"
	"time"

	"git.apache.org/thrift.git/lib/go/thrift"
	"github.com/nats-io/nats"
)

type natsServerTransport struct {
	conn      *nats.Conn
	listening bool
}

func newNATSServerTransport(conn *nats.Conn) *natsServerTransport {
	return &natsServerTransport{conn: conn}
}

func (n *natsServerTransport) Listen() error {
	n.listening = true
	return nil
}

func (n *natsServerTransport) Accept() (thrift.TTransport, error) {
	return nil, errors.New("Use AcceptNATS")
}

func (n *natsServerTransport) AcceptNATS(listenTo, replyTo string,
	timeout time.Duration) thrift.TTransport {

	return NewNATSTransport(n.conn, listenTo, replyTo, timeout)
}

func (n *natsServerTransport) IsListening() bool {
	return n.listening
}

func (n *natsServerTransport) Close() error {
	n.listening = false
	return nil
}

func (n *natsServerTransport) Interrupt() error {
	return nil
}

Remove unused fields from server transport


package blockstoragecommands

import (
	"github.com/jrperritt/rack/commands/blockstoragecommands/snapshotcommands"
	"github.com/jrperritt/rack/commands/blockstoragecommands/volumecommands"
	"github.com/jrperritt/rack/internal/github.com/codegangsta/cli"
)

// Get returns all the commands allowed for a `block-storage` request.
func Get() []cli.Command {
	return []cli.Command{
		{
			Name:        "snapshot",
			Usage:       "Copies of block storage volumes at a specific moment in time. Used for backup, restoration, and other long term storage.",
			Subcommands: snapshotcommands.Get(),
		},
		{
			Name:        "volume",
			Usage:       "Block level volumes to expand storage on your servers.",
			Subcommands: volumecommands.Get(),
		},
	}
}

package blockstoragecommands

import (
	"github.com/jrperritt/rack/commands/blockstoragecommands/snapshotcommands"
	"github.com/jrperritt/rack/commands/blockstoragecommands/volumecommands"
	"github.com/jrperritt/rack/internal/github.com/codegangsta/cli"
)

// Get returns all the commands allowed for a `block-storage` request.
func Get() []cli.Command {
	return []cli.Command{
		{
			Name:        "snapshot",
			Usage:       "Copies of block storage volumes at a specific moment in time. Used for backup, restoration, and other long term storage.",
			Subcommands: snapshotcommands.Get(),
		},
		{
			Name:        "volume",
			Usage:       "Block level volumes to add storage capacity to your servers.",
			Subcommands: volumecommands.Get(),
		},
	}
}

Clarify meaning of block storage volumes.


package utils

import "time"

var (
	Interval = 10 * time.Second
	Timeout  = 5 * time.Minute
)

package utils

import "time"

var (
	Interval = 10 * time.Second
	Timeout  = 10 * time.Minute
)

Increase e2e poll timeout to 10min


package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"time"

	"github.com/eferro/go-snmpqueries/pkg/snmpquery"
)

func generateRandomQueries() <-chan snmpquery.Query {
	out := make(chan snmpquery.Query)
	go func() {
		queryId := 0
		for {
			query := snmpquery.Query{
				Id:          queryId,
				Query:       "Fake query " + strconv.Itoa(queryId),
				Destination: "Fake destination " + strconv.Itoa(queryId),
			}
			out <- query
			queryId += 1
			time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
		}
	}()
	return out
}

func main() {

	input := generateRandomQueries()

	processed := make(chan snmpquery.Query)
	go func() {
		for query := range input {
			snmpquery.HandleQuery(&query)
			processed <- query
		}
	}()

	for query := range processed {
		fmt.Println(query.Query, query.Response)
	}
}

package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"time"

	"github.com/eferro/go-snmpqueries/pkg/snmpquery"
)

func generateRandomQueries(input chan snmpquery.Query) {
	queryId := 0
	for {
		query := snmpquery.Query{
			Id:          queryId,
			Query:       "Fake query " + strconv.Itoa(queryId),
			Destination: "Fake destination " + strconv.Itoa(queryId),
		}
		input <- query
		queryId += 1
		time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
	}
}

func processQueries(input chan snmpquery.Query, processed chan snmpquery.Query) {
	for query := range input {
		snmpquery.HandleQuery(&query)
		processed <- query
	}
}

func printResults(processed chan snmpquery.Query) {
	for query := range processed {
		fmt.Println(query.Query, query.Response)
	}
}

func main() {
	input := make(chan snmpquery.Query)
	processed := make(chan snmpquery.Query)

	go generateRandomQueries(input)
	go processQueries(input, processed)

	printResults(processed)
}

Refactor (to clarify the flow)


package main

import (
	"fmt"
	"log"

	"github.com/jessevdk/go-flags"
	"github.com/k0kubun/go-readline"
)

type Options struct {
	ScreenName string `short:"a" long:"account" description:"login as an account of selected screen_name"`
}

func main() {
	account := loadAccount()

	startUserStream(account)
	invokeInteractiveShell(account)
}

func loadAccount() *Account {
	options := new(Options)
	if _, err := flags.Parse(options); err != nil {
		log.Fatal(err)
	}

	if len(options.ScreenName) > 0 {
		return AccountByScreenName(options.ScreenName)
	} else {
		return DefaultAccount()
	}
}

func invokeInteractiveShell(account *Account) {
	readline.CatchSignals(0)

	for {
		currentLine := readline.Readline(prompt(account))
		if currentLine == nil || *currentLine == ":exit" {
			return
		}

		err := executeCommand(account, *currentLine)
		if err != nil {
			fmt.Print(err.Error())
		}
		readline.AddHistory(*currentLine)
	}
}

func prompt(account *Account) *string {
	prompt := fmt.Sprintf("[%s] ", coloredScreenName(account.ScreenName))
	return &prompt
}

package main

import (
	"fmt"
	"log"

	"github.com/jessevdk/go-flags"
	"github.com/k0kubun/go-readline"
)

type Options struct {
	ScreenName string `short:"a" long:"account" description:"login as an account of selected screen_name"`
}

func main() {
	options := new(Options)
	if _, err := flags.Parse(options); err != nil {
		log.Fatal(err)
	}

	account := loadAccount(options)

	startUserStream(account)
	invokeInteractiveShell(account)
}

func loadAccount(options *Options) *Account {
	if len(options.ScreenName) > 0 {
		return AccountByScreenName(options.ScreenName)
	} else {
		return DefaultAccount()
	}
}

func invokeInteractiveShell(account *Account) {
	readline.CatchSignals(0)

	for {
		currentLine := readline.Readline(prompt(account))
		if currentLine == nil || *currentLine == ":exit" {
			return
		}

		err := executeCommand(account, *currentLine)
		if err != nil {
			fmt.Print(err.Error())
		}
		readline.AddHistory(*currentLine)
	}
}

func prompt(account *Account) *string {
	prompt := fmt.Sprintf("[%s] ", coloredScreenName(account.ScreenName))
	return &prompt
}

Move option parsing outside of loadAccount


package flagutil

import (
	"strings"
)

func (sl *StringList) String() string {
	return `"` + strings.Join(*sl, ",") + `"`
}

func (sl *StringList) Set(value string) error {
	*sl = strings.Split(value, ",")
	return nil
}

package flagutil

import (
	"strings"
)

func (sl *StringList) String() string {
	return `"` + strings.Join(*sl, ",") + `"`
}

func (sl *StringList) Set(value string) error {
	if value == "" {
		*sl = make(StringList, 0)
	} else {
		*sl = strings.Split(value, ",")
	}
	return nil
}

Fix bug handling empty string in lib/flagutil.StringList.Set().


package sys

import (
	"syscall"
)

func fileOwner(v interface{}) (uid, gid, muid string) {
	uid = DefaultUid
	gid = DefaultGid
	//muid = DefaultMuid
	muid = ""

	stat, ok := v.(*syscall.Dir)
	if !ok {
		return
	}

	// This is pretty easy, it's almost like this OS
	// was made for 9P :D
	return stat.Uid, stat.Gid, stat.Muid
}

package sys

import (
	"syscall"
)

func fileOwner(v interface{}) (uid, gid, muid string) {
	uid = DefaultUid
	gid = DefaultGid
	muid = DefaultMuid

	stat, ok := v.(*syscall.Dir)
	if !ok {
		return
	}

	// This is pretty easy, it's almost like this OS
	// was made for 9P :D
	return stat.Uid, stat.Gid, stat.Muid
}

Use the default value we set in the main owner.go


package sessmgr

import (
	"sync"
	"time"
)

type Session struct {
	id   string
	Last time.Time
	mu   sync.RWMutex
	Val  map[string]interface{}
	prov Provider
}

func NewSession(id string, provider Provider) *Session {
	v := make(map[string]interface{}, 0)
	return &Session{
		id:   id,
		Last: time.Now(),
		Val:  v, prov: provider,
	}
}

func (s *Session) Set(key string, val interface{}) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	s.Val[key] = val
	s.prov.Update(s.id)

	return nil
}

func (s *Session) Get(key string) interface{} {
	s.mu.RLock()
	defer s.mu.RUnlock()

	// TODO: ? deal with bool
	v, _ := s.Val[key]
	s.prov.Update(s.id)

	return v
}

func (s *Session) Unset(key string) {
	s.mu.Lock()
	defer s.mu.Unlock()

	delete(s.Val, key)
	s.prov.Update(s.id)
}

func (s *Session) ID() string {
	return s.id
}

package sessmgr

import (
	"sync"
	"time"
)

type Session struct {
	id   string
	Last time.Time
	mu   sync.RWMutex
	Val  map[string]interface{}
	prov Provider
}

func NewSession(id string, provider Provider) *Session {
	v := make(map[string]interface{})
	return &Session{
		id:   id,
		Last: time.Now(),
		Val:  v, prov: provider,
	}
}

func (s *Session) Set(key string, val interface{}) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	s.Val[key] = val
	s.prov.Update(s.id)

	return nil
}

func (s *Session) Get(key string) interface{} {
	s.mu.RLock()
	defer s.mu.RUnlock()

	// TODO: ? deal with bool
	v, _ := s.Val[key]
	s.prov.Update(s.id)

	return v
}

func (s *Session) Unset(key string) {
	s.mu.Lock()
	defer s.mu.Unlock()

	delete(s.Val, key)
	s.prov.Update(s.id)
}

func (s *Session) ID() string {
	return s.id
}

Remove cap from map def.


package interfaces

import (
	pickle "github.com/hydrogen18/stalecucumber"
	"github.com/pkg/errors"
)

type SDK struct {
	Name     string   `json:"name" pickle:"name"`
	Version  string   `json:"version" pickle:"version"`
	ClientIP string   `json:"clientIP" pickle:"client_ip"`
	Upstream Upstream `json:"upstream" pickle:"-"`
}

type Upstream struct {
	Name    string `json:"name" pickle:"-"`
	URL     string `json:"url" pickle:"-"`
	IsNewer bool   `json:"isNewer"`
}

func (sdk *SDK) UnmarshalRecord(nodeBlob interface{}) error {
	// TODO safe cast to map[interface{}]interface{}
	// TODO safe get from map using `sdk` alias key
	// TODO safe get from map using `sentry.interfaces.Sdk` canonical key
	if err := pickle.UnpackInto(&sdk).From(nodeBlob.(map[interface{}]interface{})["sdk"], nil); err != nil {
		return errors.Wrapf(err, "can not convert node blob to sentry.interfaces.Sdk")
	}
	sdk.Upstream.Name = sdk.Name                                // TODO check original code
	sdk.Upstream.URL = "https://docs.sentry.io/clients/python/" // TODO remove hardcode
	return nil
}

func (sdk *SDK) UnmarshalAPI(rawEvent map[string]interface{}) error {
	return nil
}

package interfaces

type SDK struct {
	Name     string   `json:"name" node:"name"`
	Version  string   `json:"version" node:"version"`
	ClientIP string   `json:"clientIP" node:"client_ip"`
	Upstream Upstream `json:"upstream"`
}

type Upstream struct {
	Name    string `json:"name"`
	URL     string `json:"url"`
	IsNewer bool   `json:"isNewer"`
}

func (sdk *SDK) UnmarshalRecord(nodeBlob interface{}) error {
	err := DecodeRecord("sdk", "sentry.interfaces.Sdk", nodeBlob, sdk)
	sdk.Upstream.Name = sdk.Name                                // TODO check original code
	sdk.Upstream.URL = "https://docs.sentry.io/clients/python/" // TODO remove hardcode
	return err
}

func (sdk *SDK) UnmarshalAPI(rawEvent map[string]interface{}) error {
	return nil
}

Switch SDK from pickle mapper to mapstructure


package remotedialer

import (
	"io"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

type wsConn struct {
	sync.Mutex
	conn *websocket.Conn
}

func newWSConn(conn *websocket.Conn) *wsConn {
	w := &wsConn{
		conn: conn,
	}
	w.setupDeadline()
	return w
}

func (w *wsConn) WriteMessage(messageType int, data []byte) error {
	w.Lock()
	defer w.Unlock()
	return w.conn.WriteMessage(messageType, data)
}

func (w *wsConn) NextReader() (int, io.Reader, error) {
	return w.conn.NextReader()
}

func (w *wsConn) setupDeadline() {
	w.conn.SetReadDeadline(time.Now().Add(PingWaitDuration))
	w.conn.SetPingHandler(func(string) error {
		w.Lock()
		w.conn.WriteControl(websocket.PongMessage, []byte(""), time.Now().Add(time.Second))
		w.Unlock()
		return w.conn.SetReadDeadline(time.Now().Add(PingWaitDuration))
	})
	w.conn.SetPongHandler(func(string) error {
		return w.conn.SetReadDeadline(time.Now().Add(PingWaitDuration))
	})

}

package remotedialer

import (
	"io"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

type wsConn struct {
	sync.Mutex
	conn *websocket.Conn
}

func newWSConn(conn *websocket.Conn) *wsConn {
	w := &wsConn{
		conn: conn,
	}
	w.setupDeadline()
	return w
}

func (w *wsConn) WriteMessage(messageType int, data []byte) error {
	w.Lock()
	defer w.Unlock()
	w.conn.SetWriteDeadline(time.Now().Add(PingWaitDuration))
	return w.conn.WriteMessage(messageType, data)
}

func (w *wsConn) NextReader() (int, io.Reader, error) {
	return w.conn.NextReader()
}

func (w *wsConn) setupDeadline() {
	w.conn.SetReadDeadline(time.Now().Add(PingWaitDuration))
	w.conn.SetPingHandler(func(string) error {
		w.Lock()
		w.conn.WriteControl(websocket.PongMessage, []byte(""), time.Now().Add(time.Second))
		w.Unlock()
		return w.conn.SetReadDeadline(time.Now().Add(PingWaitDuration))
	})
	w.conn.SetPongHandler(func(string) error {
		return w.conn.SetReadDeadline(time.Now().Add(PingWaitDuration))
	})

}

Set write deadline in client/agent connections


package rfc3797

import (
	"math"
)

func main() {

}

func Entropy(n int, p int) float64 {
	i := 0
	result := 0.0

	if (n < 1) || (n >= p) {
		return 0.0
	}

	for i = p; i > (p - n); i-- {
		result += math.Log(float64(i))
	}

	for i = n; i > 1; i-- {
		result -= math.Log(float64(i))
	}

	result /= 0.69315

	return result
}

package rfc3797

import (
	"math"
)

func main() {

}

func Entropy(n int, p int) float64 {
	i := 0
	result := 0.0

	// These cases represent invalid input values.
	if (n < 1) || (n >= p) {
		return 0.0
	}

	for i = p; i > (p - n); i-- {
		result += math.Log(float64(i))
	}

	for i = n; i > 1; i-- {
		result -= math.Log(float64(i))
	}

	// Convert to the number of bits required.
	result /= math.Log(float64(2))

	return result
}

Use actual value of log_e(2) rather than five digit approximation.


package unittest

import (
    "testing"
)

type Any interface{}

func Failure(t *testing.T, x, y Any, mid string) {
    t.Fail()
    t.Log(x, mid, y)
}

func CheckEqual(t *testing.T, x, y Any) {
    if x != y {
        Failure(t, x, y, "!=")
    }
}

func CheckNotEqual(t *testing.T, x, y Any) {
    if x == y {
        Failure(t, x, y, "==")
    }
}

package unittest

import (
    "testing"
)

type Any interface{}

func Failure(t *testing.T, msg ...Any) {
    t.Fail()
    t.Log(msg)
}

func CheckEqual(t *testing.T, x, y Any) {
    if x != y {
        Failure(t, x, y, "!=")
    }
}

func CheckNotEqual(t *testing.T, x, y Any) {
    if x == y {
        Failure(t, x, y, "==")
    }
}

func Check(t *testing.T, x Any) {
    if x == false {
        Failure(t, x, "== false")
    }
}

func CheckFalse(t *testing.T, x Any) {
    if x == true {
        Failure(t, x, "== true")
    }
}

Add Check, CheckFalse, and tweak Failure message


package far

import (
	"bufio"
	"os"
	"strings"
)

func FileExists(path string) bool {
	_, err := os.Stat(path)

	if err != nil {
		return false
	} else {
		return true
	}
}

func FindAndReplace(path, current, update string) (int, error) {
	file, _ := os.Open(path)
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}

	write_file, err := os.Create(path)
	if err != nil {
		panic(err)
	}
	defer write_file.Close()

	writer := bufio.NewWriter(file)

	replaceCount := 0

	for _, line := range lines {
		if strings.Contains(line, current) {
			line = strings.Replace(line, current, update, -1)
			replaceCount++
		}
		write_file.WriteString(line + "\n")
	}

	writer.Flush()

	return replaceCount, nil
}

package far

import (
	"bufio"
	"os"
	"strings"
)

func FileExists(path string) bool {
	_, err := os.Stat(path)

	if err != nil {
		return false
	} else {
		return true
	}
}

func FindAndReplace(path, current, update string) (int, error) {
	file, _ := os.Open(path)
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}

	write_file, err := os.Create(path)
	if err != nil {
		panic(err)
	}
	defer write_file.Close()

	writer := bufio.NewWriter(file)

	replaceCount := 0

	for _, line := range lines {
		if strings.Contains(line, current) {
			replaceCount += strings.Count(line, current)
			line = strings.Replace(line, current, update, -1)
		}
		write_file.WriteString(line + "\n")
	}

	writer.Flush()

	return replaceCount, nil
}

Update replaceCount to handle multiple instances


// Provides a simple REST API implementing a basic to-do list
package main

import (
	"expvar"
	"log"
	"net/http"

	"sync"
	"todolist/repo"
	"todolist/spi"
)

var repository spi.Repo

// Starts two HTTP services:
//	one at port 8080 for exposing the ToDoList REST service,
//	one at port 8081 for exposing the expvar service.
// The application runs as long as both HTTP services are up
func main() {
	repository = repo.NewRepo()
	err := repository.Init()

	if nil != err {
		panic(err)
	}

	wg := new(sync.WaitGroup)
	wg.Add(1)
	go registerBusinessServer(wg)
	go registerExpvarServer(wg)
	wg.Wait()
}

func registerBusinessServer(wg *sync.WaitGroup) {
	log.Fatal(http.ListenAndServe(":8080", NewRouter()))
	wg.Done()
}

func registerExpvarServer(wg *sync.WaitGroup) {
	log.Fatal(http.ListenAndServe(":8081", expvar.Handler()))
	wg.Done()
}

// Provides a simple REST API implementing a basic to-do list
package main

import (
	"expvar"
	"log"
	"net/http"

	"sync"
	"todolist/repo"
	"todolist/spi"
)

var repository spi.Repo

// Starts two HTTP services:
//	one at port 8080 for exposing the ToDoList REST service,
//	one at port 8081 for exposing the expvar service.
// The application runs as long as both HTTP services are up
func main() {
	repository = repo.NewRepo()

	wg := new(sync.WaitGroup)
	wg.Add(1)
	go registerBusinessServer(wg)
	go registerExpvarServer(wg)
	wg.Wait()
}

func registerBusinessServer(wg *sync.WaitGroup) {
	log.Fatal(http.ListenAndServe(":8080", NewRouter()))
	wg.Done()
}

func registerExpvarServer(wg *sync.WaitGroup) {
	log.Fatal(http.ListenAndServe(":8081", expvar.Handler()))
	wg.Done()
}

Remove duplicate call to repo.Init()


package nativeengine

import schematypes "github.com/taskcluster/go-schematypes"

type config struct {
	Groups []string `json:"groups,omitempty"`
}

var configSchema = schematypes.Object{
	MetaData: schematypes.MetaData{
		Title: "Native Engine Config",
		Description: "Configuration for the native engine, this engines creates " +
			"a system user-account per task, and deletes user-account when task " +
			"is completed.",
	},
	Properties: schematypes.Properties{
		"groups": schematypes.Array{
			MetaData: schematypes.MetaData{
				Title: "Group Memberships",
				Description: "List of system user-groups that the temporary " +
					"task-users should be be granted membership of.",
			},
			Items: schematypes.String{
				MetaData: schematypes.MetaData{
					Title:       "Group Name",
					Description: "Name of a user-group that task-users should be assigned",
				},
				Pattern: "^[a-zA-Z0-9_-]+$",
			},
		},
	},
	Required: []string{},
}

package nativeengine

import schematypes "github.com/taskcluster/go-schematypes"

type config struct {
	Groups []string `json:"groups,omitempty"`
}

var configSchema = schematypes.Object{
	MetaData: schematypes.MetaData{
		Title: "Native Engine Config",
		Description: "Configuration for the native engine, this engines creates " +
			"a system user-account per task, and deletes user-account when task " +
			"is completed.",
	},
	Properties: schematypes.Properties{
		"groups": schematypes.Array{
			MetaData: schematypes.MetaData{
				Title: "Group Memberships",
				Description: "List of system user-groups that the temporary " +
					"task-users should be be granted membership of.",
			},
			Items: schematypes.String{
				MetaData: schematypes.MetaData{
					Title:       "Group Name",
					Description: "Name of a user-group that task-users should be assigned",
				},
				Pattern: "^[a-zA-Z0-9_.-]+$",
			},
		},
	},
	Required: []string{},
}

Add dot for the list of allowed group names. r=jonasfj


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

package directory

import (
	"github.com/corestoreio/csfw/config"
	"golang.org/x/text/language"
)

type Currency struct {
	// https://godoc.org/golang.org/x/text/language
	c language.Currency
}

// BaseCurrencyCode retrieves application base currency code
func BaseCurrencyCode(cr config.Reader) (language.Currency, error) {
	base, err := cr.GetString(config.Path(PathCurrencyBase))
	if err != nil && err != config.ErrKeyNotFound {
		return language.Currency{}, err
	}
	return language.ParseCurrency(base)
}

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

package directory

import (
	"strings"

	"github.com/corestoreio/csfw/config"
	"golang.org/x/text/language"
)

type Currency struct {
	// https://godoc.org/golang.org/x/text/language
	c language.Currency
}

// BaseCurrencyCode retrieves application base currency code
func BaseCurrencyCode(cr config.Reader) (language.Currency, error) {
	base, err := cr.GetString(config.Path(PathCurrencyBase))
	if err != nil && err != config.ErrKeyNotFound {
		return language.Currency{}, err
	}
	return language.ParseCurrency(base)
}

// AllowedCurrencies returns all installed currencies from global scope.
func AllowedCurrencies(cr config.Reader) ([]string, error) {
	installedCur, err := cr.GetString(config.Path(PathSystemCurrencyInstalled))
	if err != nil && err != config.ErrKeyNotFound {
		return nil, err
	}
	// TODO use internal model of PathSystemCurrencyInstalled defined in package directory
	return strings.Split(installedCur, ","), nil
}

Move AllowedCurrencies from store into directory package


package mapper

import (
  "git.aviuslabs.net/golang/async"
  "reflect"
)

func Map(data interface{}, routine async.Routine, callbacks ...async.Done) error {
  var (
    routines []async.Routine
    results  []interface{}
  )

  d := reflect.ValueOf(data)

  for i := 0; i < d.Len(); i++ {
    v := d.Index(i).Interface()
    routines = append(routines, func(done async.Done, args ...interface{}) {
      done = func(original async.Done) async.Done {
        return func(err error, args ...interface{}) {
          results = append(results, args...)
          if i == d.Len() {
            original(err, results...)
            return
          }
          original(err, args...)
        }
      }(done)

      routine(done, v)
    })
  }

  async.Waterfall(routines, callbacks...)

  return nil
}

package mapper

import (
  "git.aviuslabs.net/golang/async"
  "reflect"
)

func Map(data interface{}, routine async.Routine, callbacks ...async.Done) {
  var (
    routines []async.Routine
    results  []interface{}
  )

  d := reflect.ValueOf(data)

  for i := 0; i < d.Len(); i++ {
    v := d.Index(i).Interface()
    routines = append(routines, func(done async.Done, args ...interface{}) {
      done = func(original async.Done) async.Done {
        return func(err error, args ...interface{}) {
          results = append(results, args...)
          if i == d.Len() {
            original(err, results...)
            return
          }
          original(err, args...)
        }
      }(done)

      routine(done, v)
    })
  }

  async.Waterfall(routines, callbacks...)
}

Remove error return from Map; it's most likely not going to be used


package knc

import (
	"fmt"
	"os/exec"
	"encoding/json"
	"keycommon/reqtarget"
)

type KncServer struct {
	Hostname string
}

func (k KncServer) kncRequest(data []byte) ([]byte, error) {
	cmd := exec.Command("/usr/bin/knc", fmt.Sprintf("host@%s", k.Hostname), "20575")

	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	go func() {
		defer stdin.Close()
		stdin.Write(data)
	}()

	response, err := cmd.Output()
	if err != nil {
		return nil, err
	}

	return response, nil
}

func (k KncServer) SendRequests(reqs []reqtarget.Request) ([]string, error) {
	raw_reqs, err := json.Marshal(reqs)
	if err != nil {
		return nil, err
	}

	raw_resps, err := k.kncRequest(raw_reqs)
	if err != nil {
		return nil, err
	}

	resps := []string{}
	err = json.Unmarshal(raw_resps, &resps)
	if err != nil {
		return nil, err
	}

	return resps, nil
}

package knc

import (
	"fmt"
	"os/exec"
	"encoding/json"
	"keycommon/reqtarget"
)

type KncServer struct {
	Hostname string
}

func (k KncServer) kncRequest(data []byte) ([]byte, error) {
	cmd := exec.Command("/usr/bin/knc", fmt.Sprintf("host@%s", k.Hostname), "20575")

	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	go func() {
		defer stdin.Close()
		stdin.Write(data)
	}()

	response, err := cmd.Output()
	if err != nil {
		return nil, err
	}

	return response, nil
}

func (k KncServer) SendRequests(reqs []reqtarget.Request) ([]string, error) {
	raw_reqs, err := json.Marshal(reqs)
	if err != nil {
		return nil, err
	}

	raw_resps, err := k.kncRequest(raw_reqs)
	if err != nil {
		return nil, err
	}

	resps := []string{}
	err = json.Unmarshal(raw_resps, &resps)
	if err != nil {
		return nil, err
	}

	if len(resps) != len(reqs) {
		return nil, errors.New("Wrong number of results")
	}

	return resps, nil
}

Make sure number of responses matches number of requests


package main

import (
	"fmt"
	"io/ioutil"
	"testing"

	rss "github.com/jteeuwen/go-pkg-rss"
	"github.com/stretchr/testify/require"
)

var items []*rss.Item
var fixtures = []string{
	"aws-ec2-us-east-1",
	"crossfitwc",
	"github-status",
	"heroku-status",
	"weather.gov-KPHL",
}

func Test_formatContent(t *testing.T) {
	for _, fixture := range fixtures {
		feed := rss.New(1, true, nil, testItemHandler)
		items = []*rss.Item{}

		xml, err := ioutil.ReadFile(fmt.Sprintf("fixtures/%s.xml", fixture))
		require.NoError(t, err)

		b, err := ioutil.ReadFile(fmt.Sprintf("fixtures/%s.out", fixture))
		require.NoError(t, err)
		expected := string(b)

		err = feed.FetchBytes("http://example.com", xml, charsetReader)
		require.NoError(t, err)
		require.NotEmpty(t, items)

		item := items[0]
		c, err := extractContent(item)
		require.NoError(t, err)
		require.Equal(t, expected, formatContent(c))
	}
}

func testItemHandler(feed *rss.Feed, ch *rss.Channel, newitems []*rss.Item) {
	items = newitems
}

package main

import (
	"fmt"
	"io/ioutil"
	"testing"

	rss "github.com/jteeuwen/go-pkg-rss"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

var items []*rss.Item
var fixtures = []string{
	"aws-ec2-us-east-1",
	"crossfitwc",
	"github-status",
	"heroku-status",
	"weather.gov-KPHL",
}

func Test_formatContent(t *testing.T) {
	for _, fixture := range fixtures {
		feed := rss.New(1, true, nil, testItemHandler)
		items = []*rss.Item{}

		xml, err := ioutil.ReadFile(fmt.Sprintf("fixtures/%s.xml", fixture))
		require.NoError(t, err)

		b, err := ioutil.ReadFile(fmt.Sprintf("fixtures/%s.out", fixture))
		require.NoError(t, err)
		expected := string(b)

		err = feed.FetchBytes("http://example.com", xml, charsetReader)
		require.NoError(t, err)
		require.NotEmpty(t, items)

		item := items[0]
		c, err := extractContent(item)
		require.NoError(t, err)
		assert.Equal(t, expected, formatContent(c), fixture)
	}
}

func testItemHandler(feed *rss.Feed, ch *rss.Channel, newitems []*rss.Item) {
	items = newitems
}

Use assert instead of require for fixture tests


/*
Copyright 2018 The Skaffold Authors

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

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

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

package local

import (
	"context"
	"testing"

	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/GoogleContainerTools/skaffold/testutil"
)

func TestBazelBin(t *testing.T) {
	defer func(c util.Command) { util.DefaultExecCommand = c }(util.DefaultExecCommand)
	util.DefaultExecCommand = testutil.NewFakeCmdOut(
		"bazel info bazel-bin",
		"/absolute/path/bin\n",
		nil,
	)

	bazelBin, err := bazelBin(context.Background(), ".")

	testutil.CheckErrorAndDeepEqual(t, false, err, "/absolute/path/bin", bazelBin)
}

func TestBuildTarPath(t *testing.T) {
	buildTarget := "//:skaffold_example.tar"

	tarPath := buildTarPath(buildTarget)

	testutil.CheckDeepEqual(t, "skaffold_example.tar", tarPath)
}

func TestBuildImageTag(t *testing.T) {
	buildTarget := "//:skaffold_example.tar"

	imageTag := buildImageTag(buildTarget)

	testutil.CheckDeepEqual(t, ":skaffold_example", imageTag)
}

Add a few unit tests


package main

import (
	"github.com/gnamma/server"
	"log"
)

func main() {
	s := server.New(server.Options{
		Name:        "Bar",
		Description: "Yeah. This seems appropriate?",
		Address:     ":3000",
	})

	log.Println("Starting Gnamma server...")

	log.Printf("Name: %v, Description: %v\n", s.Opts.Name, s.Opts.Description)

	err := s.Listen()
	if err != nil {
		log.Fatal(err)
	}

	log.Println("Exiting")
}

package main

import (
	"flag"
	"log"

	"github.com/gnamma/server"
)

var (
	name        = flag.String("name", "server", "The name of the server which you want to host")
	description = flag.String("description", "Greetings, traveller!", "A short description of the server")
	address     = flag.String("address", ":3000", "The address which you want to host the server on, etc localhost:3000")
)

func main() {
	flag.Parse()

	s := server.New(server.Options{
		Name:        *name,
		Description: *description,
		Address:     *address,
	})

	log.Println("Starting Gnamma server...")

	log.Printf("Name: %v, Description: %v\n", s.Opts.Name, s.Opts.Description)

	err := s.Listen()
	if err != nil {
		log.Fatal(err)
	}

	log.Println("Exiting")
}

Add flags to GNS cli