package wall_street_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Wall Street", func() {
	It("is not fully implemented", func() {
		Expect(true).To(BeFalse())
	})
})

package wall_street_test

import (
	"io"
	"wall_street"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Wall Street", func() {
	Describe("Readline", func() {

		It("it reads from stdin and returns a string", func() {
			simulateSTDIN("The return of the Archons", func(r io.Reader) {
				readline := wall_street.Readline("Tonight on The Outer Limits")
				Expect(readline).To(Equal("The return of the Archons"))
			})
		})
	})
})

func simulateSTDIN(input string, block func(r io.Reader)) {
	reader, writer := io.Pipe()
	go func() {
		defer writer.Close()
		writer.Write([]byte(input))
	}()

	block(reader)
}

Write a better failing test


package main_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"

	"time"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
)

var _ = Describe("Pushing an app", func() {
	It("stops the time for pushing an app", func() {
		for index := 0; index < loopCount; index++ {
			startTime := time.Now()

			appName := generator.PrefixedRandomName("APP")
			Expect(
				cf.Cf("push", appName, "-p", "assets/dora").Wait(cfPushTimeout)).
				To(Exit(0))

			statsdClient.Timing(metricsPrefix+"cf-push", time.Since(startTime).Seconds()*1000)
		}
	})
})

package main_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"

	"time"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
)

var _ = Describe("Pushing an app", func() {
	It("stops the time for pushing an app", func() {
		for index := 0; index < loopCount; index++ {
			startTime := time.Now()

			appName := generator.PrefixedRandomName("APP")
			Expect(
				cf.Cf("push", appName, "-p", "assets/dora").Wait(cfPushTimeout)).
				To(Exit(0))

			statsdClient.Timing(asSparseMetric("cf-push"), time.Since(startTime).Seconds()*1000)
		}
	})
})

func asSparseMetric(metricName string) string {
	return metricsPrefix + metricName + ".sparse-avg"
}

Add sparse-avg suffix to metrics name


package router

const (
	FS_STATIC                   = "static"
	FS_UPLOAD_DROPLET           = "upload_droplet"
	FS_UPLOAD_BUILD_ARTIFACTS   = "upload_build_artifacts"
	FS_DOWNLOAD_BUILD_ARTIFACTS = "download_build_artifacts"
)

func NewFileServerRoutes() Routes {
	return Routes{
		{Path: "/static/", Method: "GET", Handler: FS_STATIC},
		{Path: "/droplet/:guid", Method: "POST", Handler: FS_UPLOAD_DROPLET},
		{Path: "/build_artifacts/:app_guid", Method: "POST", Handler: FS_UPLOAD_BUILD_ARTIFACTS},
		{Path: "/build_artifacts/:app_guid", Method: "GET", Handler: FS_DOWNLOAD_BUILD_ARTIFACTS},
	}
}

package router

const (
	FS_STATIC                   = "static"
	FS_UPLOAD_DROPLET           = "upload_droplet"
	FS_UPLOAD_BUILD_ARTIFACTS   = "upload_build_artifacts"
	FS_DOWNLOAD_BUILD_ARTIFACTS = "download_build_artifacts"
)

func NewFileServerRoutes() Routes {
	return Routes{
		{Path: "/v1/static/", Method: "GET", Handler: FS_STATIC},
		{Path: "/v1/droplet/:guid", Method: "POST", Handler: FS_UPLOAD_DROPLET},
		{Path: "/v1/build_artifacts/:app_guid", Method: "POST", Handler: FS_UPLOAD_BUILD_ARTIFACTS},
		{Path: "/v1/build_artifacts/:app_guid", Method: "GET", Handler: FS_DOWNLOAD_BUILD_ARTIFACTS},
	}
}

Update file server routes with API version


package main

import (
	"fmt"
	"io"
	"os"
)

var ARGV []string

func main() {
	ARGV = os.Args[1:]

	// If there are no arguments, then we read STDIN
	if len(ARGV) == 0 {
		ARGV = append(ARGV, "-")
	}

	// Iterate arguments to read filenames
	for _, filename := range ARGV {
		// - means read stdin as a special case, we just use /dev/stdin instead
		if filename == "-" {
			filename = "/dev/stdin"
		}

		// Time to try and read the file in question
		f, err := os.Open(filename)
		if err != nil {
			fmt.Fprintf(os.Stderr, "cat: %s: No such file or directory\n", filename)
			continue
		}

		// Copy our output across!
		io.Copy(os.Stdout, f)
	}

}

package main

import (
	"fmt"
	"io"
	"os"
)

var ARGV []string
var exitcode int

func main() {
	ARGV = os.Args[1:]
	exitcode = 0

	// If there are no arguments, then we read STDIN
	if len(ARGV) == 0 {
		ARGV = append(ARGV, "-")
	}

	// Iterate arguments to read filenames
	for _, filename := range ARGV {
		// - means read stdin as a special case, we just use /dev/stdin instead
		if filename == "-" {
			filename = "/dev/stdin"
		}

		// Time to try and read the file in question
		f, err := os.Open(filename)
		if err != nil {
			fmt.Fprintf(os.Stderr, "cat: %s: No such file or directory\n", filename)
			exitcode = 1
			continue
		}

		// Copy our output across!
		io.Copy(os.Stdout, f)
	}

	os.Exit(exitcode)
}

Exit with correct code on error


package hexToBase64

import "testing"

func TestHexToBase64(t *testing.T) {
	cases := []struct {
		in, want string
		fails    bool
	}{
		{
			"49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d",
			"SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t",
			false,
		},
		{
			"This is not valid hex",
			"This should be ignored",
			true,
		},
	}

	for _, c := range cases {
		got, err := HexToBase64(c.in)
		switch {
		case (err != nil) != c.fails:
			t.Errorf("HexToBase64(%#v) errors: %#v, want %#v", c.in, err != nil, c.fails)
		case !c.fails && got != c.want:
			t.Errorf("HexToBase64(%#v) == %#v,  want %#v", c.in, got, c.want)
		}
	}
}

package hexToBase64

import "testing"

func TestHexToBase64(t *testing.T) {
	cases := []struct {
		in, want string
		fails    bool
	}{
		{
			"",
			"",
			false,
		},
		{
			"49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d",
			"SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t",
			false,
		},
		{
			"This is not valid hex",
			"This should be ignored",
			true,
		},
	}

	for _, c := range cases {
		got, err := HexToBase64(c.in)
		failed := err != nil
		switch {
		case failed != c.fails:
			t.Errorf("HexToBase64(%#v) failure: %#v, want %#v", c.in, failed, c.fails)
		case !c.fails && got != c.want:
			t.Errorf("HexToBase64(%#v) == %#v,  want %#v", c.in, got, c.want)
		}
	}
}

Add zero value test case to challenge 1


// Challenge 46 - RSA parity oracle
// http://cryptopals.com/sets/6/challenges/46

package cryptopals

import "math/big"

type challenge46 struct {
}

type parityOracleServer struct {
	priv privateKey
}

func (server *parityOracleServer) isOdd(c *big.Int) bool {
	m := server.priv.decrypt(c)

	mod := big.NewInt(2)
	mod = mod.Mod(m, mod)

	return mod.Sign() > 0
}

func (challenge46) DecryptRsaParityOracle(server *parityOracleServer, pub *publicKey, c *big.Int) *big.Int {
	low := big.NewInt(0)
	high := new(big.Int).Set(pub.n)

	candidate := new(big.Int).Set(c)
	two := pub.encrypt(big.NewInt(2))

	for low.Cmp(high) < 0 {
		candidate = candidate.Mul(candidate, two)
		candidate = candidate.Mod(candidate, pub.n)

		mid := new(big.Int).Add(low, high)
		mid = mid.Div(mid, two)

		if server.isOdd(candidate) {
			low = mid
		} else {
			high = mid
		}
	}

	return high
}

// Challenge 46 - RSA parity oracle
// http://cryptopals.com/sets/6/challenges/46

package cryptopals

import "math/big"

type challenge46 struct {
}

type parityOracleServer struct {
	priv privateKey
}

func (server *parityOracleServer) isOdd(c *big.Int) bool {
	m := server.priv.decrypt(c)

	mod := big.NewInt(2)
	mod = mod.Mod(m, mod)

	return mod.Sign() > 0
}

func (challenge46) DecryptRsaParityOracle(server *parityOracleServer, pub *publicKey, c *big.Int) *big.Int {
	low := big.NewInt(0)
	high := new(big.Int).Set(pub.n)

	candidate := new(big.Int).Set(c)
	two := big.NewInt(2)
	multiplier := pub.encrypt(two)

	for low.Cmp(high) < 0 {
		candidate = candidate.Mul(candidate, multiplier)
		candidate = candidate.Mod(candidate, pub.n)

		mid := new(big.Int).Add(low, high)
		mid = mid.Div(mid, two)

		if server.isOdd(candidate) {
			low = mid
		} else {
			high = mid
		}
	}

	return high
}

Fix division by two when decrypting (I was actually dividing by 2^e instead of just 2)


// Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
//	http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 logger

func loggerConfig() string {
	config := `
	<seelog type="asyncloop" minlevel="` + level + `">
		<outputs formatid="main">
			<console />`
	if logfile != "" {
		config += `<rollingfile filename="` + logfile + `" type="date"
			 datepattern="2006-01-02-15" archivetype="zip" maxrolls="5" />`
	}
	config += `
		</outputs>
		<formats>
			<format id="main" format="%UTCDate(2006-01-02T15:04:05Z07:00) [%LEVEL] %Msg%n" />
		</formats>
	</seelog>
`
	return config
}

// Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
//	http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 logger

func loggerConfig() string {
	config := `
	<seelog type="asyncloop" minlevel="` + level + `">
		<outputs formatid="main">
			<console />`
	if logfile != "" {
		config += `<rollingfile filename="` + logfile + `" type="date"
			 datepattern="2006-01-02-15" archivetype="none" maxrolls="24" />`
	}
	config += `
		</outputs>
		<formats>
			<format id="main" format="%UTCDate(2006-01-02T15:04:05Z07:00) [%LEVEL] %Msg%n" />
		</formats>
	</seelog>
`
	return config
}

Change log archive to none


package main

import (
	"github.com/HearthSim/stove/bnet"
	"github.com/HearthSim/stove/pegasus"
)

func main() {
	serv := bnet.NewServer()
	serv.RegisterGameServer("WTCG", pegasus.NewServer(serv))
	serv.ListenAndServe("localhost:1119")
}

package main

import (
	"fmt"
	"github.com/HearthSim/stove/bnet"
	"github.com/HearthSim/stove/pegasus"
)

const (
	CONN_HOST = "localhost"
	CONN_PORT = 1119
)

func main() {
	serv := bnet.NewServer()
	serv.RegisterGameServer("WTCG", pegasus.NewServer(serv))

	addr := fmt.Sprintf("%s:%d", CONN_HOST, CONN_PORT)
	fmt.Printf("Listening on %s ...\n", addr)
	serv.ListenAndServe(addr)
}

Add some output on startup


package state

import (
	"os"
	"testing"
)

func TestKVStore(t *testing.T) {
	kv := KVStore{
		DbFileName: "test.db",
		BucketName: "Test",
	}
	kv.Init()
	defer kv.Close()

	err := kv.Set([]byte("foo"), []byte("bar"))
	if err != nil {
		t.Error("Counter not incremented")
	}

	value := kv.Get([]byte("foo"))
	if string(value) != "bar" {
		t.Errorf("Expected value at foo to be bar, go %v", value)
	}

	os.Remove("test.db")
}

package state

import (
	"os"
	"testing"
)

func TestKVStore(t *testing.T) {
	kv := KVStore{
		DbFileName: "test.db",
		BucketName: "Test",
	}
	kv.Init()
	defer kv.Close()

	err := kv.Set([]byte("foo"), []byte("bar"))
	if err != nil {
		t.Error("Counter not incremented")
	}

	value := kv.Get([]byte("foo"))
	if string(value) != "bar" {
		t.Errorf("Expected value at foo to be bar, go %v", value)
	}

	kv.Delete([]byte("foo"))
	value = kv.Get([]byte("foo"))
	if string(value) != "" {
		t.Errorf("Expected value at foo to be empty, got %v", value)
	}

	os.Remove("test.db")
}

Add test to ensure we actually delete a key


package redis

import (
	"github.com/DMarby/picsum-photos/cache"
	"github.com/mediocregopher/radix/v3"
)

// Provider implements a redis cache
type Provider struct {
	pool *radix.Pool
}

// New returns a new Provider instance
func New(address string, poolSize int) (*Provider, error) {
	// Use the default pool, which has a 10 second timeout
	pool, err := radix.NewPool("tcp", address, poolSize)
	if err != nil {
		return nil, err
	}

	return &Provider{
		pool: pool,
	}, nil
}

// Get returns an object from the cache if it exists
func (p *Provider) Get(key string) (data []byte, err error) {
	err = p.pool.Do(radix.Cmd(&data, "GET", key))
	if err != nil {
		return nil, err
	}

	if len(data) == 0 {
		return nil, cache.ErrNotFound
	}

	return
}

// Set adds an object to the cache
func (p *Provider) Set(key string, data []byte) (err error) {
	return p.pool.Do(radix.FlatCmd(nil, "SET", key, data))
}

// Shutdown shuts down the cache
func (p *Provider) Shutdown() {
	p.pool.Close()
}

package redis

import (
	"github.com/DMarby/picsum-photos/cache"
	"github.com/mediocregopher/radix/v3"
)

// Provider implements a redis cache
type Provider struct {
	pool *radix.Pool
}

// New returns a new Provider instance
func New(address string, poolSize int) (*Provider, error) {
	// Use the default pool, which has a 10 second timeout
	pool, err := radix.NewPool("tcp", address, poolSize)
	if err != nil {
		return nil, err
	}

	return &Provider{
		pool: pool,
	}, nil
}

// Get returns an object from the cache if it exists
func (p *Provider) Get(key string) (data []byte, err error) {
	mn := radix.MaybeNil{Rcv: &data}
	err = p.pool.Do(radix.Cmd(&mn, "GET", key))
	if err != nil {
		return nil, err
	}

	if mn.Nil {
		return nil, cache.ErrNotFound
	}

	return
}

// Set adds an object to the cache
func (p *Provider) Set(key string, data []byte) (err error) {
	return p.pool.Do(radix.FlatCmd(nil, "SET", key, data))
}

// Shutdown shuts down the cache
func (p *Provider) Shutdown() {
	p.pool.Close()
}

Use radix.MaybeNil for detecting if something doesn't exist in the cache


// Copyright (C) 2017 Damon Revoe. All rights reserved.
// Use of this source code is governed by the MIT
// license, which can be found in the LICENSE file.

package main

func listPackages(workspacedir, pkgpath string) error {
	packageIndex, err := buildPackageIndex(pkgpath)

	if err != nil {
		return err
	}

	packageIndex.printListOfPackages()

	return nil
}

// Copyright (C) 2017 Damon Revoe. All rights reserved.
// Use of this source code is governed by the MIT
// license, which can be found in the LICENSE file.

package main

import (
	"log"

	"github.com/spf13/cobra"
)

func listPackages() error {
	packageIndex, err := buildPackageIndex(flags.pkgPath)

	if err != nil {
		return err
	}

	packageIndex.printListOfPackages()

	return nil
}

// listCmd represents the init command
var listCmd = &cobra.Command{
	Use:   "list",
	Short: "Print the list of packages found in $" + pkgPathEnvVar,
	Args:  cobra.MaximumNArgs(0),
	Run: func(cmd *cobra.Command, args []string) {
		if err := listPackages(); err != nil {
			log.Fatal(err)
		}
	},
}

func init() {
	RootCmd.AddCommand(listCmd)

	listCmd.Flags().SortFlags = false
	addWorkspaceDirFlag(listCmd)
	addPkgPathFlag(listCmd)
}

Add the 'list' command using cobra


package nigronimgosession

import (
	"net/http"

	"github.com/gorilla/context"
	mgo "gopkg.in/mgo.v2"
)

type DatabaseAccessor struct {
	*mgo.Session
	url  string
	name string
}

func NewDatabaseAccessor(url, name, string) (*DatabaseAccessor, error) {
	session, err := mgo.Dial(url)
	if err == nil {
		return &DatabaseAccessor{session, url, name}, nil
	} else {
		return &DatabaseAccessor{}, err
	}
}

func (da *DatabaseAccessor) Set(request *http.Request, session *mgo.Session) {
	db := session.DB(da.name)
	context.Set(request, 0, db)
	context.Set(request, 1, session)
}

package nigronimgosession

import (
	"net/http"

	"github.com/gorilla/context"
	mgo "gopkg.in/mgo.v2"
)

type DatabaseAccessor struct {
	*mgo.Session
	url  string
	name string
	coll string
}

func NewDatabaseAccessor(url, name, coll string) (*DatabaseAccessor, error) {
	session, err := mgo.Dial(url)
	if err == nil {
		return &DatabaseAccessor{session, url, name, coll}, nil
	} else {
		return &DatabaseAccessor{}, err
	}
}

func (da *DatabaseAccessor) Set(request *http.Request, session *mgo.Session) {
	db := session.DB(da.name)
	context.Set(request, 0, db)
	context.Set(request, 1, session)
}

Revert the database accessor cahnges


package testutil

import (
	"os/exec"
	"runtime"
	"syscall"
	"testing"
)

func ExecCompatible(t *testing.T) {
	if runtime.GOOS != "windows" && syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
}

func QemuCompatible(t *testing.T) {
	// Check if qemu exists
	_, err := exec.Command("qemu-system-x86_64", "-version").CombinedOutput()
	if err != nil {
		t.Skip("Must have Qemu installed for Qemu specific tests to run")
	}
}

func RktCompatible(t *testing.T) {
	if runtime.GOOS == "windows" || syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
	// else see if rkt exists
	_, err := exec.Command("rkt", "version").CombinedOutput()
	if err != nil {
		t.Skip("Must have rkt installed for rkt specific tests to run")
	}
}

func MountCompatible(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("Windows does not support mount")
	}

	if syscall.Geteuid() != 0 {
		t.Skip("Must be root to run test")
	}
}

package testutil

import (
	"os/exec"
	"runtime"
	"syscall"
	"testing"
)

func ExecCompatible(t *testing.T) {
	if runtime.GOOS != "windows" && syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
}

func QemuCompatible(t *testing.T) {
	// Check if qemu exists
	bin := "qemu-system-x86_64"
	if runtime.GOOS == "windows" {
		bin = "qemu-img"
	}
	_, err := exec.Command(bin, "--version").CombinedOutput()
	if err != nil {
		t.Skip("Must have Qemu installed for Qemu specific tests to run")
	}
}

func RktCompatible(t *testing.T) {
	if runtime.GOOS == "windows" || syscall.Geteuid() != 0 {
		t.Skip("Must be root on non-windows environments to run test")
	}
	// else see if rkt exists
	_, err := exec.Command("rkt", "version").CombinedOutput()
	if err != nil {
		t.Skip("Must have rkt installed for rkt specific tests to run")
	}
}

func MountCompatible(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("Windows does not support mount")
	}

	if syscall.Geteuid() != 0 {
		t.Skip("Must be root to run test")
	}
}

Use same binary as Fingerprint in the QemuCompatible function


package main

import (
  "html/template"
  "log"
  "net/http"
)

type Blog struct {
  Articles map[string]*Article
}

func (b *Blog) getArticle(slug string) *Article {
  if article := b.Articles[slug]; article != nil {
    return article
  }

  return nil
}

func (b *Blog) articleHandler(w http.ResponseWriter, r *http.Request) {
  slug := r.URL.Path[len("/articles/"):]

  article := b.getArticle(slug)

  if article == nil {
    http.NotFound(w, r)
  }

  template, _ := template.ParseFiles("layouts/article.html")

  template.Execute(w, article)

}

func main() {
  blog := Blog{Articles: LoadArticles()}

  fs := http.FileServer(http.Dir("public"))
  http.Handle("/public/", http.StripPrefix("/public/", fs))

  http.HandleFunc("/articles/", blog.articleHandler)

  log.Println("Listening...")
  http.ListenAndServe(":3001", nil)
}

package main

import (
  "html/template"
  "log"
  "net/http"
)

type Blog struct {
  Articles map[string]*Article
}

func (b *Blog) getArticle(slug string) *Article {
  if article := b.Articles[slug]; article != nil {
    return article
  }

  return nil
}

func (b *Blog) articleHandler(w http.ResponseWriter, r *http.Request) {
  slug := r.URL.Path[len("/articles/"):]

  article := b.getArticle(slug)

  if article == nil {
    http.NotFound(w, r)
    return
  }

  template, _ := template.ParseFiles("layouts/article.html")

  template.Execute(w, article)
}

func main() {
  blog := Blog{Articles: LoadArticles()}

  fs := http.FileServer(http.Dir("public"))
  http.Handle("/public/", http.StripPrefix("/public/", fs))

  http.HandleFunc("/articles/", blog.articleHandler)

  log.Println("Listening...")
  http.ListenAndServe(":3001", nil)
}

Return when the article is not found and avoid render the template


package dom

/*
 * Implements a very small, very non-compliant subset of the DOM Core Level 2
 */

// DOM2: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
type Node interface {
  NodeName() string;
}

// DOM2: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614
type Element interface {
  Node;
  TagName() string;
//  GetAttribute(name string) string;
//  SetAttribute(name string, value string);
}

// DOM2: http://www.w3.org/TR/DOM-Level-2-Core/core.html#i-Document
type Document interface {
  Node;
  DocumentElement() Element;
}

// internal structures that implements the above public interfaces
type elementImpl struct {}
func (e *elementImpl) NodeName() string { return ""; }
func (e *elementImpl) TagName() string { return e.NodeName(); }

type documentImpl struct {}
func (d *documentImpl) NodeName() string { return ""; }
func (d *documentImpl) DocumentElement() Element { return new(elementImpl); }

func ParseString(s string) *documentImpl {
  var d = new(documentImpl);
  return d;
}

package dom

/*
 * Implements a very small, very non-compliant subset of the DOM Core Level 2
 */

// DOM2: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
type Node interface {
  NodeName() string;
}

// DOM2: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614
type Element interface {
  Node;
  TagName() string;
//  GetAttribute(name string) string;
//  SetAttribute(name string, value string);
}

// DOM2: http://www.w3.org/TR/DOM-Level-2-Core/core.html#i-Document
type Document interface {
  Node;
  DocumentElement() Element;
}

// internal structures that implement the above public interfaces

type elem struct {}
func (e *elem) NodeName() string { return "elem.NodeName() not implemented"; }
func (e *elem) TagName() string { return e.NodeName(); }

type doc struct {}
func (d *doc) NodeName() string { return ""; }
func (d *doc) DocumentElement() Element { return new(elem); }

func ParseString(s string) Document {
  var d = new(doc);
  return d;
}

Rename internal structures to shorter names. Change return type of ParseString() to Document instead of *Document


package schema

import "time"

type Service struct {
	ID      string    `gorethink:"id"`
	Name    string    `gorethink:"name"`
	Type    string    `gorethink:"_type"`
	Current bool      `gorethink:"current"`
	CTime   time.Time `gorethink:"ctime"`
}

type Service2Template struct {
	ID         string `gorethink:"id"`
	ServiceID  string `gorethink:"service_id"`
	TemplateID string `gorethink:"template_id"`
}

type Template struct {
	ID      string `gorethink:"id"`
	Name    string `gorethink:"name"`
	Body    string `gorethink:"body"`
	Version int    `gorethink:"version"`
}

type ChangeLog struct {
	ID      string    `gorethink:"id"`
	OtherID string    `gorethink:"other_id"`
	Who     string    `gorethink:"who"`
	When    time.Time `gorethink:"when"`
}

package schema

import "time"

// A Service is a named service that has a set of templates associated with it.
type Service struct {
	ID      string    `gorethink:"id"`
	Name    string    `gorethink:"name"`
	Type    string    `gorethink:"_type"`   // The type of service.
	Current bool      `gorethink:"current"` // Is this the current service definition.
	CTime   time.Time `gorethink:"ctime"`
}

// Service2Template is a join table that maps a service to templates.
type Service2Template struct {
	ID         string `gorethink:"id"`
	ServiceID  string `gorethink:"service_id"`
	TemplateID string `gorethink:"template_id"`
}

// Template is a consul-template for service configuration/monitoring.
type Template struct {
	ID      string `gorethink:"id"`
	Name    string `gorethink:"name"`
	Path    string `gorethink:"path"`    // Path to template definition
	Body    string `gorethink:"body"`    // The body of the template (same as Path at point in time)
	Version int    `gorethink:"version"` // Version of template. A template can change over time.
}

// ChangeLog tracks the changes to service and template definitions. It allows
// a user to see the difference across definitions.
type ChangeLog struct {
	ID      string    `gorethink:"id"`
	OtherID string    `gorethink:"other_id"`
	Who     string    `gorethink:"who"`
	When    time.Time `gorethink:"when"`
}

Add comments and documentation to definitions.


package repo

type Identity struct {
	Name  string
	Email string
}

func (i *Identity) hasName() bool {
	return i.Name != ""
}

func (i *Identity) hasEmail() bool {
	return i.Email != ""
}

func (i *Identity) String() string {
	str := ""
	if i.hasName() {
		str += "\tName: " + i.Name
	}
	if i.hasEmail() {
		str += "\tEmail: " + i.Email
	}
	return str
}

package repo

type Identity struct {
	Name  string
	Email string
}

func (i *Identity) hasName() bool {
	return i.Name != ""
}

func (i *Identity) hasEmail() bool {
	return i.Email != ""
}

func (i *Identity) String() string {
	str := ""
	if i.hasName() {
		str += "  Name: " + i.Name + "\n"
	}
	if i.hasEmail() {
		str += "  Email: " + i.Email
	}
	return str
}

Improve string representation of Identity


// Define helper / mock for unit testing
//
// Because golang likes return error object instead of exception/panic,
// always handle error return values is a good practise. But sometimes it is
// impossible to got error, such as read from memory buffer, not handler them
// maybe maybe loose error because someday code changes, but handle them needs
// a lot of duplicate codes.
//
// In package testing contains many test helper packages, suffix with `th', to
// handle these never happen errors. Test helper check the error result, if it
// is not nil, using testing.Fatal(err) to log the error object and abort current
// test case execution.
package testing

import (
	"time"
)

// Try the action until it returns true, call timeout if timeout.
func TryWait(d time.Duration, try func() bool, timeout func()) {
	tick := int64(d) / 100
	for i := 0; i < 100; i++ {
		if try() {
			return
		}
		time.Sleep(time.Duration(tick))
	}
	timeout()
}

// Package testing define helper / mock for unit testing
//
// Because golang likes return error object instead of exception/panic,
// always handle error return values is a good practise. But sometimes it is
// impossible to got error, such as read from memory buffer, not handler them
// maybe maybe loose error because someday code changes, but handle them needs
// a lot of duplicate codes.
//
// In package testing contains many test helper packages, suffix with `th', to
// handle these never happen errors. Test helper check the error result, if it
// is not nil, using testing.Fatal(err) to log the error object and abort current
// test case execution.
package testing

import (
	"time"
)

// TryWait the action until it returns true, call timeout if timeout.
func TryWait(d time.Duration, try func() bool, timeout func()) {
	tick := int64(d) / 100
	for i := 0; i < 100; i++ {
		if try() {
			return
		}
		time.Sleep(time.Duration(tick))
	}
	timeout()
}

Fix two doc comment format


package main

import (
	"testing"
	"time"
)

func TestParseTime(t *testing.T) {

	message := []byte{0x24, 0x4b, 0xbb, 0x9a, 0xc9, 0xf0}
	utcDate := time.Now().UTC()

	wanted := time.Date(utcDate.Year(), utcDate.Month(), utcDate.Day(),
		10, 19, 26, 999999984, time.UTC)

	result := parseTime(message)

	if result != wanted {
		t.Errorf("Time not parsed correctly, got: %s, want: %s.", result, wanted)
	}
}

func BenchmarkParseTime(b *testing.B) {

	message := []byte{0x24, 0x4b, 0xbb, 0x9a, 0xc9, 0xf0}

	for n := 0; n < b.N; n++ {
		parseTime(message)
	}
}

Add benchmarks for parseTime func


// Copyright 2014 The Go 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 main

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

//go:generate jsonenums -type=ShirtSize
type ShirtSize byte

const (
	NA ShirtSize = iota
	XS
	S
	M
	L
	XL
)

//go:generate jsonenums -type=WeekDay
type WeekDay int

const (
	Monday WeekDay = iota
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
	Sunday
)

func main() {
	v := struct {
		Size ShirtSize
		Day  WeekDay
	}{M, Friday}
	if err := json.NewEncoder(os.Stdout).Encode(v); err != nil {
		log.Fatal(err)
	}
}

Move the go:generate comments one line up to avoid documenting the type


// See LICENSE.txt for licensing information.

package main

import (
	"fmt"
	"strings"
)

var (
	SPINNER_STRINGS = []string{"◢ ", "◣ ", "◤ ", "◥ "}
	SPINNER_LEN     = len(SPINNER_STRINGS)
)

type Spinner struct {
	running  bool   // indiacte we're actually printing
	msg      string // current message
	pos      int    // position in SPINNER_RUNES
	last_len int    // total length of last status
}

func (s *Spinner) Finish() {
	fmt.Println()
	s.running = false
	s.msg = ""
	s.pos = 0
	s.last_len = 0
}

func (s *Spinner) Tick() {
	if s.running {
		fmt.Print("\r", strings.Repeat(" ", s.last_len), "\r")
	} else {
		s.running = true
	}

	fmt.Print(SPINNER_STRINGS[s.pos])
	fmt.Print(s.msg)

	s.pos = (s.pos + 1) % SPINNER_LEN
	s.last_len = 2 + len(s.msg)
}

func (s *Spinner) Msg(msg string) {
	s.msg = msg
	s.Tick()
}

// See LICENSE.txt for licensing information.

package main

import (
	"fmt"
	"strings"
)

var (
	SPINNER_STRINGS = []string{"◢ ", "◣ ", "◤ ", "◥ "}
	SPINNER_LEN     = len(SPINNER_STRINGS)
)

type Spinner struct {
	running  bool   // indiacte we're actually printing
	msg      string // current message
	pos      int    // position in SPINNER_STRINGS
	last_len int    // total length of last status
}

func (s *Spinner) Finish() {
	fmt.Println()
	s.running = false
	s.msg = ""
	s.pos = 0
	s.last_len = 0
}

func (s *Spinner) Tick() {
	if s.running {
		fmt.Print("\r", strings.Repeat(" ", s.last_len), "\r")
	} else {
		s.running = true
	}

	fmt.Print(SPINNER_STRINGS[s.pos])
	fmt.Print(s.msg)

	s.pos = (s.pos + 1) % SPINNER_LEN
	s.last_len = 2 + len(s.msg)
}

func (s *Spinner) Msg(msg string) {
	s.msg = msg
	s.Tick()
}

Fix comment; They were never runes


package runtime

import (
	"encoding/json"
	"fmt"
	"reflect"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
)

// Decode decodes the specified val into the specified target.
func Decode(target interface{}, val string) error {
	return decode(reflect.ValueOf(target).Elem(), val)
}

func decode(target reflect.Value, inputValue string) error {
	targetType := target.Type()

	if target.Kind() == reflect.Ptr {
		target.Set(reflect.New(targetType.Elem()))
		return decode(target.Elem(), inputValue)
	}

	if targetType.Kind() == reflect.Struct {
		if targetProto, ok := target.Addr().Interface().(proto.Message); ok {
			return jsonpb.UnmarshalString(inputValue, targetProto)
		}

		return fmt.Errorf("Unacceptable type %s", targetType)
	}

	return json.Unmarshal([]byte(inputValue), target.Addr().Interface())
}

package runtime

import (
	"encoding/json"
	"fmt"
	"reflect"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
)

// Decode decodes the specified val into the specified target.
func Decode(target interface{}, val string) error {
	return decode(reflect.ValueOf(target).Elem(), val)
}

func decode(target reflect.Value, inputValue string) error {
	targetType := target.Type()

	if target.Kind() == reflect.Ptr {
		target.Set(reflect.New(targetType.Elem()))

		return decode(target.Elem(), inputValue)
	}

	if targetType.Kind() == reflect.String {
		target.Set(reflect.ValueOf(inputValue))
		return nil
	}

	if targetType.Kind() == reflect.Struct {
		if targetProto, ok := target.Addr().Interface().(proto.Message); ok {
			return jsonpb.UnmarshalString(inputValue, targetProto)
		}

		return fmt.Errorf("Unacceptable type %s", targetType)
	}

	return json.Unmarshal([]byte(inputValue), target.Addr().Interface())
}

Fix support for unmarshaling to string types when the value is valid json otherwise.


package desugar

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tisp-lang/tisp/src/lib/ast"
)

func TestNamesFind(t *testing.T) {
	n := "x"
	assert.True(t, newNames(n).find(ast.NewLetVar(n, n)).include(n))
}

package desugar

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tisp-lang/tisp/src/lib/ast"
	"github.com/tisp-lang/tisp/src/lib/debug"
)

func TestNamesFindWithLetVar(t *testing.T) {
	n := "x"
	assert.True(t, newNames(n).find(ast.NewLetVar(n, n)).include(n))
}

func TestNamesFindWithLetFunction(t *testing.T) {
	n := "x"

	for _, test := range []struct {
		letFunc ast.LetFunction
		answer  bool
	}{
		{
			ast.NewLetFunction(
				n,
				ast.NewSignature(nil, nil, "", nil, nil, ""),
				nil,
				n,
				debug.NewGoInfo(0)),
			true,
		},
		{
			ast.NewLetFunction(
				n,
				ast.NewSignature(nil, nil, "", nil, nil, ""),
				[]interface{}{ast.NewLetVar(n, n)},
				n,
				debug.NewGoInfo(0)),
			true,
		},
		{
			ast.NewLetFunction(
				n,
				ast.NewSignature(nil, nil, "", nil, nil, ""),
				[]interface{}{ast.NewLetVar(n, "y")},
				n,
				debug.NewGoInfo(0)),
			false,
		},
	} {
		assert.Equal(t, test.answer, newNames(n).find(test.letFunc).include(n))
	}
}

Test names with let-function nodes


package ziputils

import (
	. "github.com/francoishill/golang-web-dry/errors/checkerror"
	"io"
	"os"
)

func SaveReaderToFile(logger SimpleLogger, bodyReader io.Reader, saveFilePath string) {
	out, err := os.Create(saveFilePath)
	CheckError(err)
	defer out.Close()

	_, err = io.Copy(out, bodyReader)
	CheckError(err)
}

package ziputils

import (
	. "github.com/francoishill/golang-web-dry/errors/checkerror"
	"io"
	"os"
	"path/filepath"

	"github.com/francoishill/golang-web-dry/osutils"
)

func SaveReaderToFile(logger SimpleLogger, bodyReader io.Reader, saveFilePath string) {
	fullDestinationDirPath := filepath.Dir(saveFilePath)
	if !osutils.DirectoryExists(fullDestinationDirPath) {
		logger.Debug("(TAR) Creating directory '%s' ( parent of file '%s')", fullDestinationDirPath, filepath.Base(saveFilePath))
		err := os.MkdirAll(fullDestinationDirPath, os.FileMode(0655))
		CheckError(err)
	}

	out, err := os.Create(saveFilePath)
	CheckError(err)
	defer out.Close()

	_, err = io.Copy(out, bodyReader)
	CheckError(err)
}

Create file parent dir if not exist.


package server

import (
	"net/http"
	"time"

	"github.com/influxdata/chronograf"
)

// Logger is middleware that logs the request
func Logger(logger chronograf.Logger, next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		now := time.Now()
		logger.
			WithField("component", "server").
			WithField("remote_addr", r.RemoteAddr).
			WithField("method", r.Method).
			WithField("url", r.URL).
			Info("Request")
		next.ServeHTTP(w, r)
		later := time.Now()
		elapsed := later.Sub(now)

		logger.
			WithField("component", "server").
			WithField("remote_addr", r.RemoteAddr).
			WithField("response_time", elapsed.String()).
			Info("Success")
	}
	return http.HandlerFunc(fn)
}

package server

import (
	"net/http"
	"time"

	"github.com/influxdata/chronograf"
)

type logResponseWriter struct {
	http.ResponseWriter

	responseCode int
}

func (l *logResponseWriter) WriteHeader(status int) {
	l.responseCode = status
	l.ResponseWriter.WriteHeader(status)
}

// Logger is middleware that logs the request
func Logger(logger chronograf.Logger, next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		now := time.Now()
		logger.
			WithField("component", "server").
			WithField("remote_addr", r.RemoteAddr).
			WithField("method", r.Method).
			WithField("url", r.URL).
			Info("Request")

		lrr := &logResponseWriter{w, 0}
		next.ServeHTTP(lrr, r)
		later := time.Now()
		elapsed := later.Sub(now)

		logger.
			WithField("component", "server").
			WithField("remote_addr", r.RemoteAddr).
			WithField("response_time", elapsed.String()).
			WithField("code", lrr.responseCode).
			Info("Response: ", http.StatusText(lrr.responseCode))
	}
	return http.HandlerFunc(fn)
}

Add HTTP status code to logs


package asciidocgo

import "testing"
import . "github.com/smartystreets/goconvey/convey"

func TestAsciidocgo(t *testing.T) {
	Load(nil)
	Convey("Asciidocgo takes a Reader and return a Document", t, func() {
		Convey("A nil Reader must returns a nil Document", func() {
			So(Load(nil), ShouldBeNil)
		})
	})
}

package asciidocgo

import "testing"
import . "github.com/smartystreets/goconvey/convey"

func TestAsciidocgo(t *testing.T) {
	Load(nil)
	Convey("Asciidocgo load() takes a string and return a Document", t, nil)
	Convey("Asciidocgo load() takes a array and return a Document", t, nil)
	Convey("Asciidocgo load() takes a IO and return a Document", t, nil)

	Convey("Asciidocgo load() takes a Reader and return a Document", t, func() {
		Convey("A nil Reader must returns a nil Document", func() {
			So(Load(nil), ShouldBeNil)
		})
	})
}

Add input entry test declaration for Asciidocgo.


package main

import (
	"io/ioutil"
)

// Reader defines an interface that implements the
// methods to read files from some resource and translate
// it to File instances
type Reader interface {
	Read(path string) ([]File, error)
}

// DiskReader defines a implementation of the
// Reader interface to read files from Disk
type DiskReader struct{}

// Read reads the files from disk and translate it
// to the internal File structure
func (dr DiskReader) Read(path string) ([]File, error) {
	var files []File

	memFiles, err := ioutil.ReadDir(path)
	if err != nil {
		return nil, err
	}

	for _, memFile := range memFiles {
		if memFile.IsDir() {
			continue
		}

		content, err := ioutil.ReadFile(path + memFile.Name())
		if err != nil {
			return nil, err
		}

		files = append(files, File{
			FileInfo: memFile,
			Path:     path,
			Content:  string(content),
		})
	}

	return files, nil
}

package main

import (
	"fmt"
	"io/ioutil"
)

// Reader defines an interface that implements the
// methods to read files from some resource and translate
// it to File instances
type Reader interface {
	Read(path string) ([]File, error)
}

// DiskReader defines a implementation of the
// Reader interface to read files from Disk
type DiskReader struct{}

// Read reads the files from disk and translate it
// to the internal File structure
func (dr DiskReader) Read(path string) ([]File, error) {
	var files []File

	memFiles, err := ioutil.ReadDir(path)
	if err != nil {
		return nil, err
	}

	for _, memFile := range memFiles {
		if memFile.IsDir() {
			continue
		}

		content, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", path, memFile.Name()))
		if err != nil {
			return nil, err
		}

		files = append(files, File{
			FileInfo: memFile,
			Path:     path,
			Content:  string(content),
		})
	}

	return files, nil
}

Fix on Loader (missing "/")


package handlers

import (
	"github.com/prometheus/client_golang/prometheus"
)

var (
	RedirectHandlerRedirectCountMetric = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "router_redirect_handler_redirect_total",
			Help: "Number of redirects handled by router redirect handlers",
		},
		[]string{
			"redirect_code",
			"redirect_type",
			"redirect_url",
		},
	)

	BackendHandlerRequestCountMetric = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "router_backend_handler_request_total",
			Help: "Number of requests handled by router backend handlers",
		},
		[]string{
			"backend_id",
			"request_method",
		},
	)

	BackendHandlerResponseDurationSecondsMetric = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "router_backend_handler_response_duration_seconds",
			Help: "Histogram of response durations by router backend handlers",
			Buckets: prometheus.ExponentialBuckets(
				0.25, 2, 6, // This buckets [...0.25  0.5  1  2  4  8...]
			),
		},
		[]string{
			"backend_id",
			"request_method",
			"response_code",
		},
	)
)

func initMetrics() {
	prometheus.MustRegister(RedirectHandlerRedirectCountMetric)

	prometheus.MustRegister(BackendHandlerRequestCountMetric)
	prometheus.MustRegister(BackendHandlerResponseDurationSecondsMetric)
}

package handlers

import (
	"github.com/prometheus/client_golang/prometheus"
)

var (
	RedirectHandlerRedirectCountMetric = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "router_redirect_handler_redirect_total",
			Help: "Number of redirects handled by router redirect handlers",
		},
		[]string{
			"redirect_code",
			"redirect_type",
			"redirect_url",
		},
	)

	BackendHandlerRequestCountMetric = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "router_backend_handler_request_total",
			Help: "Number of requests handled by router backend handlers",
		},
		[]string{
			"backend_id",
			"request_method",
		},
	)

	BackendHandlerResponseDurationSecondsMetric = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "router_backend_handler_response_duration_seconds",
			Help: "Histogram of response durations by router backend handlers",
			Buckets: prometheus.ExponentialBuckets(
				0.0625, 2, 7, // This buckets [...0.0625  0.125  0.25  0.5  1  2  4...]
			),
		},
		[]string{
			"backend_id",
			"request_method",
			"response_code",
		},
	)
)

func initMetrics() {
	prometheus.MustRegister(RedirectHandlerRedirectCountMetric)

	prometheus.MustRegister(BackendHandlerRequestCountMetric)
	prometheus.MustRegister(BackendHandlerResponseDurationSecondsMetric)
}

Adjust histogram buckets for faster responses


package auth

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"net/http"
)

const (
	tokenCookieName = "access_token"
)

func AddRoutes(r *mux.Router, service Service) {
	// Explicitly only serve login over https.
	r.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {

		decoder := json.NewDecoder(r.Body)
		req := LoginRequest{}
		err := decoder.Decode(&req)
		if err != nil {
			http.Error(w, fmt.Sprintf("failed to decode login request from request body: %v", err), 400)
			return
		}

		token, err := service.Login(req)
		if err != nil {
			// Explicitly do not pass up the reason for login failure.
			http.Error(w, "Invalid username or password.", 403)
		}

		signedString, err := service.Sign(token)
		if err != nil {
			http.Error(w, fmt.Sprintf("failed to issue token: %v", err), 503)
		}

		// Return token as a cookie.
		w.Header().Add("Set-Cookie", fmt.Sprintf("%v=%v; Path=/api; Secure; HttpOnly;", tokenCookieName, signedString))

		w.WriteHeader(http.StatusNoContent)
	}).Methods("POST").Schemes("https")
}

package auth

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"net/http"
)

const (
	tokenCookieName = "access_token"
)

func AddRoutes(r *mux.Router, service Service) {
	// Do not serve these routes over http.
	r.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {

		decoder := json.NewDecoder(r.Body)
		req := LoginRequest{}
		err := decoder.Decode(&req)
		if err != nil {
			http.Error(w, fmt.Sprintf("failed to decode login request from request body: %v", err), 400)
			return
		}

		token, err := service.Login(req)
		if err != nil {
			// Explicitly do not pass up the reason for login failure.
			http.Error(w, "Invalid username or password.", 403)
		}

		signedString, err := service.Sign(token)
		if err != nil {
			http.Error(w, fmt.Sprintf("failed to issue token: %v", err), 503)
		}

		// Return token as a cookie.
		w.Header().Add("Set-Cookie", fmt.Sprintf("%v=%v; Path=/api; Secure; HttpOnly;", tokenCookieName, signedString))

		w.WriteHeader(http.StatusNoContent)
	}).Methods("POST")
}

Remove schemes matcher from auth routes. It seems broken


package main

import (
	"testing"
)

var testcases = []struct {
	hands    string
	expected bool
}{
	{"123456789m123p1s", true},
	{"111222333m111p1s", true},
	{"EEESSSWWWNNNW", true},
	{"13579m2468p1357s", false},
	{"13579m2468pESWN", false},
	{"1133557799mEEN", true},
}

func TestJudgeTenpai(t *testing.T) {
	for _, testcase := range testcases {
		result := JudgeTenpai(testcase.hands)
		if result != testcase.expected {
			t.Errorf("%s must be %v", testcase.hands, testcase.expected)
		}
	}
}

package main

import (
	"testing"
)

var testcases = []struct {
	hands    string
	expected bool
}{
	{"123456789m123p1s", true},
	{"111222333m111p1s", true},
	{"EEESSSWWWNNNW", true},
	{"13579m2468p1357s", false},
	{"13579m2468pESWN", false},
	{"1133557799mEEN", true},
}

func TestJudgeTenpai(t *testing.T) {
	for _, testcase := range testcases {
		result := JudgeTenpai(testcase.hands)
		if result != testcase.expected {
			t.Errorf("%s must be %v but %v", testcase.hands, testcase.expected, result)
		}
	}
}

Make the failed case text understandable a bit


package eventnotifier

import (
	"net/http"
	"sync"

	"github.com/Symantec/Dominator/lib/log"
	"github.com/Symantec/keymaster/proto/eventmon"
)

type EventNotifier struct {
	logger log.DebugLogger
	mutex  sync.Mutex
	// Protected by lock.
	transmitChannels map[chan<- eventmon.EventV0]chan<- eventmon.EventV0
}

func New(logger log.DebugLogger) *EventNotifier {
	return newEventNotifier(logger)
}

func (n *EventNotifier) PublishAuthEvent(authType, username string) {
	n.publishAuthEvent(authType, username)
}

func (n *EventNotifier) PublishSSH(cert []byte) {
	n.publishCert(eventmon.EventTypeSSHCert, cert)
}

func (n *EventNotifier) PublishWebLoginEvent(username string) {
	n.publishWebLoginEvent(username)
}

func (n *EventNotifier) PublishX509(cert []byte) {
	n.publishCert(eventmon.EventTypeX509Cert, cert)
}

func (n *EventNotifier) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	n.serveHTTP(w, req)
}

package eventnotifier

import (
	"net/http"
	"sync"

	"github.com/Symantec/Dominator/lib/log"
	"github.com/Symantec/keymaster/proto/eventmon"
)

type EventNotifier struct {
	logger log.DebugLogger
	mutex  sync.Mutex
	// Protected by lock.
	transmitChannels map[chan<- eventmon.EventV0]chan<- eventmon.EventV0
}

func New(logger log.DebugLogger) *EventNotifier {
	return newEventNotifier(logger)
}

func (n *EventNotifier) PublishAuthEvent(authType, username string) {
	n.publishAuthEvent(authType, username)
}

func (n *EventNotifier) PublishServiceProviderLoginEvent(url string) {
}

func (n *EventNotifier) PublishSSH(cert []byte) {
	n.publishCert(eventmon.EventTypeSSHCert, cert)
}

func (n *EventNotifier) PublishWebLoginEvent(username string) {
	n.publishWebLoginEvent(username)
}

func (n *EventNotifier) PublishX509(cert []byte) {
	n.publishCert(eventmon.EventTypeX509Cert, cert)
}

func (n *EventNotifier) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	n.serveHTTP(w, req)
}

Check in PublishServiceProviderLoginEvent() stub function.


package day4

import (
	"strings"

	"github.com/domdavis/adventofcode/2016/day4/room"
)

func Solution() string {
	return "Not yet solved"
}

func sum(input string) int {
	total := 0
	for _, code := range strings.Split(input, "\n") {
		room := room.New(code)

		if room.Real {
			total += room.Sector
		}
	}

	return total
}

package day4

import (
	"strings"

	"strconv"

	"github.com/domdavis/adventofcode/2016/day4/room"
)

func Solution() string {
	return strconv.Itoa(sum(data))
}

func sum(input string) int {
	total := 0
	for _, code := range strings.Split(input, "\n") {
		room := room.New(code)

		if room.Real {
			total += room.Sector
		}
	}

	return total
}

Add part 1 of day 4 test


package main

import (
	"fmt"
	"strings"

	"github.com/bwmarrin/discordgo"
)

const commandPrefix = `$`

func messageCreateHandler(s *discordgo.Session, m *discordgo.MessageCreate) {

	user, _ := s.User("@me")
	if m.Author.ID != user.ID {
		s.ChannelMessageSend(botTestChannel, fmt.Sprintf("%s schrieb: %s", m.Author.Username, m.Content))

		if !strings.HasPrefix(m.Content, commandPrefix) {
			return
		}

		strAr := strings.Split(m.Content, " ")
		str := strings.Replace(strAr[0], commandPrefix, "", 1)

		switch str {
		case "help":
			s.ChannelMessageSend(m.ChannelID, "Hallo")
		}

	}
}

package main

import (
	"fmt"
	"strings"

	"github.com/bwmarrin/discordgo"
	"github.com/spf13/viper"
)

const commandPrefix = `$`

func messageCreateHandler(s *discordgo.Session, m *discordgo.MessageCreate) {

	user, _ := s.User("@me")
	if m.Author.ID != user.ID {
		if !strings.HasPrefix(m.Content, commandPrefix) {
			return
		}

		strAr := strings.Split(m.Content, " ")
		str := strings.Replace(strAr[0], commandPrefix, "", 1)
		ch, _ := s.Channel(m.ChannelID)
		if ch.Name == "regeln" {

			switch str {
			case "accept":
				rollen, _ := s.GuildRoles(ch.GuildID)
				for _, rl := range rollen {
					fmt.Println(rl.ID)
				}
				fmt.Println(s.GuildRoles(ch.GuildID))
				err := s.GuildMemberRoleAdd(ch.GuildID, m.Author.ID, viper.GetString("mitgliedRollenId"))
				fmt.Println(err)
			}
		}

		switch str {
		case "help":
			s.ChannelMessageSend(m.ChannelID, "Hallo")
		}

	}
}

Add check, if rules are accepted


package schedule

import "time"

type ConstantSchedule struct {
	Interval time.Duration
}

func Every(duration time.Duration) ConstantSchedule {
	if duration < time.Second {
		duration = time.Second
	}
	duration = duration - time.Duration(duration.Nanoseconds())%time.Second
	return ConstantSchedule{
		Interval: duration,
	}
}

func (c ConstantSchedule) Next(current time.Time) time.Time {
	return current.Add(c.Interval).Round(1 * time.Second)
}

package schedule

import "time"

type ConstantSchedule struct {
	Interval time.Duration
}

func Every(duration time.Duration) ConstantSchedule {
	if duration < time.Second {
		duration = time.Second
	}
	duration = duration - time.Duration(duration.Nanoseconds())%time.Second
	return ConstantSchedule{
		Interval: duration,
	}
}

func (c ConstantSchedule) Next(current time.Time) time.Time {
	return current.Add(c.Interval - time.Duration(current.Nanosecond())*time.Nanosecond)
}

Remove nanoseconds from Next's time in ConstantSchedule


package common

// Radical represents possible radical configurations of an atom.
type Radical uint8

const (
	RadicalNone Radical = 0
	RadicalSinglet
	RadicalDoublet
	RadicalTriplet
)

// BondType defines the possible types of bonds between a pair of
// atoms.
type BondType uint8

const (
	BondTypeNone BondType = 0
	BondTypeSingle
	BondTypeDouble
	BondTypeTriple
	BondTypeAltern // InChI says 'avoid by all means'!
)

package common

// The following `enum` definitions are in line with the corresponding
// ones in InChI 1.04 software.  A notable difference is that we DO
// NOT provide for specifying bond stereo with respect to the second
// atom in the pair.

// Radical represents possible radical configurations of an atom.
type Radical uint8

const (
	RadicalNone Radical = iota
	RadicalSinglet
	RadicalDoublet
	RadicalTriplet
)

// BondType defines the possible types of bonds between a pair of
// atoms.
type BondType uint8

const (
	BondTypeNone BondType = iota
	BondTypeSingle
	BondTypeDouble
	BondTypeTriple
	BondTypeAltern // InChI says 'avoid by all means'!
)

// BondStereo defines the possible stereo orientations of a given
// bond, when 2-D coordinates are given.
type BondStereo uint8

const (
	BondStereoNone         BondStereo = 0
	BondStereoUp           BondStereo = 1
	BondStereoEither       BondStereo = 4
	BondStereoDown         BondStereo = 6
	BondStereoDoubleEither BondStereo = 3
)

// StereoType specifies the nature of the origin of the stereo
// behaviour.
type StereoType uint8

const (
	StereoTypeNone StereoType = iota
	StereoTypeDoubleBond
	StereoTypeTetrahedral
	StereoTypeAllene
)

// StereoParity defines the possible stereo configurations, given a
// particular stereo centre (atom or bond).
type StereoParity uint8

const (
	StereoParityNone StereoParity = iota
	StereoParityOdd
	StereoParityEven
	StereoParityUnknown
	StereoParityUndefined
)

Complete the most important common enum definitions


package TLSHandshakeDecoder

import (
	_ "bytes"
	"errors"
	"fmt"
)

type TLSRecordLayer struct {
	contentType uint8
	version     uint16
	length      uint16
	Fragment    []byte
}

func DecodeRecord(p *TLSRecordLayer, data []byte) error {
	if len(data) < 5 {
		return errors.New("Payload too short to be a TLS packet.")
	}

	p.contentType = uint8(data[0])
	p.version = uint16(data[1])<<8 | uint16(data[2])
	p.length = uint16(data[3])<<8 | uint16(data[4])

	p.Fragment = make([]byte, p.length)
	l := copy(p.Fragment, data[5:5+p.length])
	if l < int(p.length) {
		return fmt.Errorf("Payload to short: copied %d, expected %d.", l, p.length)
	}

	return nil
}

package TLSHandshakeDecoder

import (
	_ "bytes"
	"errors"
	"fmt"
)

type TLSRecordLayer struct {
	ContentType uint8
	Version     uint16
	length      uint16
	Fragment    []byte
}

func DecodeRecord(p *TLSRecordLayer, data []byte) error {
	if len(data) < 5 {
		return errors.New("Payload too short to be a TLS packet.")
	}

	p.ContentType = uint8(data[0])
	p.Version = uint16(data[1])<<8 | uint16(data[2])
	p.length = uint16(data[3])<<8 | uint16(data[4])

	p.Fragment = make([]byte, p.length)
	l := copy(p.Fragment, data[5:5+p.length])
	if l < int(p.length) {
		return fmt.Errorf("Payload to short: copied %d, expected %d.", l, p.length)
	}

	return nil
}

Make attributes in struct more visible


package systemd_test

import (
	"fmt"

	"github.com/mistifyio/mistify/acomm"
	"github.com/mistifyio/mistify/providers/systemd"
)

func (s *sd) TestGet() {
	tests := []struct {
		name string
		err  string
	}{
		{"dbus.service", ""},
		{"doesnotexist.service", "unit not found"},
	}

	for _, test := range tests {
		args := &systemd.GetArgs{test.name}
		argsS := fmt.Sprintf("%+v", test)

		req, err := acomm.NewRequest("zfs-exists", "unix:///tmp/foobar", "", args, nil, nil)
		s.Require().NoError(err, argsS)

		res, streamURL, err := s.systemd.Get(req)
		s.Nil(streamURL, argsS)
		if test.err == "" {
			if !s.NoError(err, argsS) {
				continue
			}
			result, ok := res.(*systemd.GetResult)
			if !s.True(ok, argsS) {
				continue
			}
			if !s.NotNil(result.Unit, argsS) {
				continue
			}
			s.Equal(test.name, result.Unit.Name, argsS)
		} else {
			s.EqualError(err, test.err, argsS)
		}
	}
}

package systemd_test

import (
	"fmt"

	"github.com/mistifyio/mistify/acomm"
	"github.com/mistifyio/mistify/providers/systemd"
)

func (s *sd) TestGet() {
	tests := []struct {
		name string
		err  string
	}{
		{"", "missing arg: name"},
		{"doesnotexist.service", "unit not found"},
		{"dbus.service", ""},
	}

	for _, test := range tests {
		args := &systemd.GetArgs{test.name}
		argsS := fmt.Sprintf("%+v", test)

		req, err := acomm.NewRequest("zfs-exists", "unix:///tmp/foobar", "", args, nil, nil)
		s.Require().NoError(err, argsS)

		res, streamURL, err := s.systemd.Get(req)
		s.Nil(streamURL, argsS)
		if test.err == "" {
			if !s.NoError(err, argsS) {
				continue
			}
			result, ok := res.(*systemd.GetResult)
			if !s.True(ok, argsS) {
				continue
			}
			if !s.NotNil(result.Unit, argsS) {
				continue
			}
			s.Equal(test.name, result.Unit.Name, argsS)
		} else {
			s.EqualError(err, test.err, argsS)
		}
	}
}

Add missing arg test to Systemd Provider Get


package main

import (
	"github.com/itsankoff/gotcha/client"
	"github.com/itsankoff/gotcha/common"
	"log"
	"time"
)

func main() {
	input := make(chan *common.Message)
	ws := client.NewWebSocketClient()
	ws.SetReceiver(input)

	c := client.New(ws)
	err := c.Connect("ws://127.0.0.1:9000/websocket")
	log.Println("connected", err)
	userId, err := c.Register("pesho", "123")
	log.Println("registered", err)

	err = c.Authenticate(userId, "123")
	log.Println("authenticated", err)

	time.Sleep(10 * time.Second)
}

package main

import (
	"github.com/itsankoff/gotcha/client"
	"log"
	"time"
)

func main() {
	ws := client.NewWebSocketClient()
	c := client.New(ws)
	err := c.Connect("ws://127.0.0.1:9000/websocket")
	log.Println("connected", err)
	userId, err := c.Register("pesho", "123")
	log.Println("registered", err)

	err = c.Authenticate(userId, "123")
	log.Println("authenticated", err)

	time.Sleep(10 * time.Second)
}

Remove redundant input channel for websocket transport


package interceptor

import (
	"testing"

	"github.com/stretchr/testify/require"
)

func TestSanitizeIPTablesOutput(t *testing.T) {
	require.Equal(t, "x  y", sanitizeIPTablesOutput(([]byte)("x\n\ty")))

	as := make([]byte, 1000)
	for i := range as {
		as[i] = 'a'
	}
	require.Equal(t, string(as[:200]), sanitizeIPTablesOutput(as))
}

package interceptor

import (
	"strings"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestSanitizeIPTablesOutput(t *testing.T) {
	require.Equal(t, "x  y", sanitizeIPTablesOutput(([]byte)("x\n\ty")))

	as := strings.Repeat("a", 1000)
	require.Equal(t, as[:200], sanitizeIPTablesOutput(([]byte)(as)))
}

Use strings package to avoid a loop


package options

import "time"

const DEFAULT_MAX_RETRY_ATTEMPTS = 3
const DEFAULT_SLEEP = 5 * time.Second

// List of recurring transient errors encountered when calling terraform
// If any of these match, we'll retry the command
var RETRYABLE_ERRORS = []string{
	"(?s).*Failed to load state.*tcp.*timeout.*",
	"(?s).*Failed to load backend.*TLS handshake timeout.*",
	"(?s).*Creating metric alarm failed.*request to update this alarm is in progress.*",
	"(?s).*Error installing provider.*TLS handshake timeout.*",
	"(?s).*Error configuring the backend.*TLS handshake timeout.*",
	"(?s).*Error installing provider.*tcp.*timeout.*",
}

package options

import "time"

const DEFAULT_MAX_RETRY_ATTEMPTS = 3
const DEFAULT_SLEEP = 5 * time.Second

// List of recurring transient errors encountered when calling terraform
// If any of these match, we'll retry the command
var RETRYABLE_ERRORS = []string{
	"(?s).*Failed to load state.*tcp.*timeout.*",
	"(?s).*Failed to load backend.*TLS handshake timeout.*",
	"(?s).*Creating metric alarm failed.*request to update this alarm is in progress.*",
	"(?s).*Error installing provider.*TLS handshake timeout.*",
	"(?s).*Error configuring the backend.*TLS handshake timeout.*",
	"(?s).*Error installing provider.*tcp.*timeout.*",
	"(?s).*Error installing provider.*tcp.*timeout.*",
	"NoSuchBucket: The specified bucket does not exist",
}

Add NoSuchBucket to retryable errors


//go:build js

package syscall

import (
	"syscall/js"
)

// fsCall emulates a file system-related syscall via a corresponding NodeJS fs
// API.
//
// This version is similar to the upstream, but it gracefully handles missing fs
// methods (allowing for smaller prelude) and removes a workaround for an
// obsolete NodeJS version.
func fsCall(name string, args ...interface{}) (js.Value, error) {
	type callResult struct {
		val js.Value
		err error
	}

	c := make(chan callResult, 1)
	f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
		var res callResult

		if len(args) >= 1 {
			if jsErr := args[0]; !jsErr.IsUndefined() && !jsErr.IsNull() {
				res.err = mapJSError(jsErr)
			}
		}

		res.val = js.Undefined()
		if len(args) >= 2 {
			res.val = args[1]
		}

		c <- res
		return nil
	})
	defer f.Release()
	if jsFS.Get(name).IsUndefined() {
		return js.Undefined(), ENOSYS
	}
	jsFS.Call(name, append(args, f)...)
	res := <-c
	return res.val, res.err
}

//go:build js

package syscall

import (
	"syscall/js"
)

// fsCall emulates a file system-related syscall via a corresponding NodeJS fs
// API.
//
// This version is similar to the upstream, but it gracefully handles missing fs
// methods (allowing for smaller prelude) and removes a workaround for an
// obsolete NodeJS version.
func fsCall(name string, args ...interface{}) (js.Value, error) {
	type callResult struct {
		val js.Value
		err error
	}

	c := make(chan callResult, 1)
	f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
		var res callResult

		// Check that args has at least one element, then check both IsUndefined() and IsNull() on
		// that element. In some situations, BrowserFS calls the callback without arguments or with
		// an undefined argument: https://github.com/gopherjs/gopherjs/pull/1118
		if len(args) >= 1 {
			if jsErr := args[0]; !jsErr.IsUndefined() && !jsErr.IsNull() {
				res.err = mapJSError(jsErr)
			}
		}

		res.val = js.Undefined()
		if len(args) >= 2 {
			res.val = args[1]
		}

		c <- res
		return nil
	})
	defer f.Release()
	if jsFS.Get(name).IsUndefined() {
		return js.Undefined(), ENOSYS
	}
	jsFS.Call(name, append(args, f)...)
	res := <-c
	return res.val, res.err
}

Add a comment to explain fsCall() safety checks


package gof1

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

// GetRaces queries the Ergast api and returns the details of every completed race in the F1 season specified
func GetRaces(year int) []Race {
	url := fmt.Sprintf("http://ergast.com/api/f1/%v/results.json?limit=1000&offset=0", year)
	fmt.Println(url)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Println("NewRequest:", err)
		return nil
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("Do:", err)
		return nil
	}
	defer resp.Body.Close()

	var result F1

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		log.Println(err)
	}

	return result.MRData.RaceTable.Races
}

package gof1

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

const baseUrl = "http://ergast.com/api/f1/"

func GetRacesInSeason(year int) []Race {
	url := fmt.Sprintf("%s%v/schedule.json", baseUrl, year)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Println("NewRequest:", err)
		return nil
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("Do:", err)
		return nil
	}
	defer resp.Body.Close()

	var result F1

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		log.Println(err)
	}

	return result.MRData.RaceTable.Races
}

// GetRacesWithResults queries the Ergast api and returns the details of every completed race in the F1 season specified
func GetRacesWithResults(year int) []Race {
	url := fmt.Sprintf("%s%v/results.json", baseUrl, year)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Println("NewRequest:", err)
		return nil
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("Do:", err)
		return nil
	}
	defer resp.Body.Close()

	var result F1

	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		log.Println(err)
	}

	return result.MRData.RaceTable.Races
}

Add call to pull schedule


package agent

import (
	"errors"
	"fmt"
	"time"

	"github.com/AdRoll/goamz/aws"
	"github.com/AdRoll/goamz/ec2"
)

type EC2Tags struct {
}

func (e EC2Tags) Get() (map[string]string, error) {
	tags := make(map[string]string)

	// Passing blank values here instructs the AWS library to look at the
	// current instances meta data for the security credentials.
	auth, err := aws.GetAuth("", "", "", time.Time{})
	if err != nil {
		return tags, errors.New(fmt.Sprintf("Error creating AWS authentication: %s", err.Error()))
	}

	// Find the current region and create a new EC2 connection
	region := aws.GetRegion(aws.InstanceRegion())
	ec2Client := ec2.New(auth, region)

	// Filter by the current machines instance-id
	filter := ec2.NewFilter()
	filter.Add("resource-id", aws.InstanceId())

	// Describe the tags for the current instance
	resp, err := ec2Client.DescribeTags(filter)
	if err != nil {
		return tags, errors.New(fmt.Sprintf("Error downloading tags: %s", err.Error()))
	}

	// Collect the tags
	for _, tag := range resp.Tags {
		tags[tag.Key] = tag.Value
	}

	// We set this manually, it's not a standard tag
	tags["aws:instance-id"] = aws.InstanceId()

	return tags, nil
}

package agent

import (
	"errors"
	"fmt"
	"time"

	"github.com/AdRoll/goamz/aws"
	"github.com/AdRoll/goamz/ec2"
)

type EC2Tags struct {
}

func (e EC2Tags) Get() (map[string]string, error) {
	tags := make(map[string]string)

	// Passing blank values here instructs the AWS library to look at the
	// current instances meta data for the security credentials.
	auth, err := aws.GetAuth("", "", "", time.Time{})
	if err != nil {
		return tags, errors.New(fmt.Sprintf("Error creating AWS authentication: %s", err.Error()))
	}

	// Find the current region and create a new EC2 connection
	region := aws.GetRegion(aws.InstanceRegion())
	ec2Client := ec2.New(auth, region)

	// Filter by the current machines instance-id
	filter := ec2.NewFilter()
	filter.Add("resource-id", aws.InstanceId())

	// Describe the tags for the current instance
	resp, err := ec2Client.DescribeTags(filter)
	if err != nil {
		return tags, errors.New(fmt.Sprintf("Error downloading tags: %s", err.Error()))
	}

	// Collect the tags
	for _, tag := range resp.Tags {
		tags[tag.Key] = tag.Value
	}

	return tags, nil
}

Revert "Add the EC2 instance ID to the automatic metadata"


package main

import (
	"github.com/cburkert/go-statusbar/reporters/battery"
	"github.com/cburkert/go-statusbar/reporters/volume"
)

func main() {
	statusBar := NewStatusBar(" | ")
	statusBar.AddReporter(volume.NewVolumeReporter())
	statusBar.AddReporter(battery.NewPowerReporter("/sys/class/power_supply/"))
	statusBar.AddReporter(NewDateReporter("Mon 02 Ý 15:04"))
	statusBar.Run()
}

package main

import (
	"github.com/cburkert/go-statusbar/reporters/battery"
	"github.com/cburkert/go-statusbar/reporters/volume"
)

func main() {
	statusBar := NewStatusBar(" ▕▏ ")
	statusBar.AddReporter(volume.NewVolumeReporter())
	statusBar.AddReporter(battery.NewPowerReporter("/sys/class/power_supply/"))
	statusBar.AddReporter(NewDateReporter("Mon 02 ◾ 15:04"))
	statusBar.Run()
}

Use more appealing separator characters


package flow

import (
	"testing"
)

type doubleOnce struct {
	In <-chan int
	Out chan<- int
}

func (c *doubleOnce) Process() {
	i := <-c.In
	c.Out <- 2*i
}

func TestSimpleComponent(t *testing.T) {
	in := make(chan int)
	out := make(chan int)
	c := &doubleOnce{
		in,
		out,
	}

	wait := Run(c)

	in <- 12
	res := <-out

	if res != 24 {
		t.Errorf("%d != %d", res, 24)
	}

	<-wait
}

package flow

import (
	"testing"
)

// This component interface is common for many test cases
type intInAndOut struct {
	In <-chan int
	Out chan<- int
}

type doubleOnce intInAndOut

func (c *doubleOnce) Process() {
	i := <-c.In
	c.Out <- 2*i
}

// Test a simple component that runs only once
func TestSimpleComponent(t *testing.T) {
	in := make(chan int)
	out := make(chan int)
	c := &doubleOnce{
		in,
		out,
	}

	wait := Run(c)

	in <- 12
	res := <-out

	if res != 24 {
		t.Errorf("%d != %d", res, 24)
	}

	<-wait
}

type doubler intInAndOut

func (c *doubler) Process() {
	for i := range c.In {
		c.Out <- 2*i
	}
}

func TestSimpleLongRunningComponent(t *testing.T) {
	data := map[int]int{
		12: 24,
		7: 14,
		400: 800,
	}
	in := make(chan int)
	out := make(chan int)
	c := &doubler{
		in,
		out,
	}

	wait := Run(c)

	for src, expected := range data {
		in <- src
		actual := <- out

		if actual != expected {
			t.Errorf("%d != %d", actual, expected)
		}
	}

	// We have to close input for the process to finish
	close(in)
	<-wait
}

Add test for long running process


package gitbook

import (
	"github.com/GitbookIO/go-gitbook-api/api"
	"github.com/GitbookIO/go-gitbook-api/client"
)

type API struct {
	// Authentication API client
	Account *api.Account
	// Individual book API client
	Book *api.Book
	// Book listing API client
	Books *api.Books
	// User API client
	User *api.User

	// Internal client
	Client *client.Client
}

type APIOptions client.ClientOptions

func NewAPI(opts APIOptions) *API {
	c := client.NewClient(client.ClientOptions(opts))
	return NewAPIFromClient(c)
}

func NewAPIFromClient(c *client.Client) *API {
	return &API{
		Account: &api.Account{c},
		Book:    &api.Book{c},
		Books:   &api.Books{c},
		User:    &api.User{c},
		Client:  c,
	}
}

func (a *API) Fork(opts APIOptions) *API {
	forkedClient := a.Client.Fork(client.ClientOptions(opts))
	return NewAPIFromClient(forkedClient)
}

func (a *API) AuthFork(username, password string) *API {
	forkedClient := a.Client.AuthFork(username, password)
	return NewAPIFromClient(forkedClient)
}

package gitbook

import (
	"github.com/GitbookIO/go-gitbook-api/api"
	"github.com/GitbookIO/go-gitbook-api/client"
)

type API struct {
	// Authentication API client
	Account *api.Account
	// Individual book API client
	Book *api.Book
	// Book listing API client
	Books *api.Books
	// Builds API client
	Builds *api.Builds
	// User API client
	User *api.User

	// Internal client
	Client *client.Client
}

type APIOptions client.ClientOptions

func NewAPI(opts APIOptions) *API {
	c := client.NewClient(client.ClientOptions(opts))
	return NewAPIFromClient(c)
}

func NewAPIFromClient(c *client.Client) *API {
	return &API{
		Account: &api.Account{c},
		Book:    &api.Book{c},
		Books:   &api.Books{c},
		Books:   &api.Builds{c},
		User:    &api.User{c},
		Client:  c,
	}
}

func (a *API) Fork(opts APIOptions) *API {
	forkedClient := a.Client.Fork(client.ClientOptions(opts))
	return NewAPIFromClient(forkedClient)
}

func (a *API) AuthFork(username, password string) *API {
	forkedClient := a.Client.AuthFork(username, password)
	return NewAPIFromClient(forkedClient)
}

Add Builds API to main API client


package fibgo

var cache = make(map[int]int)

// N return fibonacci number on N position
// N should start from 0, otherwise panic will raised
func N(n int) int {
	if n < 0 {
		panic("n should not less than 0")
	}

	v, ok := cache[n]
	if ok {
		return v
	}

	if n < 2 {
		cache[n] = n
		return n
	}

	v = N(n-2) + N(n-1)
	cache[n] = v
	return v
}

// Seq will generate the fibonacci sequence
func Seq(length int) []int {
	out := make([]int, length)
	for i := 0; i < length; i++ {
		out[i] = N(i)
	}
	return out
}

package fibgo

var cache = make(map[int]int)

// TODO uudashr: pass in cache in order to respect the pure function concept

// N return fibonacci number on N position
// N should start from 0, otherwise panic will raised
func N(n int) int {
	if n < 0 {
		panic("n should not less than 0")
	}

	v, ok := cache[n]
	if ok {
		return v
	}

	if n < 2 {
		cache[n] = n
		return n
	}

	v = N(n-2) + N(n-1)
	cache[n] = v
	return v
}

// Seq will generate the fibonacci sequence
func Seq(length int) []int {
	out := make([]int, length)
	for i := 0; i < length; i++ {
		out[i] = N(i)
	}
	return out
}

Add notes to improve the cacheable design


package db

import (
	"github.com/garyburd/redigo/redis"
)

// Save takes a key (struct used as template for all data containers to ease the managing of the DB)
// and generates an unique key in order to add the record to the DB.
func Save(key string, value []byte) error {
	defer mutex.Unlock()
	mutex.Lock()

	_, err := connection.Do("SET", key, value)
	return err
}

// Get is used to pull information from the DB in order to be used by the server.
// Get operates as read only function and does not modify the data in the DB.
func Get(key string) ([]byte, error) {
	defer mutex.Unlock()
	mutex.Lock()

	return redis.Bytes(connection.Do("GET", key))
}

// GetList operates as Get, but instead of an unique key it takes a patern in order to return
// a list of keys that reflect the entered patern.
func GetList(pattern string) ([]interface{}, error) {
	defer mutex.Unlock()
	mutex.Lock()

	return redis.Values(connection.Do("KEYS", pattern))
}

// I think Delete speaks for itself but still. This function is used to remove entrys from the DB.
func Delete(key string) error {
	defer mutex.Unlock()
	mutex.Lock()

	_, err := connection.Do("DEL", key)
	return err
}

package db

import (
	"github.com/garyburd/redigo/redis"
)

// Save takes a key (struct used as template for all data containers to ease the managing of the DB)
// and generates an unique key in order to add the record to the DB.
func Save(key string, value []byte) error {
	conn := pool.Get()
	defer conn.Close()

	_, err := conn.Do("SET", key, value)
	return err
}

// Get is used to pull information from the DB in order to be used by the server.
// Get operates as read only function and does not modify the data in the DB.
func Get(key string) ([]byte, error) {
	conn := pool.Get()
	defer conn.Close()

	return redis.Bytes(conn.Do("GET", key))
}

// GetList operates as Get, but instead of an unique key it takes a patern in order to return
// a list of keys that reflect the entered patern.
func GetList(pattern string) ([]interface{}, error) {
	conn := pool.Get()
	defer conn.Close()

	return redis.Values(conn.Do("KEYS", pattern))
}

// I think Delete speaks for itself but still. This function is used to remove entrys from the DB.
func Delete(key string) error {
	conn := pool.Get()
	defer conn.Close()

	_, err := conn.Do("DEL", key)
	return err
}

Use the pool instead the database connection


package api

import "google.golang.org/grpc"

// DialOptions are the gRPC dial options for discovery calls
// TODO: disable insecure connections
var DialOptions = []grpc.DialOption{
	grpc.WithInsecure(),
}

package api

import (
	"time"

	"google.golang.org/grpc"
)

// DialOptions are the gRPC dial options for discovery calls
// TODO: disable insecure connections
var DialOptions = []grpc.DialOption{
	grpc.WithInsecure(),
	grpc.WithTimeout(2 * time.Second),
}

Set timeout on gRPC connect


package cloudwatch

import (
	"math/rand"
	"testing"
	"time"

	"github.com/Pallinder/go-randomdata"
	"github.com/gliderlabs/logspout/router"
)

const NumMessages = 250000

func TestCloudWatchAdapter(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode.")
	}

	route := &router.Route{Address: "logspout-cloudwatch"}
	messages := make(chan *router.Message)

	adapter, err := NewAdapter(route)
	if err != nil {
		t.Error(err)
		return
	}

	go adapter.Stream(messages)
	for i := 0; i < NumMessages; i++ {
		messages <- createMessage()
	}

	close(messages)
}

func createMessage() *router.Message {
	data := ""
	timestamp := time.Now()
	random := rand.Intn(100)

	if random != 0 {
		data = randomdata.Paragraph()
	}

	return &router.Message{Data: data, Time: timestamp}
}

package cloudwatch

import (
	"math/rand"
	"testing"
	"time"

	"github.com/Pallinder/go-randomdata"
	"github.com/gliderlabs/logspout/router"
)

const NumMessages = 1000000

func TestCloudWatchAdapter(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode.")
	}

	route := &router.Route{Address: "logspout-cloudwatch"}
	messages := make(chan *router.Message)

	adapter, err := NewAdapter(route)
	if err != nil {
		t.Error(err)
		return
	}

	go adapter.Stream(messages)
	for i := 0; i < NumMessages; i++ {
		messages <- createMessage()
	}

	close(messages)
}

func createMessage() *router.Message {
	data := ""
	timestamp := time.Now()
	random := rand.Intn(100)

	if random != 0 {
		data = randomdata.Paragraph()
	}

	return &router.Message{Data: data, Time: timestamp}
}

Swap back to 1MM messages.


package main

import (
	"flag"
	"net"

	"github.com/hnakamur/rdirsync"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/grpclog"
)

func main() {
	var enableTLS bool
	flag.BoolVar(&enableTLS, "enable-tls", false, "enable TLS")
	var certFile string
	flag.StringVar(&certFile, "cert-file", "../../ssl/server/server.crt", "TLS cert file")
	var keyFile string
	flag.StringVar(&keyFile, "key-file", "../../ssl/server/server.key", "TLS key file")
	var addr string
	flag.StringVar(&addr, "addr", ":10000", "server listen address")
	flag.Parse()

	lis, err := net.Listen("tcp", addr)
	if err != nil {
		grpclog.Fatal(err)
	}

	var opts []grpc.ServerOption
	if enableTLS {
		creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
		if err != nil {
			grpclog.Fatalf("Failed to generate credentials %v", err)
		}
		opts = []grpc.ServerOption{grpc.Creds(creds)}
	}
	grpcServer := grpc.NewServer(opts...)
	rdirsync.RegisterNewRDirSyncServer(grpcServer)
	grpcServer.Serve(lis)
}

package main

import (
	"flag"
	"net"

	"github.com/hnakamur/rdirsync"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/grpclog"
)

func main() {
	var enableTLS bool
	flag.BoolVar(&enableTLS, "enable-tls", false, "enable TLS")
	var certFile string
	flag.StringVar(&certFile, "cert-file", "server.crt", "TLS cert file")
	var keyFile string
	flag.StringVar(&keyFile, "key-file", "server.key", "TLS key file")
	var addr string
	flag.StringVar(&addr, "addr", ":10000", "server listen address")
	flag.Parse()

	lis, err := net.Listen("tcp", addr)
	if err != nil {
		grpclog.Fatal(err)
	}

	var opts []grpc.ServerOption
	if enableTLS {
		creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
		if err != nil {
			grpclog.Fatalf("Failed to generate credentials %v", err)
		}
		opts = []grpc.ServerOption{grpc.Creds(creds)}
	}
	grpcServer := grpc.NewServer(opts...)
	rdirsync.RegisterNewRDirSyncServer(grpcServer)
	grpcServer.Serve(lis)
}

Change server default option values


package router

import(
  "github.com/ricallinson/forgery"
  "github.com/spacedock-io/registry/images"
  "github.com/spacedock-io/registry/repositories"
  "github.com/spacedock-io/registry/auth"
)

func Routes(server *f.Server) {
  /* Home page */
  server.Get("/", func(req *f.Request, res *f.Response, next func()) {
    res.Send("docker-registry server")
  })

  /* Ping */
  server.Get("/v1/_ping", func(req *f.Request, res *f.Response, next func()) {
    res.Send("true")
  })

  /* Images Routes */
  server.Get("/v1/images/:id/ancestry", auth.Secure(images.GetAncestry))
  server.Get("/v1/images/:id/layer", auth.Secure(images.GetLayer))
  server.Put("/v1/images/:id/layer", auth.Secure(images.GetLayer))
  server.Get("/v1/images/:id/json", auth.Secure(images.GetJson))
  server.Put("/v1/images/:id/json", auth.Secure(images.PutJson))

  server.Get("/v1/repositories/:namespace/:repo/tags", auth.Secure(repositories.GetTags))
  server.Get("/v1/repositories/:namespace/:repo/tags/:tag", auth.Secure(repositories.GetTag))
  server.Put("/v1/repositories/:namespace/:repo/tags/:tag", auth.Secure(repositories.CreateTag))
}

package router

import(
  "github.com/ricallinson/forgery"
  "github.com/spacedock-io/registry/images"
  "github.com/spacedock-io/registry/repositories"
  "github.com/spacedock-io/registry/auth"
)

func Routes(server *f.Server) {
  /* Home page */
  server.Get("/", func(req *f.Request, res *f.Response, next func()) {
    res.Send("docker-registry server")
  })

  /* Ping */
  server.Get("/v1/_ping", func(req *f.Request, res *f.Response, next func()) {
    res.Send("true")
  })

  /* Images Routes */
  server.Get("/v1/images/:id/ancestry", auth.Secure(images.GetAncestry))
  server.Get("/v1/images/:id/layer", auth.Secure(images.GetLayer))
  server.Put("/v1/images/:id/layer", auth.Secure(images.PutLayer))
  server.Get("/v1/images/:id/json", auth.Secure(images.GetJson))
  server.Put("/v1/images/:id/json", auth.Secure(images.PutJson))

  server.Get("/v1/repositories/:namespace/:repo/tags", auth.Secure(repositories.GetTags))
  server.Get("/v1/repositories/:namespace/:repo/tags/:tag", auth.Secure(repositories.GetTag))
  server.Put("/v1/repositories/:namespace/:repo/tags/:tag", auth.Secure(repositories.CreateTag))
}

Fix function name for PUT .../layer


package routes

import (
	"encoding/json"
	"net/http"
)

type Arguments map[interface{}]interface{}

type Handler func(*http.Request, Arguments) (int, interface{})

type IntermediateHandler func(http.ResponseWriter, *http.Request, Arguments) (int, interface{})

type Decorator interface {
	Decorate(IntermediateHandler) IntermediateHandler
}

type ErrorBody struct {
	Error string `json:"error"`
}

func Register(pattern string, handler Handler, decorators ...Decorator) error {
	stage := baseIntermediate(handler)
	l := len(decorators) - 1
	for i := range decorators {
		d := decorators[l-i]
		stage = d.Decorate(stage)
	}
	http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
		arguments := make(Arguments)
		status, output := stage(w, r, arguments)
		w.WriteHeader(status)
		json.NewEncoder(w).Encode(output)
	})
	return nil
}

func baseIntermediate(handler Handler) IntermediateHandler {
	return func(w http.ResponseWriter, r *http.Request, a Arguments) (int, interface{}) {
		return handler(r, a)
	}
}

package routes

import (
	"encoding/json"
	"net/http"
)

var registeredHandlers = make([]RegisteredHandler, 0x40)

type RegisteredHandler struct {
	Pattern string
	Handler http.HandlerFunc
}

type Arguments map[interface{}]interface{}

type Handler func(*http.Request, Arguments) (int, interface{})

type IntermediateHandler func(http.ResponseWriter, *http.Request, Arguments) (int, interface{})

type Decorator interface {
	Decorate(IntermediateHandler) IntermediateHandler
}

type ErrorBody struct {
	Error string `json:"error"`
}

func Register(pattern string, handler Handler, decorators ...Decorator) {
	stage := baseIntermediate(handler)
	l := len(decorators) - 1
	for i := range decorators {
		d := decorators[l-i]
		stage = d.Decorate(stage)
	}
	registeredHandlers = append(registeredHandlers, RegisteredHandler{
		pattern,
		func(w http.ResponseWriter, r *http.Request) {
			arguments := make(Arguments)
			status, output := stage(w, r, arguments)
			w.WriteHeader(status)
			json.NewEncoder(w).Encode(output)
		},
	})
}

func baseIntermediate(handler Handler) IntermediateHandler {
	return func(w http.ResponseWriter, r *http.Request, a Arguments) (int, interface{}) {
		return handler(r, a)
	}
}

Store registered route handlers in a slice.


// Package reflect adds some useful features to the standard reflect package.
package reflect

import "reflect"

// IsDefined checks if the value is different from nil looking further to its
// contents.
func IsDefined(value interface{}) bool {
	if value == nil {
		return false
	}

	v := reflect.ValueOf(value)
	switch v.Kind() {
	case reflect.Ptr, reflect.Interface:
		if canIsNil(v.Elem()) {
			v = v.Elem()
		}
	}

	if canIsNil(v) {
		return !v.IsNil()
	}

	return true
}

func canIsNil(value reflect.Value) bool {
	switch value.Kind() {
	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice:
		return true
	}

	return false
}

// Package reflect adds some useful features to the standard reflect package.
package reflect

import "reflect"

// IsDefined checks if the value is different from nil looking further to its
// contents.
func IsDefined(value interface{}) bool {
	if value == nil {
		return false
	}

	return isDefined(reflect.ValueOf(value))
}

func isDefined(value reflect.Value) bool {
	switch value.Kind() {
	case reflect.Ptr, reflect.Interface:
		if canIsNil(value.Elem()) {
			return isDefined(value.Elem())
		}
	}

	if canIsNil(value) {
		return !value.IsNil()
	}

	return true
}

func canIsNil(value reflect.Value) bool {
	switch value.Kind() {
	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice:
		return true
	}

	return false
}

Allow chaining multiple interfaces or pointers


package sentry

import (
	"errors"
	"fmt"
	"net/http"
	"runtime/debug"

	"github.com/getsentry/raven-go"
	"github.com/gin-gonic/gin"
)

func Recovery(client *raven.Client, onlyCrashes bool) gin.HandlerFunc {

	return func(c *gin.Context) {
		defer func() {
			flags := map[string]string{
				"endpoint": c.Request.RequestURI,
			}
			if rval := recover(); rval != nil {
				debug.PrintStack()
				rvalStr := fmt.Sprint(rval)
				packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)))
				client.Capture(packet, flags)
				c.AbortWithStatus(http.StatusInternalServerError)
			}
			if !onlyCrashes {
				for _, item := range c.Errors {
					packet := raven.NewPacket(item.Error(), &raven.Message{
						Message: item.Error(),
						Params:  []interface{}{item.Meta},
					})
					client.Capture(packet, flags)
				}
			}
		}()

		c.Next()
	}
}

package sentry

import (
	"errors"
	"fmt"
	"net/http"
	"runtime/debug"

	"github.com/getsentry/raven-go"
	"github.com/gin-gonic/gin"
)

func Recovery(client *raven.Client, onlyCrashes bool) gin.HandlerFunc {

	return func(c *gin.Context) {
		defer func() {
			flags := map[string]string{
				"endpoint": c.Request.RequestURI,
			}
			if rval := recover(); rval != nil {
				debug.PrintStack()
				rvalStr := fmt.Sprint(rval)
				packet := raven.NewPacket(rvalStr,
					raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)),
					raven.NewHttp(c.Request))
				client.Capture(packet, flags)
				c.AbortWithStatus(http.StatusInternalServerError)
			}
			if !onlyCrashes {
				for _, item := range c.Errors {
					packet := raven.NewPacket(item.Error(), &raven.Message{
						Message: item.Error(),
						Params:  []interface{}{item.Meta},
					})
					client.Capture(packet, flags)
				}
			}
		}()

		c.Next()
	}
}

Add NewHttp to the list of captured interfaces


package model

import (
	"errors"
	"time"
)

// UserInfo holds the parameters returned by the backends.
// This information will be serialized to build the JWT token contents.
type UserInfo struct {
	Sub     string `json:"sub"`
	Picture string `json:"picture,omitempty"`
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
	Origin  string `json:"origin,omitempty"`
	Expiry  int64  `json:"exp,omitempty"`
}

// Valid lets us use the user info as Claim for jwt-go.
// It checks the token expiry.
func (u UserInfo) Valid() error {
	if u.Expiry < time.Now().Unix() {
		return errors.New("token expired")
	}
	return nil
}

package model

import (
	"errors"
	"time"
)

// UserInfo holds the parameters returned by the backends.
// This information will be serialized to build the JWT token contents.
type UserInfo struct {
	Sub       string `json:"sub"`
	Picture   string `json:"picture,omitempty"`
	Name      string `json:"name,omitempty"`
	Email     string `json:"email,omitempty"`
	Origin    string `json:"origin,omitempty"`
	Expiry    int64  `json:"exp,omitempty"`
	Refreshes int    `json:"refs,omitempty"`
}

// Valid lets us use the user info as Claim for jwt-go.
// It checks the token expiry.
func (u UserInfo) Valid() error {
	if u.Expiry < time.Now().Unix() {
		return errors.New("token expired")
	}
	return nil
}

Add jwt refresh count to jwt payload model


package cli

import (
	"github.com/qiniu/log"
	"qshell"
	"strconv"
)

func QiniuUpload(cmd string, params ...string) {
	if len(params) == 1 || len(params) == 2 {
		var uploadConfigFile string
		var threadCount int64
		var err error
		if len(params) == 2 {
			threadCount, err = strconv.ParseInt(params[0], 10, 64)
			if err != nil {
				log.Error("Invalid <ThreadCount> value,", params[0])
				return
			}
			uploadConfigFile = params[1]
		} else {
			uploadConfigFile = params[0]
		}
		if threadCount < qshell.MIN_UPLOAD_THREAD_COUNT ||
			threadCount > qshell.MAX_UPLOAD_THREAD_COUNT {
			log.Warn("<ThreadCount> can only between 1 and 100")
			threadCount = qshell.MIN_UPLOAD_THREAD_COUNT
		}
		qshell.QiniuUpload(int(threadCount), uploadConfigFile)
	} else {
		CmdHelp(cmd)
	}
}

package cli

import (
	"github.com/qiniu/log"
	"qshell"
	"strconv"
)

func QiniuUpload(cmd string, params ...string) {
	if len(params) == 1 || len(params) == 2 {
		var uploadConfigFile string
		var threadCount int64
		var err error
		if len(params) == 2 {
			threadCount, err = strconv.ParseInt(params[0], 10, 64)
			if err != nil {
				log.Error("Invalid <ThreadCount> value,", params[0])
				return
			}
			uploadConfigFile = params[1]
		} else {
			uploadConfigFile = params[0]
		}
		if threadCount < qshell.MIN_UPLOAD_THREAD_COUNT ||
			threadCount > qshell.MAX_UPLOAD_THREAD_COUNT {
			log.Info("You can set <ThreadCount> value between 1 and 100 to improve speed")
			threadCount = qshell.MIN_UPLOAD_THREAD_COUNT
		}
		qshell.QiniuUpload(int(threadCount), uploadConfigFile)
	} else {
		CmdHelp(cmd)
	}
}

Update warn to info to make customer happy


package main

import (
	"bytes"
	"fmt"
	"github.com/alanctgardner/gogen-avro/example/avro"
)

// Use a go:generate directive to build the Go structs for `example.avsc`
// Source files will be in a package called `avro`

//go:generate $GOPATH/bin/gogen-avro ./avro example.avsc

func main() {
	// Create a new DemoSchema struct
	demoStruct := &avro.DemoSchema{
		IntField:    1,
		DoubleField: 2.3,
		StringField: "A string",
		BoolField:   true,
		BytesField:  []byte{1, 2, 3, 4},
	}

	// Serialize the struct to a byte buffer
	var buf bytes.Buffer
	fmt.Printf("Serializing struct: %#v\n", demoStruct)
	demoStruct.Serialize(&buf)

	// Deserialize the byte buffer back into a struct
	newDemoStruct, err := avro.DeserializeDemoSchema(&buf)
	if err != nil {
		fmt.Printf("Error deserializing struct: %v\n", err)
		return
	}
	fmt.Printf("Deserialized struct: %#v\n", newDemoStruct)
}

package main

import (
	"bytes"
	"fmt"
	"github.com/alanctgardner/gogen-avro/example/avro"
)

// Use a go:generate directive to build the Go structs for `example.avsc`
// Source files will be in a package called `avro`

//go:generate mkdir -p ./avro
//go:generate $GOPATH/bin/gogen-avro ./avro example.avsc

func main() {
	// Create a new DemoSchema struct
	demoStruct := &avro.DemoSchema{
		IntField:    1,
		DoubleField: 2.3,
		StringField: "A string",
		BoolField:   true,
		BytesField:  []byte{1, 2, 3, 4},
	}

	// Serialize the struct to a byte buffer
	var buf bytes.Buffer
	fmt.Printf("Serializing struct: %#v\n", demoStruct)
	demoStruct.Serialize(&buf)

	// Deserialize the byte buffer back into a struct
	newDemoStruct, err := avro.DeserializeDemoSchema(&buf)
	if err != nil {
		fmt.Printf("Error deserializing struct: %v\n", err)
		return
	}
	fmt.Printf("Deserialized struct: %#v\n", newDemoStruct)
}

Add mkdir to go generate


package main

import (
	"fmt"
	"github.com/s3git/s3git-go"
	"strings"
)

func main() {
	repo, _ := s3git.InitRepository(".")

	repo.Add(strings.NewReader("hello s3git"))

	repo.Commit("Initial commit")

	list, _ := repo.List("")

	for l := range list {
		fmt.Println(l)
	}

	commits, _ := repo.ListCommits("")

	for commit := range commits {
		fmt.Println(commit)
	}
}

package main

import (
	"fmt"
	"github.com/s3git/s3git-go"
	"strings"
)

func main() {
	repo, _ := s3git.InitRepository(".")

	repo.Add(strings.NewReader("hello s3git"))

	repo.Commit("Initial commit")

	commits, _ := repo.ListCommits("")

	for commit := range commits {
		fmt.Println(commit)
	}
}

Move list to clone example


package cues

import (
	"errors"
)

type CueList struct {
	Cues []Cue
}

func (cueList CueList) ConvertCues() (string, error) {
	var err error
	ret := "Ident 3:0\r\nClear Cues\r\n"

	if cueList.Cues != nil {
		for i := range cueList.Cues {
			line, _ := cueList.Cues[i].ConvertToAscii()
			ret += line
		} //end iterate cueList for

		ret += "EndData"
	} else {
		err = errors.New("No cues provided")
	}

	return ret, err
}

package cues

import (
	"errors"
)

type CueList struct {
	Cues []Cue
}

func (cueList CueList) ConvertCues() (string, error) {
	var err error
	ret := "Ident 3:0\r\n"

	if cueList.Cues != nil {
		for i := range cueList.Cues {
			line, _ := cueList.Cues[i].ConvertToAscii()
			ret += line
		} //end iterate cueList for

		ret += "EndData"
	} else {
		err = errors.New("No cues provided")
	}

	return ret, err
}

Remove Clear Cues entry in output file


package chuper

import (
	"net/url"

	"github.com/PuerkitoBio/fetchbot"
)

type Context struct {
	*fetchbot.Context
	Cache Cache
}

func (c *Context) SourceURL() *url.URL {
	switch cmd := c.Cmd.(type) {
	case Cmd:
		return cmd.SourceURL()
	default:
		return nil
	}
}

package chuper

import (
	"net/url"

	"github.com/PuerkitoBio/fetchbot"
)

type Context struct {
	*fetchbot.Context
	C Cache
}

func (c *Context) Cache() Cache {
	return c.C
}

func (c *Context) Queue() *fetchbot.Queue {
	return c.Q
}

func (c *Context) URL() *url.URL {
	return c.Cmd.URL()
}

func (c *Context) SourceURL() *url.URL {
	switch cmd := c.Cmd.(type) {
	case Cmd:
		return cmd.SourceURL()
	default:
		return nil
	}
}

Add Cache, Queue and URL methods to Context


package services

import (
	"fmt"
	"os/exec"
)

func ccompile(source, dialect string) (out []byte, err error) {
	var standard string
	switch dialect {
	case "ansi":
		standard = "-ansi"
	case "c89":
		standard = "-std=c89"
	case "c90":
		standard = "-std=c90"
	case "c99":
		standard = "-std=c99"
	case "c11":
		standard = "-std=c11"
	}
	out, err = exec.Command(cc, standard, "-pedantic", "-Werror", "-Wall",
		"-pipe", "-fPIC", "-o", fmt.Sprintf("%s.out", source),
		source).CombinedOutput()
	return
}

package services

import (
	"fmt"
	"os/exec"
)

func ccompile(source, dialect string) ([]byte, error) {
	var std string
	switch dialect {
	case "ansi":
		std = "-ansi"
	case "c89":
		std = "-std=c89"
	case "c90":
		std = "-std=c90"
	case "c99":
		std = "-std=c99"
	case "c11":
		std = "-std=c11"
	}
	out, err = exec.Command(cc, std, "-pedantic", "-Werror", "-static",
		"-Wall", "-pipe", "-fPIC", "-o", fmt.Sprintf("%s.out", source),
		source).CombinedOutput()
	return out, err
}

Build with static linking for better memory readout when judging.


package main

import ()

func ExampleCliNoArguments() {
	repos := map[string]Repo{
		"zathura": Repo{},
		"test":    Repo{},
		"gamma":   Repo{},
	}

	app := BuildCLI(repos, Config{})
	args := make([]string, 1)

	app.Run(args)
	// Output: gamma
	// test
	// zathura
}

func ExampleCliPrintItem() {
	repos := map[string]Repo{
		"joanjett": Repo{
			Info: map[string]Info{
				"bad_reputation": Info{
					Type: "info",
					Body: "I don't give a damn about my bad reputation!",
				},
			},
		},
	}

	app := BuildCLI(repos, Config{})
	args := []string{"/go/bin/sagacity", "joanjett", "bad_reputation"}

	app.Run(args)
	// Output: I don't give a damn about my bad reputation!
}

package main

// func ExampleCliNoArguments() {
// 	repos := map[string]Repo{
// 		"zathura": Repo{},
// 		"test":    Repo{},
// 		"gamma":   Repo{},
// 	}

// 	app := BuildCLI(repos, Config{})
// 	args := make([]string, 1)

// 	app.Run(args)
// 	// Output: gamma
// 	// test
// 	// zathura
// }

// func ExampleCliPrintItem() {
// 	repos := map[string]Repo{
// 		"joanjett": Repo{
// 			Info: map[string]Info{
// 				"bad_reputation": Info{
// 					Type: "info",
// 					Body: "I don't give a damn about my bad reputation!",
// 				},
// 			},
// 		},
// 	}

// 	app := BuildCLI(repos, Config{})
// 	args := []string{"/go/bin/sagacity", "joanjett", "bad_reputation"}

// 	app.Run(args)
// 	// Output: I don't give a damn about my bad reputation!
// }

Disable CLI tests since CLI was rewritten


package netlink

//import "bytes"
//import "encoding/binary"
import "os"
import "syscall"

type Socket struct {
  fd int
}

func toErr(eno int)(err os.Error){
  if eno != 0 { err = os.NewError(syscall.Errstr(eno))}
  return
}

func Dial(nlf NetlinkFamily)(rwc *Socket, err os.Error){
  //func Dial(nlfam netlinkFamily)(rwc netlinkSocket, err os.Error){
  fdno, errno := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, int(nlf))
  err = toErr(errno)
  if err == nil {
    rwc = &Socket{fd:fdno}
  }
  return
}

func (self *Socket)Close()(err os.Error){
  errno := syscall.Close(self.fd)
  err = toErr(errno)
  return
}

func (self *Socket)Write(in []byte)(n int, err os.Error){
  if n < 0 {
    panic(n)
  }
  n, errno := syscall.Write(self.fd, in)
  err = toErr(errno)
  return
}

func (self *Socket)Read(in []byte)(n int, err os.Error){
  if n < 0 {
    panic(n)
  }
  n, errno := syscall.Read(self.fd, in)
  err = toErr(errno)
  return
}

package netlink

import "os"
import "syscall"

type Socket struct {
  fd int
}

func toErr(eno int)(err os.Error){
  if eno != 0 { err = os.NewError(syscall.Errstr(eno))}
  return
}

func Dial(nlf NetlinkFamily)(rwc *Socket, err os.Error){
  fdno, errno := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, int(nlf))
  err = toErr(errno)
  if err == nil {
    rwc = &Socket{fd:fdno}
  }
  return
}

func (self *Socket)Close()(err os.Error){
  errno := syscall.Close(self.fd)
  err = toErr(errno)
  return
}

func (self *Socket)Write(in []byte)(n int, err os.Error){
  n, errno := syscall.Write(self.fd, in)
  err = toErr(errno)
  return
}

func (self *Socket)Read(in []byte)(n int, err os.Error){
  n, errno := syscall.Read(self.fd, in)
  err = toErr(errno)
  return
}

Remove bogus panics, spurious comments


package main

import (
	"reflect"
	"regexp"
	"testing"
)

var genMatcherTests = []struct {
	src string
	dst *regexp.Regexp
}{
	{"abc", regexp.MustCompile(`abc`)},

	{"a,b", regexp.MustCompile(`(a|b)`)},
}

func TestGenMatcher(t *testing.T) {
	for _, test := range genMatcherTests {
		expect := test.dst
		actual, err := newMatcher(test.src)
		if err != nil {
			t.Errorf("NewSubvert(%q) returns %q, want nil",
				test.src, err)
		}
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}

package main

import (
	"reflect"
	"regexp"
	"testing"
)

var genMatcherTests = []struct {
	src string
	dst *regexp.Regexp
}{
	{"abc", regexp.MustCompile(`(abc)`)},

	{"a,b", regexp.MustCompile(`(a|b)`)},
}

func TestGenMatcher(t *testing.T) {
	for _, test := range genMatcherTests {
		expect := test.dst
		actual, err := newMatcher(test.src)
		if err != nil {
			t.Errorf("NewSubvert(%q) returns %q, want nil",
				test.src, err)
		}
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}

Fix spec to capture by default


package piglowservice

import (
	"log"

	pb "github.com/didrocks/grpc-piglow/proto"
	context "golang.org/x/net/context"
)

func (s *service) SetLED(ctx context.Context, in *pb.LedRequest) (*pb.Ack, error) {
	s.p.SetLED((int8)(in.Num), (uint8)(in.Brightness))
	err := s.p.Apply()
	if err != nil { // Apply the changes
		log.Println("Couldn't apply changes: ", err)
	}
	return &pb.Ack{Ok: true}, err
}

package piglowservice

import (
	"log"

	"fmt"

	pb "github.com/didrocks/grpc-piglow/proto"
	context "golang.org/x/net/context"
)

func (s *service) SetLED(ctx context.Context, in *pb.LedRequest) (*pb.Ack, error) {
	var err error

	n, err := ensureNumLed(in.Num)
	if err != nil {
		return nil, err
	}
	b, err := ensureBrightness(in.Brightness)
	if err != nil {
		return nil, err
	}

	s.p.SetLED(n, b)
	if err = s.p.Apply(); err != nil { // Apply the changes
		log.Println("Couldn't apply changes: ", err)
	}
	return &pb.Ack{Ok: true}, err
}

// convert and ensure num led is valid
func ensureNumLed(n int32) (int8, error) {
	if n < 0 || n > 17 {
		return 0, fmt.Errorf("invalid led number: %d", n)
	}
	return int8(n), nil
}

// convert and ensure brightness is valid
func ensureBrightness(b uint32) (uint8, error) {
	if b > 255 {
		return 0, fmt.Errorf("invalid brightness value: %d", b)
	}
	return uint8(b), nil
}

Add safeguards on values sent