package s3

import (
	"testing"

	"github.com/rlmcpherson/s3gof3r"
	"polydawn.net/repeatr/input/tests"
	"polydawn.net/repeatr/lib/guid"
	"polydawn.net/repeatr/output/s3"
)

func TestCoreCompliance(t *testing.T) {
	if _, err := s3gof3r.EnvKeys(); err != nil {
		t.Skipf("skipping s3 output tests; no s3 credentials loaded (err: %s)", err)
	}

	// group all effects of this test run under one "dir" for human reader sanity and cleanup in extremis.
	testRunGuid := guid.New()

	tests.CheckRoundTrip(t, "s3", s3.New, New, "s3://repeatr-test/test-"+testRunGuid+"/rt/obj.tar")
}

package s3

import (
	"testing"

	"github.com/rlmcpherson/s3gof3r"
	"polydawn.net/repeatr/input/tests"
	"polydawn.net/repeatr/lib/guid"
	"polydawn.net/repeatr/output/s3"
)

func TestCoreCompliance(t *testing.T) {
	if _, err := s3gof3r.EnvKeys(); err != nil {
		t.Skipf("skipping s3 output tests; no s3 credentials loaded (err: %s)", err)
	}

	// group all effects of this test run under one "dir" for human reader sanity and cleanup in extremis.
	testRunGuid := guid.New()

	tests.CheckRoundTrip(t, "s3", s3.New, New, "s3://repeatr-test/test-"+testRunGuid+"/rt/obj.tar")
	tests.CheckRoundTrip(t, "s3", s3.New, New, "s3+splay://repeatr-test/test-"+testRunGuid+"/rt-splay/heap/")
}

Add test of s3 splay URIs: CA-storage under prefix


package models

import (
  "github.com/spacedock-io/registry/db"
)

type Image struct {
  Id        int64
  Uuid      string
  Json      []byte
  Checksum  string
  Size      int64
  Ancestry  []string
  Tags      []Tag
}

func (image *Image) Save() error {
  q := db.DB.Save(image)
  return q.Error
}

package models

import (
  "github.com/spacedock-io/registry/db"
)

type Image struct {
  Id        int64
  Uuid      string
  Json      []byte
  Checksum  string
  Size      int64
  Ancestry  []Ancestor
  Tags      []Tag
}

type Ancestor struct {
  Id int64
  ImageId int64
  Name string
}

func (image *Image) Save() error {
  q := db.DB.Save(image)
  return q.Error
}

Add very basic Ancestry model


package templates

func ScopeTemplateContent() string {
	return `{{ .Name}}:
  {{ range .Services }}{{ .GetName }}:
    {{ range $key, $value := .GetParameters }}{{ $key }}: {{ $value }}
    {{ end }}{{ end }}
`
}

package templates

func ScopeTemplateContent() string {
	return `#cloud-config

{{ .Name}}:
  {{ range .Services }}{{ .GetName }}:
    {{ range $key, $value := .GetParameters }}{{ $key }}: {{ $value }}
    {{ end }}
  {{ end }}
`
}

Add line break after each service on template


package migrator

import (
	"github.com/mattes/migrate/migrate"
	"github.com/resourced/resourced-master/config"
)

func New(generalConfig config.GeneralConfig) *Migrator {
	m := &Migrator{}
	m.AppGeneralConfig = generalConfig

	return m
}

type Migrator struct {
	AppGeneralConfig config.GeneralConfig
}

func (m *Migrator) CoreMigrateUp() ([]error, bool) {
	return migrate.UpSync(m.AppGeneralConfig.DSN, "./migrations/core")
}

func (m *Migrator) TSWatchersMigrateUp() ([]error, bool) {
	for _, dsn := range m.AppGeneralConfig.Watchers.DSNs {
		errs, ok := migrate.UpSync(dsn, "./migrations/ts-watchers")
		if errs != nil && len(errs) > 0 {
			return errs, ok
		}
	}

	return nil, true
}

func (m *Migrator) TSMetricsMigrateUp() ([]error, bool) {
	for _, dsn := range m.AppGeneralConfig.Metrics.DSNs {
		errs, ok := migrate.UpSync(dsn, "./migrations/ts-metrics")
		if errs != nil && len(errs) > 0 {
			return errs, ok
		}
	}

	return nil, true
}

package migrator

import (
	_ "github.com/mattes/migrate/driver/postgres"
	"github.com/mattes/migrate/migrate"
	"github.com/resourced/resourced-master/config"
)

func New(generalConfig config.GeneralConfig) *Migrator {
	m := &Migrator{}
	m.AppGeneralConfig = generalConfig

	return m
}

type Migrator struct {
	AppGeneralConfig config.GeneralConfig
}

func (m *Migrator) CoreMigrateUp() ([]error, bool) {
	return migrate.UpSync(m.AppGeneralConfig.DSN, "./migrations/core")
}

func (m *Migrator) TSWatchersMigrateUp() ([]error, bool) {
	for _, dsn := range m.AppGeneralConfig.Watchers.DSNs {
		errs, ok := migrate.UpSync(dsn, "./migrations/ts-watchers")
		if errs != nil && len(errs) > 0 {
			return errs, ok
		}
	}

	return nil, true
}

func (m *Migrator) TSMetricsMigrateUp() ([]error, bool) {
	for _, dsn := range m.AppGeneralConfig.Metrics.DSNs {
		errs, ok := migrate.UpSync(dsn, "./migrations/ts-metrics")
		if errs != nil && len(errs) > 0 {
			return errs, ok
		}
	}

	return nil, true
}

Upgrade migrate library to avoid using sqlite lib.


package rpc

import (
	"cgl.tideland.biz/asserts"
	"net/rpc"
	"testing"
)

func TestServer_Address_PanicIfNotStarted(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)

	defer func() {
		p := recover()
		assert.NotNil(p, "should panic")
		assert.Equal(p.(string), "Server not listening.", "right panic")
	}()

	NewServer().Address()
}

func TestServer_Start(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)

	s := NewServer()

	// Verify it can start
	err := s.Start()
	assert.Nil(err, "should start without err")
	addr := s.Address()

	// Verify we can connect to it!
	_, err = rpc.Dial("tcp", addr)
	assert.Nil(err, "should be able to connect to RPC")

	// Verify it stops
	s.Stop()
	_, err = rpc.Dial("tcp", addr)
	assert.NotNil(err, "should NOT be able to connect to RPC")
}

func TestServer_RegisterUi(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)

	ui := &testUi{}

	// Start the server with a UI
	s := NewServer()
	s.RegisterUi(ui)
	assert.Nil(s.Start(), "should start properly")
	defer s.Stop()

	// Verify it works
	client, err := rpc.Dial("tcp", s.Address())
	assert.Nil(err, "should connect via RPC")

	uiClient := &Ui{client}
	uiClient.Say("format")

	assert.Equal(ui.sayFormat, "format", "format should be correct")
}

Test regisering a UI with the server


// Package dns resolves names to dns records
package dns

import (
	"net"

	"github.com/micro/go-micro/network/resolver"
)

// Resolver is a DNS network resolve
type Resolver struct{}

// Resolve assumes ID is a domain name e.g micro.mu
func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) {
	host, port, err := net.SplitHostPort(name)
	if err != nil {
		host = name
		port = "8085"
	}

	if len(host) == 0 {
		host = "localhost"
	}

	addrs, err := net.LookupHost(host)
	if err != nil {
		return nil, err
	}

	records := make([]*resolver.Record, 0, len(addrs))

	for _, addr := range addrs {
		// join resolved record with port
		address := net.JoinHostPort(addr, port)
		// append to record set
		records = append(records, &resolver.Record{
			Address: address,
		})
	}

	return records, nil
}

// Package dns resolves names to dns records
package dns

import (
	"context"
	"net"

	"github.com/micro/go-micro/network/resolver"
	"github.com/miekg/dns"
)

// Resolver is a DNS network resolve
type Resolver struct {
	// The resolver address to use
	Address string
}

// Resolve assumes ID is a domain name e.g micro.mu
func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) {
	host, port, err := net.SplitHostPort(name)
	if err != nil {
		host = name
		port = "8085"
	}

	if len(host) == 0 {
		host = "localhost"
	}

	if len(r.Address) == 0 {
		r.Address = "1.0.0.1:53"
	}

	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn(host), dns.TypeA)
	rec, err := dns.ExchangeContext(context.Background(), m, r.Address)
	if err != nil {
		return nil, err
	}

	var records []*resolver.Record

	for _, answer := range rec.Answer {
		h := answer.Header()
		// check record type matches
		if h.Rrtype != dns.TypeA {
			continue
		}

		arec, _ := answer.(*dns.A)
		addr := arec.A.String()

		// join resolved record with port
		address := net.JoinHostPort(addr, port)
		// append to record set
		records = append(records, &resolver.Record{
			Address: address,
		})
	}

	return records, nil
}

Make use of cloudflare 1.0.0.1 by default to resolve addresses


package syssetup

import (
	"io/ioutil"
	"os/exec"

	"github.com/sirupsen/logrus"
)

var (
	callIPTablesFile = "/proc/sys/net/bridge/bridge-nf-call-iptables"
)

func Configure() error {
	exec.Command("modprobe", "br_netfilter").Run()
	if err := ioutil.WriteFile(callIPTablesFile, []byte("1"), 0640); err != nil {
		logrus.Warnf("failed to write value 1 at %s: %v", callIPTablesFile, err)
	}
	return nil
}

package syssetup

import (
	"io/ioutil"
	"os/exec"

	"github.com/sirupsen/logrus"
)

var (
	callIPTablesFile = "/proc/sys/net/bridge/bridge-nf-call-iptables"
	forward          = "/proc/sys/net/ipv4/ip_forward"
)

func Configure() error {
	exec.Command("modprobe", "br_netfilter").Run()
	if err := ioutil.WriteFile(callIPTablesFile, []byte("1"), 0640); err != nil {
		logrus.Warnf("failed to write value 1 at %s: %v", callIPTablesFile, err)
	}
	if err := ioutil.WriteFile(forward, []byte("1"), 0640); err != nil {
		logrus.Warnf("failed to write value 1 at %s: %v", forward, err)
	}
	return nil
}

Set /proc/sys/net/ipv4/ip_forward on agent start


package state

import (
	"github.com/hashicorp/terraform/terraform"
)

// State is the collection of all state interfaces.
type State interface {
	StateReader
	StateWriter
	StateRefresher
	StatePersister
}

// StateReader is the interface for things that can return a state. Retrieving
// the state here must not error. Loading the state fresh (an operation that
// can likely error) should be implemented by RefreshState. If a state hasn't
// been loaded yet, it is okay for State to return nil.
type StateReader interface {
	State() *terraform.State
}

// StateWriter is the interface that must be implemented by something that
// can write a state. Writing the state can be cached or in-memory, as
// full persistence should be implemented by StatePersister.
type StateWriter interface {
	WriteState(*terraform.State) error
}

// StateRefresher is the interface that is implemented by something that
// can load a state. This might be refreshing it from a remote location or
// it might simply be reloading it from disk.
type StateRefresher interface {
	RefreshState() error
}

// StatePersister is implemented to truly persist a state. Whereas StateWriter
// is allowed to perhaps be caching in memory, PersistState must write the
// state to some durable storage.
type StatePersister interface {
	PersistState() error
}

// Locker is implemented to lock state during command execution.
type Locker interface {
	Lock(reason string) error
	Unlock() error
}

package state

import (
	"github.com/hashicorp/terraform/terraform"
)

// State is the collection of all state interfaces.
type State interface {
	StateReader
	StateWriter
	StateRefresher
	StatePersister
}

// StateReader is the interface for things that can return a state. Retrieving
// the state here must not error. Loading the state fresh (an operation that
// can likely error) should be implemented by RefreshState. If a state hasn't
// been loaded yet, it is okay for State to return nil.
type StateReader interface {
	State() *terraform.State
}

// StateWriter is the interface that must be implemented by something that
// can write a state. Writing the state can be cached or in-memory, as
// full persistence should be implemented by StatePersister.
type StateWriter interface {
	WriteState(*terraform.State) error
}

// StateRefresher is the interface that is implemented by something that
// can load a state. This might be refreshing it from a remote location or
// it might simply be reloading it from disk.
type StateRefresher interface {
	RefreshState() error
}

// StatePersister is implemented to truly persist a state. Whereas StateWriter
// is allowed to perhaps be caching in memory, PersistState must write the
// state to some durable storage.
type StatePersister interface {
	PersistState() error
}

// Locker is implemented to lock state during command execution.
// The optional info parameter can be recorded with the lock, but the
// implementation should not depend in its value.
type Locker interface {
	Lock(info string) error
	Unlock() error
}

Change lock reason -> info


package regex

import (
	"fmt"
	"time"

	"cirello.io/gochatbot/bot"
)

var regexRules = []regexRule{
	{
		`{{ .RobotName }} jump`, `tells the robot to jump`,
		func(bot bot.Self, msg string, matches []string) []string {
			var ret []string
			ret = append(ret, "{{ .User }}, How high?")
			lastJumpTS := bot.MemoryRead("jump", "lastJump")
			ret = append(ret, fmt.Sprint("{{ .User }} (last time I jumped:", lastJumpTS, ")"))
			bot.MemorySave("jump", "lastJump", fmt.Sprint(time.Now()))

			return ret
		},
	},
}

package regex

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"time"

	"cirello.io/gochatbot/bot"
)

var regexRules = []regexRule{
	{
		`{{ .RobotName }} jump`, `tells the robot to jump`,
		func(bot bot.Self, msg string, matches []string) []string {
			var ret []string
			ret = append(ret, "{{ .User }}, How high?")
			lastJumpTS := bot.MemoryRead("jump", "lastJump")
			ret = append(ret, fmt.Sprint("{{ .User }} (last time I jumped:", lastJumpTS, ")"))
			bot.MemorySave("jump", "lastJump", fmt.Sprint(time.Now()))

			return ret
		},
	},
	{
		`{{ .RobotName }} godoc (.*)`, `search godoc.org and return the first result`,
		func(bot bot.Self, msg string, matches []string) []string {
			if len(matches) < 2 {
				return []string{}
			}

			resp, err := http.Get(fmt.Sprintf("http://api.godoc.org/search?q=%s", url.QueryEscape(matches[1])))
			if err != nil {
				return []string{err.Error()}
			}
			defer resp.Body.Close()

			var data struct {
				Results []struct {
					Path     string `json:"path"`
					Synopsis string `json:"synopsis"`
				} `json:"results"`
			}

			if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
				return []string{err.Error()}
			}

			if len(data.Results) == 0 {
				return []string{"package not found"}
			}

			return []string{fmt.Sprintf("%s %s/%s", data.Results[0].Synopsis, "http://godoc.org", data.Results[0].Path)}

		},
	},
}

Add example command in Regex rule which uses its matches


package raft

// FSM provides an interface that can be implemented by
// clients to make use of the replicated log
type FSM interface {
	// Apply log is invoked once a log entry is commited
	ApplyLog([]byte)
}

package raft

// FSM provides an interface that can be implemented by
// clients to make use of the replicated log
type FSM interface {
	// Apply log is invoked once a log entry is commited
	Apply([]byte)
}

Change FSM method to just Apply


package wrapplog

import (
	"strings"

	"github.com/Sirupsen/logrus"
)

var jsonFormatter = logrus.JSONFormatter{}

type WrappFormatter struct {
	// TimestampFormat sets the format used for marshaling timestamps.
	TimestampFormat string
}

func (f *WrappFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	jsonBytes, err := (&jsonFormatter).Format(entry)
	prefix := []byte(strings.ToUpper(entry.Level.String()) + " ")
	return append(prefix[:], jsonBytes[:]...), err
}

package wrapplog

import (
	"os"
	"strings"

	"github.com/Sirupsen/logrus"
)

var jsonFormatter = logrus.JSONFormatter{}

type WrappFormatter struct{}

func init() {
	logrus.SetFormatter(&WrappFormatter{})
	logrus.SetOutput(os.Stdout)
	logrus.Info("initializing wrapp logging")
}

// Format logs according to WEP-007
func (f *WrappFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	jsonBytes, err := (&jsonFormatter).Format(entry)
	prefix := []byte(strings.ToUpper(entry.Level.String()) + " ")
	return append(prefix[:], jsonBytes[:]...), err
}

Set up WrappFormatter in init


package util

import (
	"regexp"
)

func Contains(stringSlice []string, searchString string) bool {
	for _, value := range stringSlice {
		if value == searchString {
			return true
		}
	}
	return false
}

func ContainsRegex(regexs []string, searchString string) bool {
	for _, regex := range regexs {
		match, err := regexp.MatchString(regex, searchString)
		if match {
			return true
		}
		if err != nil {
			loggerUtilHTML.Errorf(err.Error())
		}
	}
	return false
}

func ContainsGetIndex(stringSlice []string, searchString string) int {
	for key, value := range stringSlice {
		if value == searchString {
			return key
		}
	}
	return -1
}

package util

import (
	"regexp"
)

func Contains(stringSlice []string, searchString string) bool {
	for _, regex := range stringSlice {
		match, err := regexp.MatchString(regex, searchString)
		if match {
			return true
		}
		if err != nil {
			loggerUtilHTML.Errorf(err.Error())
		}
	}
	return false
}

func ContainsRegex(regexs []string, searchString string) bool {
	for _, regex := range regexs {
		match, err := regexp.MatchString(regex, searchString)
		if match {
			return true
		}
		if err != nil {
			loggerUtilHTML.Errorf(err.Error())
		}
	}
	return false
}

func ContainsGetIndex(stringSlice []string, searchString string) int {
	for key, value := range stringSlice {
		if value == searchString {
			return key
		}
	}
	return -1
}

Add regex for specific form inputs detection


package models

import (
	"github.com/coopernurse/gorp"
)

func CreateTables(g *gorp.DbMap) {
	// Add User Table
	t := g.AddTableWithName(User{}, "dispatch_user").SetKeys(true, "UserId")
	t.ColMap("Password").Transient = true

	// Add UserApp Table
	g.AddTableWithName(UserApp{}, "dispatch_app").SetKeys(true, "UserAppId")

	// Add UserSubscription Table
	g.AddTableWithName(UserSubscription{}, "dispatch_subscription").SetKeys(true, "SubscriptionId")

	// Add User Identity Tables
	g.AddTableWithName(Identity{}, "dispatch_identity").SetKeys(true, "IdentityId")
}

package models

import (
	"github.com/coopernurse/gorp"
)

func CreateTables(g *gorp.DbMap) {
	// Add User Table
	t := g.AddTableWithName(User{}, "dispatch_user").SetKeys(true, "UserId")
	t.ColMap("Password").Transient = true

	// Add UserApp Table
	g.AddTableWithName(UserApp{}, "dispatch_app").SetKeys(true, "UserAppId")

	// Add UserSubscription Table
	g.AddTableWithName(UserSubscription{}, "dispatch_subscription").SetKeys(true, "SubscriptionId")

	// Add User Identity Tables
	g.AddTableWithName(Identity{}, "dispatch_identity").SetKeys(true, "IdentityId")

	// Add MailServer Tables
	g.AddTableWithName(Message{}, "dispatch_messages").SetKeys(true, "MessageId")
	g.AddTableWithName(Alert{}, "dispatch_alerts").SetKeys(true, "AlertId")
	g.AddTableWithName(Component{}, "dispatch_components").SetKeys(true, "ComponentId")
}

Put the Tables for Live


package main

import (
	"fmt"
	"os"
	"flag"

	"github.com/golang/glog"

	"github.com/asobti/kube-monkey/config"
	"github.com/asobti/kube-monkey/kubemonkey"
)

func glogUsage() {
        fmt.Fprintf(os.Stderr, "usage: example -stderrthreshold=[INFO|WARN|FATAL] -log_dir=[string]\n", )
        flag.PrintDefaults()
        os.Exit(2)
}

func initConfig() {
	if err := config.Init(); err != nil {
		glog.Fatal(err.Error())
	}
}

func main() {
        // Check commandline options or "flags" for glog parameters
        // to be picked up by the glog module
        flag.Usage = glogUsage
        flag.Parse()

        // Since km runs as a k8 pod, log everything to stderr (stdout not supported)
        // this takes advantage of k8's logging driver allowing kubectl logs kube-monkey
	flag.Lookup("logtostderr").Value.Set("true")

	// Initialize configs
	initConfig()

	glog.Info("Starting kube-monkey with logging level: ", flag.Lookup("v").Value)

	if err := kubemonkey.Run(); err != nil {
		glog.Fatal(err.Error())
	}
}

package main

import (
	"fmt"
	"os"
	"flag"

	"github.com/golang/glog"

	"github.com/asobti/kube-monkey/config"
	"github.com/asobti/kube-monkey/kubemonkey"
)

func glogUsage() {
	fmt.Fprintf(os.Stderr, "usage: example -stderrthreshold=[INFO|WARN|FATAL] -log_dir=[string]\n", )
	flag.PrintDefaults()
	os.Exit(2)
}

func initConfig() {
	if err := config.Init(); err != nil {
		glog.Fatal(err.Error())
	}
}

func main() {
	// Check commandline options or "flags" for glog parameters
	// to be picked up by the glog module
	flag.Usage = glogUsage
	flag.Parse()

	// Since km runs as a k8 pod, log everything to stderr (stdout not supported)
	// this takes advantage of k8's logging driver allowing kubectl logs kube-monkey
	flag.Lookup("alsologtostderr").Value.Set("true")

	// Initialize configs
	initConfig()

	glog.Info("Starting kube-monkey with logging level: ", flag.Lookup("v").Value)

	if err := kubemonkey.Run(); err != nil {
		glog.Fatal(err.Error())
	}
}

Enable file and stderr logging


package main

import "math/rand"
import "time"

const DEFAULT_AD_CHANCE = 85

type Plug struct {
	ID             int
	S3ID           string
	Owner          string
	ViewsRemaining int
}

func (p Plug) IsDefault() bool {
	return p.ViewsRemaining >= 0
}

func ChoosePlug(plugs []Plug) Plug {
	rand.Seed(time.Now().Unix())
	// Split plugs into default and custom ads
	var defaults []Plug
	var customs []Plug
	for i := 0; i < len(plugs); i++ {
		if plugs[i].IsDefault() {
			defaults = append(defaults, plugs[i])
		} else {
			customs = append(customs, plugs[i])
		}
	}
	// Decide whether to chose default ad or user submitted ad
	var pickDefault int = rand.Intn(100)
	if pickDefault >= DEFAULT_AD_CHANCE && len(defaults) != 0 {
		return defaults[rand.Intn(len(defaults))]
	} else {
		return customs[rand.Intn(len(customs))]
	}
}

package main

import "math/rand"
import "time"

const DEFAULT_AD_CHANCE = 95

type Plug struct {
	ID             int
	S3ID           string
	Owner          string
	ViewsRemaining int
}

func (p Plug) IsDefault() bool {
	return p.ViewsRemaining >= 0
}

func ChoosePlug(plugs []Plug) Plug {
	rand.Seed(time.Now().Unix())
	// Split plugs into default and custom ads
	var defaults []Plug
	var customs []Plug
	for i := 0; i < len(plugs); i++ {
		if plugs[i].IsDefault() {
			defaults = append(defaults, plugs[i])
		} else {
			customs = append(customs, plugs[i])
		}
	}
	// Decide whether to chose default ad or user submitted ad
	var pickDefault int = rand.Intn(100)
	if pickDefault >= DEFAULT_AD_CHANCE && len(defaults) != 0 {
		return defaults[rand.Intn(len(defaults))]
	} else {
		return customs[rand.Intn(len(customs))]
	}
}

Make Default Ads super rare


package secretcrypt

import (
	"bytes"
	"testing"
)

func passthrough(plaintext string) {
	crypted, err := Encrypt("testphrase", []byte(plaintext))
	if err != nil {
		panic(err)
	}

	plain, err := Decrypt("testphrase", crypted)
	if err != nil {
		panic(err)
	}

	if !bytes.Equal(plain, []byte(plain)) {
		panic("expected correct plaintext")
	}
}

func TestEncryptDecryptDoesNotCorrupt(t *testing.T) {
	passthrough("test")
	passthrough("")
	passthrough("t")
}

package secretcrypt

import (
	"bytes"
	"testing"
	"math/rand"
)

func passthrough(passphrase string, plaintext []byte) {
	crypted, err := Encrypt(passphrase, plaintext)
	if err != nil {
		panic(err)
	}

	plainResult, err := Decrypt(passphrase, crypted)
	if err != nil {
		panic(err)
	}

	if !bytes.Equal(plainResult, plaintext) {
		panic("expected correct plaintext")
	}
}

func TestEncryptDecryptDoesNotCorrupt(t *testing.T) {
	rand.NewSource(0)
	rSource := rand.NewSource(0)
	r := rand.New(rSource)

	// Choose a small number of sizes for performance reasons. Because key stretching happens on every
	// call, we're slow.
	plaintextLens := []int{0, 5, 64000, 128000}
	for i := 0; i < len(plaintextLens); i++ {
		b := make([]byte, plaintextLens[i])

		r.Read(b)
		passthrough("testphrase", b)
	}
}

Fix test bug, improve test edge case coverage.


// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package ldb_test

import (
	"github.com/conformal/btcdb"
	"github.com/conformal/btcwire"
	"os"
	"testing"
)

// we need to test for empty databas and make certain it returns proper value

func TestEmptyDB(t *testing.T) {

	dbname := "tstdbempty"
	_ = os.RemoveAll(dbname)
	db, err := btcdb.CreateDB("leveldb", dbname)
	if err != nil {
		t.Errorf("Failed to open test database %v", err)
		return
	}
	defer os.RemoveAll(dbname)

	// This is a reopen test
	db.Close()

	db, err = btcdb.OpenDB("leveldb", dbname)
	if err != nil {
		t.Errorf("Failed to open test database %v", err)
		return
	}
	defer db.Close()

	sha, height, err := db.NewestSha()
	if !sha.IsEqual(&btcwire.ShaHash{}) {
		t.Errorf("sha not nil")
	}
	if height != -1 {
		t.Errorf("height not -1 %v", height)
	}
}

// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package ldb_test

import (
	"github.com/conformal/btcdb"
	"github.com/conformal/btcwire"
	"os"
	"testing"
)

// we need to test for empty databas and make certain it returns proper value

func TestEmptyDB(t *testing.T) {

	dbname := "tstdbempty"
	_ = os.RemoveAll(dbname)
	db, err := btcdb.CreateDB("leveldb", dbname)
	if err != nil {
		t.Errorf("Failed to open test database %v", err)
		return
	}
	defer os.RemoveAll(dbname)

	// This is a reopen test
	db.Close()

	db, err = btcdb.OpenDB("leveldb", dbname)
	if err != nil {
		t.Errorf("Failed to open test database %v", err)
		return
	}
	defer db.Close()

	sha, height, err := db.NewestSha()
	if !sha.IsEqual(&btcwire.ShaHash{}) {
		t.Errorf("sha not zero hash")
	}
	if height != -1 {
		t.Errorf("height not -1 %v", height)
	}
}

Update error message for zero hash change.


package codeutilsShared

import (
	"crypto/sha512"
	"encoding/hex"
	"os"
)

// GlobalFileMode as a file mode we'll use for "global" operations such as when doing IO as root
var GlobalFileMode os.FileMode

// UniversalFileMode as a file mode we'll wherever we can
var UniversalFileMode os.FileMode

func init() {
	GlobalFileMode = 0777    // Set to global read/write/executable
	UniversalFileMode = 0744 // Only read/write/executable by owner, readable by group and others
}

// Sha512Sum will create a sha512sum of the string
func Sha512Sum(content string) string {
	sha512Hasher := sha512.New()                     // Create a new Hash struct
	sha512Hasher.Write([]byte(content))              // Write the byte array of the content
	return hex.EncodeToString(sha512Hasher.Sum(nil)) // Return string encoded sum of sha512sum
}

package codeutilsShared

import (
	"crypto/sha512"
	"encoding/hex"
	"os"
)

// GlobalFileMode as a file mode we'll use for "global" operations such as when doing IO as root
var GlobalFileMode os.FileMode

// UniversalFileMode as a file mode we'll wherever we can
var UniversalFileMode os.FileMode

func init() {
	GlobalFileMode = 0777    // Set to global read/write/executable
	UniversalFileMode = 0744 // Only read/write/executable by owner, readable by group and others
}

// Sha512Sum will create a sha512sum of the string
func Sha512Sum(content string, rounds int) string {
	var hashString string

	sha512Hasher := sha512.New()                           // Create a new Hash struct
	sha512Hasher.Write([]byte(content))                    // Write the byte array of the content
	hashString = hex.EncodeToString(sha512Hasher.Sum(nil)) // Return string encoded sum of sha512sum

	if (rounds != 0) && (rounds > 1) { // If we are cycling more than one rounds
		for currentRound := 0; currentRound < rounds; currentRound++ {
			hashString = Sha512Sum(hashString, 1) // Rehash the new hashString
		}
	}

	return hashString
}

Implement rounds in Sha512Sum func


package adeptus

var (
	regex_xp = regexp.MustCompile(`\(?\d+xp\)?`) // Match `150xp` and `(150xp)`
)

type Upgrade interface {
	Mark string
	Name string
	Cost string
}

// ParseUpgrade generate an upgrade from a raw line
func ParseUpgrade(raw string) (Upgrade, error) {
	upgrade := Upgrade{}

	// Get the fields of the line
	fields := strings.Fields(raw)

	// The minimum number of fields is 2
	if len(fields) < 2 {
		return upgrade, fmt.Errorf("not enought")
	}

	// Check that the mark is a valid one
	if !in(fields[0], []string{"*", "+", "-"}) {
		return upgrade, fmt.Errorf("%s isn't a valid mark", fields[0])
	}

	// Set the upgrade mark
	upgrade.Mark = fields[0]
	fields = fields[1:]

	// Check if a field seems to be a cost field
	for i, field := range fields {
		if !regex_xp.MatchString(field) {
			continue
		}

		upgrade.Cost = regex_xp.FindString(field)
		fields = append(fields[:i], fields[i+1:]...)
		break
	}

	// The remaining line is the name of the upgrade
	upgrade.Name = strings.Join(fields, " ")

	return upgrade, nil
}

package adeptus

var (
	regex_xp = regexp.MustCompile(`\(?\d+xp\)?`) // Match `150xp` and `(150xp)`
)

type Upgrade interface {
	Mark string
	Name string
	Cost string
	Line int
}

// ParseUpgrade generate an upgrade from a raw line
func ParseUpgrade(raw string, line int) (Upgrade, error) {
	// Initialize a new upgrade
	upgrade := Upgrade{
		Line: line,
	}

	// Get the fields of the line
	fields := strings.Fields(raw)

	// The minimum number of fields is 2
	if len(fields) < 2 {
		return Upgrade{}, fmt.Errorf("not enought")
	}

	// Check that the mark is a valid one
	if !in(fields[0], []string{"*", "+", "-"}) {
		return Upgrade{}, fmt.Errorf("%s isn't a valid mark", fields[0])
	}

	// Set the upgrade mark
	upgrade.Mark = fields[0]
	fields = fields[1:]

	// Check if a field seems to be a cost field
	for i, field := range fields {
		if !regex_xp.MatchString(field) {
			continue
		}

		upgrade.Cost = regex_xp.FindString(field)
		fields = append(fields[:i], fields[i+1:]...)
		break
	}

	// The remaining line is the name of the upgrade
	upgrade.Name = strings.Join(fields, " ")

	return upgrade, nil
}

Add a Line field to the Upgrade struct


// Copyright 2014 Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package util

import "testing"

func TestAssertEquals(t *testing.T) {
	v := 1
	AssertEquals(t, v, v)
	if t.Failed() {
		t.Errorf("AssertEquals(t, %d, %d) fails, want %d equals %d", v, v, v, v)
	}
}

// Copyright 2014 Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package util

import "testing"

func TestAssertEquals(t *testing.T) {
	v := 1
	AssertEquals(t, v, v)
	if t.Failed() {
		t.Errorf("AssertEquals(t, %d, %d) fails; want %d equals %d", v, v, v, v)
	}
}

Change error message of AssertEquals test


package main

import (
	"time"

	"github.com/didip/tollbooth"
	"github.com/magicwrighter/tollbooth/thirdparty/tollbooth_fasthttp"
	"github.com/valyala/fasthttp"
)

func main() {
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		case "/hello":
			helloHandler(ctx)
		default:
			ctx.Error("Unsupporterd path", fasthttp.StatusNotFound)
		}
	}

	// Create a limiter struct.
	limiter := tollbooth.NewLimiter(1, time.Second)

	fasthttp.ListenAndServe(":4444", tollbooth_fasthttp.LimitHandler(requestHandler, limiter))
}

func helloHandler(ctx *fasthttp.RequestCtx) {
	ctx.SetStatusCode(fasthttp.StatusOK)
	ctx.SetBody([]byte("Hello, World!"))
}

package main

import (
	"time"

	"github.com/didip/tollbooth"
	"github.com/didip/tollbooth/thirdparty/tollbooth_fasthttp"
	"github.com/valyala/fasthttp"
)

func main() {
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		case "/hello":
			helloHandler(ctx)
		default:
			ctx.Error("Unsupporterd path", fasthttp.StatusNotFound)
		}
	}

	// Create a limiter struct.
	limiter := tollbooth.NewLimiter(1, time.Second)

	fasthttp.ListenAndServe(":4444", tollbooth_fasthttp.LimitHandler(requestHandler, limiter))
}

func helloHandler(ctx *fasthttp.RequestCtx) {
	ctx.SetStatusCode(fasthttp.StatusOK)
	ctx.SetBody([]byte("Hello, World!"))
}

Remove faulty dependency on magicwright repo


// +build linux,386

package system

import (
	"syscall"
)

// Setuid sets the uid of the calling thread to the specified uid.
func Setuid(uid int) (err error) {
	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
	if e1 != 0 {
		err = e1
	}
	return
}

// Setgid sets the gid of the calling thread to the specified gid.
func Setgid(gid int) (err error) {
	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0)
	if e1 != 0 {
		err = e1
	}
	return
}

// +build linux,386

package system

import (
	"syscall"
)

// Setuid sets the uid of the calling thread to the specified uid.
func Setuid(uid int) (err error) {
	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0)
	if e1 != 0 {
		err = e1
	}
	return
}

// Setgid sets the gid of the calling thread to the specified gid.
func Setgid(gid int) (err error) {
	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0)
	if e1 != 0 {
		err = e1
	}
	return
}

Support 32 bit UID on i386


package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)

var version string

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s %s", r.Method, r.URL)
		fmt.Fprintf(w, GreetingMessage())
	})

	log.Fatal(http.ListenAndServe(":8000", nil))
}

func GetVersion() string {
	return os.Getenv("VERSION")
}

func GreetingMessage() string {
	return fmt.Sprintf("Running version %s", GetVersion())
}

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)

var version string

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		defer logRequestInfo(r)
		fmt.Fprintf(w, GreetingMessage())
	})

	http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
		defer logRequestInfo(r)
		fmt.Fprintf(w, "pong")
	})

	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		defer logRequestInfo(r)
		fmt.Fprintf(w, "ok")
	})

	log.Fatal(http.ListenAndServe(":8000", nil))
}

func GetVersion() string {
	return os.Getenv("VERSION")
}

func GreetingMessage() string {
	return fmt.Sprintf("Running version %s", GetVersion())
}

func logRequestInfo(r *http.Request) {
	log.Printf("%s %s", r.Method, r.URL)
}

Add support for /ping and /health routes


package main

import (
	"github.com/buchgr/bazelremote/cache"
)

// TODO: Add command line flags

func main() {
	e := cache.NewEnsureSpacer(0.8, 0.5)
	h := cache.NewHTTPCache(":8080", "/Users/buchgr/cache", 10*1024*1024, e)
	h.Serve()
}

package main

import (
	"flag"
	"strconv"

	"github.com/buchgr/bazel-remote/cache"
)

func main() {
	port := flag.Int("port", 8080, "The port the HTTP server listens on")
	dir := flag.String("dir", "",
		"Directory path where to store the cache contents")
	maxSize := flag.Int64("max_size", -1,
		"The maximum size of the remote cache in bytes")
	flag.Parse()

	if *maxSize <= 0 {
		flag.Usage()
		return
	}

	e := cache.NewEnsureSpacer(0.8, 0.5)
	h := cache.NewHTTPCache(":"+strconv.Itoa(*port), *dir, *maxSize, e)
	h.Serve()
}

Add basic command line flags


package main

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

	"github.com/flynn/go-flynn/migrate"
	"github.com/flynn/go-flynn/postgres"
)

func main() {
	log.SetFlags(log.Lmicroseconds | log.Lshortfile)

	db, err := postgres.Open("", "")
	if err != nil {
		log.Fatal(err)
	}

	m := migrate.NewMigrations()
	m.Add(1, "CREATE SEQUENCE hits")
	if err := m.Migrate(db.DB); err != nil {
		log.Fatal(err)
	}

	stmt, err := db.Prepare("SELECT nextval('hits')")
	if err != nil {
		log.Fatal(err)
	}

	port := os.Getenv("PORT")

	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		var count int
		if err := stmt.QueryRow().Scan(&count); err != nil {
			w.WriteHeader(500)
			w.Write([]byte(err.Error()))
			return
		}
		fmt.Fprintf(w, "Hello from Go+PostgreSQL on Flynn: port=%s hits=%d container=%s\n", port, count, os.Getenv("HOSTNAME"))
	})
	fmt.Println("hitcounter listening on port", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

package main

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

	"github.com/flynn/go-flynn/migrate"
	"github.com/flynn/go-flynn/postgres"
)

func main() {
	log.SetFlags(log.Lmicroseconds | log.Lshortfile)

	db, err := postgres.Open("", "")
	if err != nil {
		log.Fatal(err)
	}

	m := migrate.NewMigrations()
	m.Add(1, "CREATE SEQUENCE hits")
	if err := m.Migrate(db.DB); err != nil {
		log.Fatal(err)
	}

	stmt, err := db.Prepare("SELECT nextval('hits')")
	if err != nil {
		log.Fatal(err)
	}

	port := os.Getenv("PORT")

	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		var count int
		if err := stmt.QueryRow().Scan(&count); err != nil {
			w.WriteHeader(500)
			w.Write([]byte(err.Error()))
			return
		}
		fmt.Fprintf(w, "Hello from Flynn on port %s from container %s\nHits = %d\n", port, os.Getenv("HOSTNAME"), count)
	})
	fmt.Println("hitcounter listening on port", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

Reformat output to match other examples.


package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
)

func executeCmd(command string, args ...string) {
	cmd := exec.Command(command, args...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(os.Stderr, "Error creating StdoutPipe for Cmd", err)
	}

	defer cmdReader.Close()

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			fmt.Printf("%s\n", scanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		log.Fatal(os.Stderr, "Error starting Cmd", err)
	}

	err = cmd.Wait()
	// go generate command will fail when no generate command find.
	if err != nil {
		if err.Error() != "exit status 1" {
			log.Fatal(err)
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
)

func executeCmd(command string, args ...string) {
	cmd := exec.Command(command, args...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(os.Stderr, "Error creating StdoutPipe for Cmd", err)
	}

	defer cmdReader.Close()

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			fmt.Printf("%s\n", scanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		log.Fatal(os.Stderr, "Error starting Cmd", err)
	}

	err = cmd.Wait()
	// go generate command will fail when no generate command find.
	if err != nil {
		if err.Error() != "exit status 1" {
			fmt.Println(err)
			log.Fatal(err)
		}
	}
}

Add printing err to STD out


package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"code.google.com/p/go-uuid/uuid"
	"github.com/jsgoecke/nest"
	"gopkg.in/yaml.v2"
)

var thermostat *nest.Thermostat

type NestConf struct {
	Productid     string
	Productsecret string
	Authorization string
	Token         string
}

func init() {
	f, err := ioutil.ReadFile("./nest.yml")
	if err != nil {
		panic(err)
	}

	var c NestConf
	err = yaml.Unmarshal(f, &c)
	if err != nil {
		panic(err)
	}

	client := nest.New(c.Productid, uuid.NewUUID().String(), c.Productsecret, c.Authorization)
	client.Token = c.Token

	devices, apierr := client.Devices()
	if apierr != nil {
		panic(apierr)
	}

	// FIXME: If there's more than one thermostat to work with this is going to be frustrating.
	for _, thermostat = range devices.Thermostats {
	}

	fmt.Fprintln(os.Stderr, thermostat)
}

package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/jsgoecke/nest"
	"github.com/pborman/uuid"
	"gopkg.in/yaml.v2"
)

var thermostat *nest.Thermostat

type NestConf struct {
	Productid     string
	Productsecret string
	Authorization string
	Token         string
}

func init() {
	f, err := ioutil.ReadFile("./nest.yml")
	if err != nil {
		panic(err)
	}

	var c NestConf
	err = yaml.Unmarshal(f, &c)
	if err != nil {
		panic(err)
	}

	client := nest.New(c.Productid, uuid.NewUUID().String(), c.Productsecret, c.Authorization)
	client.Token = c.Token

	devices, apierr := client.Devices()
	if apierr != nil {
		panic(apierr)
	}

	// FIXME: If there's more than one thermostat to work with this is going to be frustrating.
	for _, thermostat = range devices.Thermostats {
	}

	fmt.Fprintln(os.Stderr, thermostat)
}

Update to the new uuid project home.


package buildah

import (
	"os/user"
	"strconv"

	"github.com/opencontainers/runtime-spec/specs-go"
)

// TODO: we should doing these lookups using data that's actually in the container.
func getUser(username string) (specs.User, error) {
	if username == "" {
		return specs.User{}, nil
	}
	runuser, err := user.Lookup(username)
	if err != nil {
		return specs.User{}, err
	}
	uid, err := strconv.ParseUint(runuser.Uid, 10, 32)
	if err != nil {
		return specs.User{}, nil
	}
	gid, err := strconv.ParseUint(runuser.Gid, 10, 32)
	if err != nil {
		return specs.User{}, nil
	}
	groups, err := runuser.GroupIds()
	if err != nil {
		return specs.User{}, err
	}
	gids := []uint32{}
	for _, group := range groups {
		if g, err := user.LookupGroup(group); err == nil {
			if gid, err := strconv.ParseUint(g.Gid, 10, 32); err == nil {
				gids = append(gids, uint32(gid))
			}
		}
	}
	u := specs.User{
		UID:            uint32(uid),
		GID:            uint32(gid),
		AdditionalGids: gids,
		Username:       username,
	}
	return u, nil
}

package buildah

import (
	"os/user"
	"strconv"

	"github.com/opencontainers/runtime-spec/specs-go"
)

// TODO: we should doing these lookups using data that's actually in the container.
func getUser(username string) (specs.User, error) {
	if username == "" {
		return specs.User{}, nil
	}
	runuser, err := user.Lookup(username)
	if err != nil {
		return specs.User{}, err
	}
	uid, err := strconv.ParseUint(runuser.Uid, 10, 32)
	if err != nil {
		return specs.User{}, nil
	}
	gid, err := strconv.ParseUint(runuser.Gid, 10, 32)
	if err != nil {
		return specs.User{}, nil
	}
	u := specs.User{
		UID:      uint32(uid),
		GID:      uint32(gid),
		Username: username,
	}
	return u, nil
}

Drop supplemental groups for "run"


package gockle

import (
	"fmt"

	"github.com/maraino/go-mock"
)

var mySession = &SessionMock{}

func Example_dump() {
	var rows, _ = mySession.QuerySliceMap("select * from users")

	for _, row := range rows {
		fmt.Println(row)
	}
}

func Example_insert() {
	mySession.QueryExec("insert into users (id, name) values (123, 'me')")
}

func Example_print() {
	var i = mySession.QueryIterator("select * from users")

	for done := false; !done; {
		var m = map[string]interface{}{}

		done = i.ScanMap(m)

		fmt.Println(m)
	}
}

func init() {
	var i = &IteratorMock{}

	i.When("ScanMap", mock.Any).Call(func(m map[string]interface{}) bool {
		m["id"] = 123
		m["name"] = "me"

		return false
	})

	i.When("Close").Return(nil)

	mySession.When("QueryExec", mock.Any).Return(nil)
	mySession.When("QueryIterator", mock.Any).Return(i)
	mySession.When("QueryScanMap", mock.Any).Return(map[string]interface{}{"id": 1, "name": "me"}, nil)
}

package gockle

import (
	"fmt"

	"github.com/maraino/go-mock"
)

var mySession = &SessionMock{}

func ExampleBatch() {
	var b = mySession.QueryBatch(BatchLogged)

	b.Query("insert into users (id, name) values (123, 'me')")
	b.Query("insert into users (id, name) values (456, 'you')")

	b.Exec()
}

func ExampleIterator() {
	var i = mySession.QueryIterator("select * from users")

	for done := false; !done; {
		var m = map[string]interface{}{}

		done = i.ScanMap(m)

		fmt.Println(m)
	}
}

func ExampleSession() {
	var rows, _ = mySession.QuerySliceMap("select * from users")

	for _, row := range rows {
		fmt.Println(row)
	}
}

func init() {
	var i = &IteratorMock{}

	i.When("ScanMap", mock.Any).Call(func(m map[string]interface{}) bool {
		m["id"] = 123
		m["name"] = "me"

		return false
	})

	i.When("Close").Return(nil)

	mySession.When("QueryExec", mock.Any).Return(nil)
	mySession.When("QueryIterator", mock.Any).Return(i)
	mySession.When("QueryScanMap", mock.Any).Return(map[string]interface{}{"id": 1, "name": "me"}, nil)
}

Put some Session examples into other types


package saml2aws

import (
	"fmt"
	"strings"
)

// AWSRole aws role attributes
type AWSRole struct {
	RoleARN      string
	PrincipalARN string
	Name         string
}

// ParseAWSRoles parses and splits the roles while also validating the contents
func ParseAWSRoles(roles []string) ([]*AWSRole, error) {
	awsRoles := make([]*AWSRole, len(roles))

	for i, role := range roles {
		awsRole, err := parseRole(role)
		if err != nil {
			return nil, err
		}

		awsRoles[i] = awsRole
	}

	return awsRoles, nil
}

func parseRole(role string) (*AWSRole, error) {
	tokens := strings.Split(role, ",")

	if len(tokens) != 2 {
		return nil, fmt.Errorf("Invalid role string only %d tokens", len(tokens))
	}

	awsRole := &AWSRole{}

	for _, token := range tokens {
		if strings.Contains(token, ":saml-provider") {
			awsRole.PrincipalARN = token
		}
		if strings.Contains(token, ":role") {
			awsRole.RoleARN = token
		}
	}

	if awsRole.PrincipalARN == "" {
		return nil, fmt.Errorf("Unable to locate PrincipalARN in: %s", role)
	}

	if awsRole.RoleARN == "" {
		return nil, fmt.Errorf("Unable to locate RoleARN in: %s", role)
	}

	return awsRole, nil
}

package saml2aws

import (
	"fmt"
	"strings"
)

// AWSRole aws role attributes
type AWSRole struct {
	RoleARN      string
	PrincipalARN string
	Name         string
}

// ParseAWSRoles parses and splits the roles while also validating the contents
func ParseAWSRoles(roles []string) ([]*AWSRole, error) {
	awsRoles := make([]*AWSRole, len(roles))

	for i, role := range roles {
		awsRole, err := parseRole(role)
		if err != nil {
			return nil, err
		}

		awsRoles[i] = awsRole
	}

	return awsRoles, nil
}

func parseRole(role string) (*AWSRole, error) {
	tokens := strings.Split(role, ",")

	if len(tokens) != 2 {
		return nil, fmt.Errorf("Invalid role string only %d tokens", len(tokens))
	}

	awsRole := &AWSRole{}

	for _, token := range tokens {
		if strings.Contains(token, ":saml-provider") {
			awsRole.PrincipalARN = strings.TrimSpace(token)
		}
		if strings.Contains(token, ":role") {
			awsRole.RoleARN = strings.TrimSpace(token)
		}
	}

	if awsRole.PrincipalARN == "" {
		return nil, fmt.Errorf("Unable to locate PrincipalARN in: %s", role)
	}

	if awsRole.RoleARN == "" {
		return nil, fmt.Errorf("Unable to locate RoleARN in: %s", role)
	}

	return awsRole, nil
}

Trim whitespace on extracted role ARNs


package allyourbase

import (
	"fmt"
	"math"
)

func ConvertToBase(inputBase int, inputDigits []int, outputBase int) (outputDigits []int, e error) {
	base10 := getBase10Input(inputBase, inputDigits)
	if base10 == 0 {
		return []int{0}, nil
	}
	for base10 > 0 {
		digit := base10 % outputBase
		outputDigits = append([]int{digit}, outputDigits...)
		base10 = base10 / outputBase
	}
	return outputDigits, nil
}

func getBase10Input(inputBase int, inputDigits []int) (base10Input int) {
	for i, digit := range reverse(inputDigits) {
		base10Input += powInt(inputBase, i) * digit
	}
	fmt.Printf("getBase10Input(%d, %v)=%d\n", inputBase, inputDigits, base10Input)
	return base10Input
}

func reverse(input []int) (reversed []int) {
	for i := len(input) - 1; i >= 0; i-- {
		reversed = append(reversed, input[i])
	}
	return reversed
}

func powInt(x, y int) int {
	return int(math.Pow(float64(x), float64(y)))
}

package allyourbase

import (
	"errors"
	"fmt"
	"math"
)

func ConvertToBase(inputBase int, inputDigits []int, outputBase int) (outputDigits []int, e error) {
	if inputBase < 2 {
		return []int{}, errors.New("input base must be >= 2")
	}
	base10 := getBase10Input(inputBase, inputDigits)
	if base10 == 0 {
		return []int{0}, nil
	}
	for base10 > 0 {
		digit := base10 % outputBase
		outputDigits = append([]int{digit}, outputDigits...)
		base10 = base10 / outputBase
	}
	return outputDigits, nil
}

func getBase10Input(inputBase int, inputDigits []int) (base10Input int) {
	for i, digit := range reverse(inputDigits) {
		base10Input += powInt(inputBase, i) * digit
	}
	fmt.Printf("getBase10Input(%d, %v)=%d\n", inputBase, inputDigits, base10Input)
	return base10Input
}

func reverse(input []int) (reversed []int) {
	for i := len(input) - 1; i >= 0; i-- {
		reversed = append(reversed, input[i])
	}
	return reversed
}

func powInt(x, y int) int {
	return int(math.Pow(float64(x), float64(y)))
}

Return error for invalid base


// Package thread is designed for manage OS thread parameters. Usually you
// need to call runtime.LockOSThread before use it.
//
// Only String methods allocates memory (mainly because using of fmt package)
// so don't use them when GC is disabled.
package thread

import (
	"fmt"
	"github.com/ziutek/sched"
	"syscall"
)

type Thread struct {
	tid int
}

func Current() Thread {
	tid, _, e := syscall.RawSyscall(syscall.SYS_GETTID, 0, 0, 0)
	if e != 0 {
		panic(e)
	}
	return Thread{int(tid)}
}

func (t Thread) String() string {
	return fmt.Sprint("TID=", t.tid)
}

func (t Thread) SetSchedPolicy(policy sched.Policy, param *sched.Param) error {
	return sched.SetPolicy(t.tid, policy, param)
}

func (t Thread) SchedPolicy() (sched.Policy, error) {
	return sched.GetPolicy(t.tid)
}

func (t Thread) SetSchedParam(param *sched.Param) error {
	return sched.SetParam(t.tid, param)
}

func (t Thread) SchedParam(param *sched.Param) error {
	return sched.GetParam(t.tid, param)
}

// Package thread is designed for manage OS thread parameters. Usually you
// need to call runtime.LockOSThread before use it.
//
// Only String methods allocates memory (mainly because using of fmt package)
// so don't use them when GC is disabled.
package thread

import (
	"fmt"
	"github.com/ziutek/sched"
	"syscall"
)

type Thread struct {
	tid int
}

func Current() Thread {
	tid, _, e := syscall.RawSyscall(syscall.SYS_GETTID, 0, 0, 0)
	if e != 0 {
		panic(e)
	}
	return Thread{int(tid)}
}

func (t Thread) String() string {
	return fmt.Sprint(t.tid)
}

func (t Thread) SetSchedPolicy(policy sched.Policy, param *sched.Param) error {
	return sched.SetPolicy(t.tid, policy, param)
}

func (t Thread) SchedPolicy() (sched.Policy, error) {
	return sched.GetPolicy(t.tid)
}

func (t Thread) SetSchedParam(param *sched.Param) error {
	return sched.SetParam(t.tid, param)
}

func (t Thread) SchedParam(param *sched.Param) error {
	return sched.GetParam(t.tid, param)
}

Remove TID= from string representation of thread


package main

import (
	"io/ioutil"
	"strings"
)

var airlineCodes AirlineCodes

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func init() {
	tableName := "airline"
	tableFields := []string{"Id", "Name", "IATA", "ICAO", "CallSign", "Country", "Comments"}

	CreateTable("127.0.0.1", "picasso", "picasso", "picasso", tableName)

	dat, err := ioutil.ReadFile("airline_codes.csv")
	check(err)

	lines := strings.Split(string(dat), "\n")

	for _, line := range lines {
		if strings.Contains(line, ",") {
			tokens := strings.Split(line, ",")

			if len(tokens[3]) == 0 {
				continue
			}

			AddRow(tableName, tableFields, append(tokens[:2], tokens[3:]...))
		}
	}
}

package main

import (
	"io/ioutil"
	"strings"
)

var airlineCodes AirlineCodes

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func init() {
	tableName := "airline"
	tableFields := []string{"Id", "Name", "IATA", "ICAO", "CallSign", "Country", "Comments"}

	mysql := GetServiceURI("mysql")
	CreateTable(mysql, "picasso", "picasso", "picasso", tableName)

	dat, err := ioutil.ReadFile("airline_codes.csv")
	check(err)

	lines := strings.Split(string(dat), "\n")

	for _, line := range lines {
		if strings.Contains(line, ",") {
			tokens := strings.Split(line, ",")

			if len(tokens[3]) == 0 {
				continue
			}

			AddRow(tableName, tableFields, append(tokens[:2], tokens[3:]...))
		}
	}
}

Put the mysql address in etcd


package window

/*
#cgo darwin CFLAGS:   -F/Library/Frameworks -D_GOSMF_OSX_
#cgo darwin LDFLAGS:  -F/Library/Frameworks -framework SDL2

#cgo linux CFLAGS:    -D_GOSMF_LINUX_
#cgo linux LDFLAGS:   -lSDL2main -lSDL2

#cgo windows CFLAGS:  -D_GOSMF_WINDOWS_
#cgo windows LDFLAGS: -lSDL2main -lSDL2
*/
import "C"

package window

/*
#cgo darwin CFLAGS:   -D_GOSMF_OSX_
#cgo darwin LDFLAGS:  -F/Library/Frameworks -framework SDL2

#cgo linux CFLAGS:    -D_GOSMF_LINUX_
#cgo linux LDFLAGS:   -lSDL2main -lSDL2

#cgo windows CFLAGS:  -D_GOSMF_WINDOWS_
#cgo windows LDFLAGS: -lSDL2main -lSDL2
*/
import "C"

Fix invalid CFLAG for golang v1.9.4


package config

import (
	"fmt"
	"testing"

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

func TestTrackIgnoreString(t *testing.T) {
	track := &Track{
		IgnorePatterns: []string{
			"con[.]txt",
			"pro.f",
		},
	}

	testCases := map[string]bool{
		"falcon.txt": false,
		"beacon|txt": true,
		"beacon.ext": true,
		"proof":      false,
	}

	for name, ok := range testCases {
		testName := fmt.Sprintf("%s is %s", name, acceptability(ok))
		t.Run(testName, func(t *testing.T) {
			acceptable, err := track.AcceptFilename(name)
			assert.NoError(t, err, name)
			assert.Equal(t, ok, acceptable, testName)
		})
	}
}

func acceptability(ok bool) string {
	if ok {
		return "fine"
	}
	return "not acceptable"
}

package config

import (
	"fmt"
	"testing"

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

func TestTrackIgnoreString(t *testing.T) {
	track := &Track{
		IgnorePatterns: []string{
			"con[.]txt",
			"pro.f",
		},
	}

	testCases := map[string]bool{
		"falcon.txt": false,
		"beacon|txt": true,
		"beacon.ext": true,
		"proof":      false,
	}

	for name, ok := range testCases {
		t.Run(name, func(t *testing.T) {
			acceptable, err := track.AcceptFilename(name)
			assert.NoError(t, err, name)
			assert.Equal(t, ok, acceptable, fmt.Sprintf("%s is %s", name, acceptability(ok)))
		})
	}
}

func acceptability(ok bool) string {
	if ok {
		return "fine"
	}
	return "not acceptable"
}

Remove unnecessary duplication in track test


package main

import (
	"code.tobolaski.com/btobolaski/terraform-linode"
	"github.com/hashicorp/terraform/plugin"
)

func main() {
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: linode.Provider,
	})
}

package main

import (
	"github.com/btobolaskiterraform-linode"
	"github.com/hashicorp/terraform/plugin"
)

func main() {
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: linode.Provider,
	})
}

Rename the project for github


package eparser

import (
	"testing"
)

func TestLex(t *testing.T) {
	l := newLexer()
	res, errs := l.Lex("a **= (7 ** (3 + 4 - 2)) << 1.23 % 0.3")
	expected := []tokenType{
		IDENT, POW_EQ, LPAREN, INT, POW, LPAREN, INT, ADD, INT, SUB, INT,
		RPAREN, RPAREN, LSH, FLOAT, REM, FLOAT, EOL,
	}

	if errs != nil {
		t.Error("lexer error(s) found")
	}

	for k, v := range res {
		if expected[k] != v.Type {
			t.Error("mismatched token")
		}
	}
}

func TestUTF8(t *testing.T) {
	if !isIdent('Å') || !isIdent('Ś') {
		t.Error("isIdent doesn't recognize unicode characters")
	}
}

package eparser

import (
	"testing"
)

func TestLex(t *testing.T) {
	l := newLexer()
	res, errs := l.Lex("some_var123 **= (7 ** (3 + 4 - 2)) << 1.23 % 0.3")
	expected := []tokenType{
		IDENT, POW_EQ, LPAREN, INT, POW, LPAREN, INT, ADD, INT, SUB, INT,
		RPAREN, RPAREN, LSH, FLOAT, REM, FLOAT, EOL,
	}

	if errs != nil {
		t.Error("lexer error(s) found")
	}

	for k, v := range res {
		if expected[k] != v.Type {
			t.Error("mismatched token")
		}
	}
}

func TestUTF8(t *testing.T) {
	if !isIdent('Å') || !isIdent('Ś') {
		t.Error("isIdent doesn't recognize unicode characters")
	}
}

Test identifier reader inside lexer test


package main

import (
	"errors"
	"log"

	"github.com/mattn/go-mastodon"
	"github.com/urfave/cli"
)

func cmdToot(c *cli.Context) error {
	if !c.Args().Present() {
		return errors.New("arguments required")
	}

	var toot string
	ff := c.String("ff")
	if ff != "" {
		text, err := readFile(ff)
		if err != nil {
			log.Fatal(err)
		}
		toot = string(text)
	} else {
		toot = argstr(c)
	}
	client := c.App.Metadata["client"].(*mastodon.Client)
	_, err := client.PostStatus(&mastodon.Toot{
		Status: toot,
	})
	return err
}

package main

import (
	"errors"
	"log"

	"github.com/mattn/go-mastodon"
	"github.com/urfave/cli"
)

func cmdToot(c *cli.Context) error {
	var toot string
	ff := c.String("ff")
	if ff != "" {
		text, err := readFile(ff)
		if err != nil {
			log.Fatal(err)
		}
		toot = string(text)
	} else {
		if !c.Args().Present() {
			return errors.New("arguments required")
		}
		toot = argstr(c)
	}
	client := c.App.Metadata["client"].(*mastodon.Client)
	_, err := client.PostStatus(&mastodon.Toot{
		Status: toot,
	})
	return err
}

Fix `mstdn.exe toot -ff -` errors `arguments required`


// Copyright 2012 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.

// +build solaris

// Sockets for Solaris

package net

import (
	"syscall"
)

func maxListenerBacklog() int {
	// The kernel does not track the limit.
	return syscall.SOMAXCONN
}

func listenerSockaddr(s, f int, la syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (syscall.Sockaddr, error) {
	a := toAddr(la)
	if a == nil {
		return la, nil
	}
	switch v := a.(type) {
	case *TCPAddr, *UnixAddr:
		err := setDefaultListenerSockopts(s)
		if err != nil {
			return nil, err
		}
	case *UDPAddr:
		if v.IP.IsMulticast() {
			err := setDefaultMulticastSockopts(s)
			if err != nil {
				return nil, err
			}
			switch f {
			case syscall.AF_INET:
				v.IP = IPv4zero
			case syscall.AF_INET6:
				v.IP = IPv6unspecified
			}
			return v.sockaddr(f)
		}
	}
	return la, nil
}

Remove Solaris-specific version of listenerSockaddr.


package ws2801_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/declanshanaghy/bbqberry/ws2801"
)

var _ = Describe("WS2801", func() {
	var (
		strand Strand
	)

	BeforeEach(func() {
		strand := Strand{}
		strand.Init(10)
	})

	AfterEach(func() {
		strand.Close()
	})

	Describe("Basic test", func() {
		Context("of pixel validation", func() {
			It("should fail on invalid range", func() {
				n := strand.GetNumPixels()

				Expect(func() {
					strand.ValidatePixel(n+1)
				}).To(Panic())
			})
		})
	})
})

package ws2801_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/declanshanaghy/bbqberry/ws2801"
)

var _ = Describe("WS2801", func() {
	var (
		strand *Strand
	)

	BeforeEach(func() {
		strand = NewWS2801(10, 0)
	})

	AfterEach(func() {
		strand.Close()
	})

	Describe("Basic test", func() {
		Context("of pixel validation", func() {
			It("should fail on invalid range", func() {
				n := strand.GetNumPixels()

				Expect(func() {
					strand.ValidatePixel(n+1)
				}).To(Panic())
			})
		})
	})
})

Fix unittest compilation. Still need to figure out execution on mac


package validate

import (
	"fmt"
	"log"
	"os"
	"path"

	"github.com/gobuffalo/packr"
	"github.com/xeipuuv/gojsonschema"
)

// ValidateJSON is used to check for validity
func ValidateJSON(doc string) bool {

	file := path.Join("file:///", GetPath(), "/", doc)
	box := packr.NewBox("../../../")
	s, err := box.MustString("schema.json")
	if err != nil {
		panic(err.Error())
	}
	schemaLoader := gojsonschema.NewStringLoader(s)
	documentLoader := gojsonschema.NewReferenceLoader(file)
	result, err := gojsonschema.Validate(schemaLoader, documentLoader)
	if err != nil {
		panic(err.Error())
	}

	if result.Valid() {
		fmt.Printf("The document is valid\n")
		return true
	} else {
		fmt.Printf("The document is not valid. see errors :\n")
		for _, desc := range result.Errors() {
			fmt.Printf("- %s\n", desc)
		}
		return false
	}

}

// GetPath is used to get current path
func GetPath() string {
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	return dir
}

package validate

import (
	"fmt"
	"log"
	"os"
	"path"

	"github.com/gobuffalo/packr"
	"github.com/xeipuuv/gojsonschema"
)

// ValidateJSON is used to check for validity
func ValidateJSON(doc string) bool {

	file := path.Join("file:///", GetPath(), "/", doc)
	s := GetSchema()
	schemaLoader := gojsonschema.NewStringLoader(s)
	documentLoader := gojsonschema.NewReferenceLoader(file)
	result, err := gojsonschema.Validate(schemaLoader, documentLoader)
	if err != nil {
		panic(err.Error())
	}

	if result.Valid() {
		fmt.Printf("The document is valid\n")
		return true
	} else {
		fmt.Printf("The document is not valid. see errors :\n")
		for _, desc := range result.Errors() {
			fmt.Printf("- %s\n", desc)
		}
		return false
	}

}

// GetPath is used to get current path
func GetPath() string {
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	return dir
}

//GetSchema is used to obtain the string representation of schema.json via packr
func GetSchema() string {
	box := packr.NewBox("../../../")
	s, err := box.MustString("schema.json")
	if err != nil {
		panic(err.Error())
	}
	return s
}

Create generic packr function to get schema


package middleware

import (
	"github.com/gin-gonic/gin"

	oauth_service "github.com/torinos-io/api/service/oauth_service"
	user_store "github.com/torinos-io/api/store/user_store"
	"github.com/torinos-io/api/type/system"
)

const (
	currentuser = "CurrentUser"
)

// SetCurrentUser sets current authenticated user from authorization header
func SetCurrentUser(appContext *system.AppContext) gin.HandlerFunc {
	return func(c *gin.Context) {

		h := c.GetHeader("Authorization")

		if h == "" {
			c.Next()
			return
		}

		userStore := user_store.New(appContext.MainDB)
		service := oauth_service.New(oauth_service.Context{
			Config:    appContext.Config,
			UserStore: userStore,
		})

		user, err := service.FindByAuthToken(h)

		if err != nil {
			c.Next()
			return
		}

		c.Set(currentuser, user)
		c.Next()
	}
}

package middleware

import (
	"github.com/gin-gonic/gin"

	oauth_service "github.com/torinos-io/api/service/oauth_service"
	user_store "github.com/torinos-io/api/store/user_store"
	"github.com/torinos-io/api/type/system"
)

const (
	currentUserContextName = "CurrentUser"
)

// SetCurrentUser sets current authenticated user from authorization header
func SetCurrentUser(appContext *system.AppContext) gin.HandlerFunc {
	return func(c *gin.Context) {
		h := c.GetHeader("Authorization")

		if h == "" {
			c.Next()
			return
		}

		userStore := user_store.New(appContext.MainDB)
		service := oauth_service.New(oauth_service.Context{
			Config:    appContext.Config,
			UserStore: userStore,
		})

		user, err := service.FindByAuthToken(h)

		if err != nil {
			c.Next()
			return
		}

		c.Set(currentUserContextName, user)
		c.Next()
	}
}

Rename current user const value name


package getter

import "net/url"

// RedactURL is a port of url.Redacted from the standard library,
// which is like url.String but replaces any password with "xxxxx".
// Only the password in u.URL is redacted. This allows the library
// to maintain compatibility with go1.14.
func RedactURL(u *url.URL) string {
	if u == nil {
		return ""
	}

	ru := *u
	if _, has := ru.User.Password(); has {
		ru.User = url.UserPassword(ru.User.Username(), "redacted")
	}
	q := ru.Query()
	if q.Get("sshkey") != "" {
		q.Set("sshkey", "redacted")
		ru.RawQuery = q.Encode()
	}
	return ru.String()
}

package getter

import "net/url"

// RedactURL is a port of url.Redacted from the standard library,
// which is like url.String but replaces any password with "redacted".
// Only the password in u.URL is redacted. This allows the library
// to maintain compatibility with go1.14.
// This port was also extended to redact SSH key from URL query parameter.
func RedactURL(u *url.URL) string {
	if u == nil {
		return ""
	}

	ru := *u
	if _, has := ru.User.Password(); has {
		ru.User = url.UserPassword(ru.User.Username(), "redacted")
	}
	q := ru.Query()
	if q.Get("sshkey") != "" {
		q.Set("sshkey", "redacted")
		ru.RawQuery = q.Encode()
	}
	return ru.String()
}

Redact SSH key from URL query parameter


package melrose

import "time"

type Playable interface {
	Play(Player, time.Duration)
}

type Player interface {
	PlayNote(Note, time.Duration)
	PlaySequence(Sequence, singleNoteDuration time.Duration)
}

package melrose

import "time"

type Playable interface {
	Play(Player, time.Duration)
}

type Player interface {
	PlayNote(Note, time.Duration)
	PlaySequence(Sequence, time.Duration)
}

Fix typo in Player interface


package bamstats

import (
	"encoding/json"
	"os"

	log "github.com/Sirupsen/logrus"
)

func check(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func max(a, b uint32) uint32 {
	if a < b {
		return b
	}
	return a
}

func min(a, b uint32) uint32 {
	if a < b {
		return a
	}
	return b
}

func OutputJson(stats interface{}) {
	b, err := json.MarshalIndent(stats, "", "\t")
	check(err)
	os.Stdout.Write(b)
}

package bamstats

import (
	"bufio"
	"encoding/json"
	"io"
	"os"

	log "github.com/Sirupsen/logrus"
)

func check(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func max(a, b uint32) uint32 {
	if a < b {
		return b
	}
	return a
}

func min(a, b uint32) uint32 {
	if a < b {
		return a
	}
	return b
}

func OutputJson(writer io.Writer, stats interface{}) {
	b, err := json.MarshalIndent(stats, "", "\t")
	check(err)
	writer.Write(b)
	if w, ok := writer.(*bufio.Writer); ok {
		w.Flush()
	}
}

func NewOutput(output string) io.Writer {
	switch output {
	case "-":
		return os.Stdout
	default:
		f, err := os.Create(output)
		check(err)
		return bufio.NewWriter(f)
	}
}

Add functions to output stats to file


package main

import (
	"flag"
	"log"
	"strconv"

	"git.astuart.co/andrew/limio"
)

var t = flag.String("t", "search", "the type of search to perform")
var rl = flag.String("r", "", "the rate limit")
var nc = flag.Bool("nocache", false, "skip cache")
var clr = flag.Bool("clear", false, "clear cache")

var downRate int

func init() {
	flag.Parse()

	orig := *rl
	if len(*rl) > 0 {
		rl := []byte(*rl)
		unit := rl[len(rl)-1]
		rl = rl[:len(rl)-1]
		qty, err := strconv.Atoi(string(rl))

		if err != nil {
			log.Printf("Bad quantity: %s\n", orig)
		}

		switch unit {
		case 'm':
			downRate = qty * limio.MB
		case 'k':
			downRate = qty * limio.KB
		}
	}
}

package main

import (
	"flag"
	"log"
	"os"
	"strconv"

	"git.astuart.co/andrew/limio"
)

var t = flag.String("t", "movie", "the type of search to perform")
var rl = flag.String("r", "", "the rate limit")
var nc = flag.Bool("nocache", false, "skip cache")
var clr = flag.Bool("clear", false, "clear cache")

var downRate int

func init() {
	flag.Parse()

	if *t == "tv" {
		*t = "tvsearch"
	}

	if *rl == "" {
		*rl = os.Getenv("SAB_RATE")
	}

	orig := *rl
	if len(*rl) > 0 {
		rl := []byte(*rl)
		unit := rl[len(rl)-1]
		rl = rl[:len(rl)-1]

		qty, err := strconv.ParseFloat(string(rl), 64)

		if err != nil {
			log.Printf("Bad quantity: %s\n", orig)
		}

		switch unit {
		case 'm':
			downRate = int(qty * float64(limio.MB))
		case 'k':
			downRate = int(qty * float64(limio.KB))
		}
	}
}

Allow shortening of "tvsearch" to "tv", "SAB_RATE" env, decimal rate arg


package main

import "os"
import "github.com/codegangsta/cli"

func main() {
	app := cli.NewApp()
	app.Name = "exercism"
	app.Usage = "fight the loneliness!"
	app.Action = func(c *cli.Context) {
		println("Hello friend!")
	}

	app.Run(os.Args)
}

package main

import "os"
import "github.com/codegangsta/cli"

func main() {
	app := cli.NewApp()
	app.Name = "exercism"
	app.Usage = "A command line tool to interact with http://exercism.io"
	app.Commands = []cli.Command{
		{
			Name:      "demo",
			ShortName: "d",
			Usage:     "Fetch first assignment for each language from exercism.io",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
		{
			Name:      "fetch",
			ShortName: "f",
			Usage:     "Fetch current assignment from exercism.io",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
		{
			Name:      "login",
			ShortName: "l",
			Usage:     "Save exercism.io api credentials",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
		{
			Name:      "logout",
			ShortName: "o",
			Usage:     "Clear exercism.io api credentials",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
		{
			Name:      "peek",
			ShortName: "p",
			Usage:     "Fetch upcoming assignment from exercism.io",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
		{
			Name:      "submit",
			ShortName: "s",
			Usage:     "Submit code to exercism.io on your current assignment",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
		{
			Name:      "whoami",
			ShortName: "w",
			Usage:     "Get the github username that you are logged in as",
			Action: func(c *cli.Context) {
				println("Not yet implemented")
			},
		},
	}
	app.Run(os.Args)
}

Add in all basic exercism commands.


package main

import (
	"flag"
	"fmt"

	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchevents"
)

func main() {
	var apply bool
	var dryrun bool
	var file string

	flag.BoolVar(&apply, "apply", false, "apply to CloudWatch Events")
	flag.BoolVar(&dryrun, "dry-run", false, "dry-run")
	flag.StringVar(&file, "file", "config.yml", "file path to setting yaml")
	flag.StringVar(&file, "f", "config.yml", "file path to setting yaml (shorthand)")
	flag.Parse()

	sess, err := session.NewSession(nil)
	if err != nil {
		fmt.Errorf("Error %v", err)
	}

	cwe := cloudwatchevents.New(sess)
	result, err := cwe.ListRules(nil)

	if err != nil {
		fmt.Println("Error", err)

	} else {
		fmt.Println("Success")
		fmt.Println(result)
	}
}

package main

import (
	"flag"
	"fmt"
	"io/ioutil"

	yaml "gopkg.in/yaml.v2"

	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchevents"
)

func main() {
	var apply bool
	var dryrun bool
	var file string

	flag.BoolVar(&apply, "apply", false, "apply to CloudWatch Events")
	flag.BoolVar(&dryrun, "dry-run", false, "dry-run")
	flag.StringVar(&file, "file", "config.yml", "file path to setting yaml")
	flag.StringVar(&file, "f", "config.yml", "file path to setting yaml (shorthand)")
	flag.Parse()

	sess, err := session.NewSession(nil)
	if err != nil {
		fmt.Errorf("Error %v", err)
	}

	rules := Rules{}
	err := loadYaml(file, &rules)
	if err != nil {
		return err
	}
}

func loadYaml(file string, r *Rules) error {

	buf, err := ioutil.ReadFile(file)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(buf, &r)
	if err != nil {
		return err
	}

	return nil
}

Load to structs from config yaml file


// Package `fmtmail` builds on top of the standard library's `net/mail`, by
// adding a single function:
//
//     func WriteMessage(w io.Writer, msg *mail.Message) error
//
// ...Which outputs the message to `w`.
//
// The basic functionality already works, but there are still some details
// to finish up:
//
// * Handle outputting "structured" fields; we can't just split everything
//   on character boundaries.
// * Go over RFC 5322 and make sure we're hitting all of the edge cases.
//   Right now we're probably missing some important stuff.
//
// Released under a simple permissive license, see `COPYING`.
package fmtmail

// Package `fmtmail` builds on top of the standard library's `net/mail`, by
// adding a single function:
//
//     func WriteMessage(w io.Writer, msg *mail.Message) error
//
// ...Which outputs the message to `w`.
//
// The basic functionality already works, but there are still some details
// to finish up:
//
// * Handle outputting "structured" fields; we can't just split everything
//   on character boundaries.
// * Go over RFC 5322 and make sure we're hitting all of the edge cases.
//   Right now we're probably missing some important stuff.
// * Investigate what we need to do to accomodate MIME.
//
// Released under a simple permissive license, see `COPYING`.
package fmtmail

Add a TODO to the readme


package model

import (
	"fmt"
)

type Host struct {
	Id   int
	Name string
}

func (this *Host) String() string {
	return fmt.Sprintf(
		"<id:%s,name:%s>",
		this.Id,
		this.Name,
	)
}

package model

import (
	"fmt"
)

type Host struct {
	Id   int
	Name string
}

func (this *Host) String() string {
	return fmt.Sprintf(
		"<id:%d,name:%s>",
		this.Id,
		this.Name,
	)
}

Fix wrong type error in coverage test.


package editor

import (
	"bytes"
	"strings"
	"testing"

	"github.com/elpinal/coco3/config"
)

type testScreen struct {
}

func (ts *testScreen) Refresh(prompt string, s []rune, pos int) {
}

func (ts *testScreen) SetLastLine(msg string) {
}

func TestEditor(t *testing.T) {
	inBuf := strings.NewReader("aaa" + string(CharCtrlM))
	var outBuf, errBuf bytes.Buffer
	e := New(&testScreen{}, &config.Config{}, inBuf, &outBuf, &errBuf)
	s, err := e.Read()
	if err != nil {
		t.Error(err)
	}
	if want := "aaa"; string(s) != want {
		t.Errorf("got %q, want %q", string(s), want)
	}
	e.Clear()
}

package editor

import (
	"bytes"
	"strings"
	"testing"

	"github.com/elpinal/coco3/config"
)

type testScreen struct {
}

func (ts *testScreen) Refresh(prompt string, s []rune, pos int) {
}

func (ts *testScreen) SetLastLine(msg string) {
}

func TestEditor(t *testing.T) {
	inBuf := strings.NewReader("aaa" + string(CharCtrlM))
	var outBuf, errBuf bytes.Buffer
	e := New(&testScreen{}, &config.Config{}, inBuf, &outBuf, &errBuf)
	s, err := e.Read()
	if err != nil {
		t.Error(err)
	}
	if want := "aaa"; string(s) != want {
		t.Errorf("got %q, want %q", string(s), want)
	}
	if got := outBuf.String(); got != "" {
		t.Errorf("got %q, want %q", got, "")
	}
	if got := errBuf.String(); got != "" {
		t.Errorf("got %q, want %q", got, "")
	}
	e.Clear()
}

Check if output and error are empty


package tools

import (
	"gopkg.in/mgo.v2"
	"fmt"
	"errors"
)

type SessionConf struct {
	Hosts    []string
	Database string
}

var (
	session *mgo.Session
)

func InitSession(conf SessionConf) *mgo.Session {
	var err error
	dialInfo := mgo.DialInfo{
		Addrs:    conf.Hosts,
		Database: conf.Database,
	}

	session, err = mgo.DialWithInfo(&dialInfo)

	if err != nil {
		panic(fmt.Sprintf("Failed to connect to DB server. %s", err))
	}
	return session
}

func GetSession() (*mgo.Session, error) {
	var err error
	if session == nil {
		err = errors.New("Session is not initialized")
	}
	return session, err
}

package tools

import (
	"gopkg.in/mgo.v2"
	"fmt"
	"errors"
)

type SessionConf mgo.DialInfo

var (
	session *mgo.Session
)

func InitSession(conf *SessionConf) *mgo.Session {
	var err error
	session, err = mgo.DialWithInfo((*mgo.DialInfo)(conf))

	if err != nil {
		panic(fmt.Sprintf("Failed to connect to DB server. %s", err))
	}
	return session
}

func GetSession() (*mgo.Session, error) {
	var err error
	if session == nil {
		err = errors.New("Session is not initialized")
	}
	return session, err
}

Make SessionConf into shortcut type for mgo.DialInfo


// Copyright 2015 The Chromium 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 parallel

import (
	"fmt"
)

func ExampleFanOutIn() {
	data := []int{1, 20}
	err := FanOutIn(func(ch chan<- func() error) {
		for _, d := range data {
			d := d
			ch <- func() error {
				if d > 10 {
					return fmt.Errorf("%d is over 10", d)
				}
				return nil
			}
		}
	})

	fmt.Printf("got: %q", err)
	// Output: got: "20 is over 10"
}

// Copyright 2015 The Chromium 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 parallel

import (
	"fmt"
	"sync/atomic"
	"testing"
)

func ExampleFanOutIn() {
	data := []int{1, 20}
	err := FanOutIn(func(ch chan<- func() error) {
		for _, d := range data {
			d := d
			ch <- func() error {
				if d > 10 {
					return fmt.Errorf("%d is over 10", d)
				}
				return nil
			}
		}
	})

	fmt.Printf("got: %q", err)
	// Output: got: "20 is over 10"
}

func TestRaciness(t *testing.T) {
	t.Parallel()

	val := int32(0)

	for i := 0; i < 100; i++ {
		FanOutIn(func(ch chan<- func() error) {
			ch <- func() error { atomic.AddInt32(&val, 1); return nil }
		})
	}

	if val != 100 {
		t.Error("val != 100, was", val)
	}
}

Add race test for parallel


package steamapi

import (
	"net/url"
	"strconv"
	"strings"
)

type playerBansJSON struct {
	Players []PlayerBan
}

// PlayerBan contains all ban status for community, VAC and economy
type PlayerBan struct {
	SteamID         uint64 `json:"SteamId,string"`
	CommunityBanned bool
	VACBanned       bool
	EconomyBan      string
}

// GetPlayerBans takes a list of steamIDs and returns PlayerBan slice
func GetPlayerBans(steamIDs []uint64, apiKey string) ([]PlayerBan, error) {
	var getPlayerBans = NewSteamMethod("ISteamUser", "GetPlayerBans", 1)
	strSteamIDs := make([]string, len(steamIDs))
	for _, id := range steamIDs {
		strSteamIDs = append(strSteamIDs, strconv.FormatUint(id, 10))
	}

	data := url.Values{}
	data.Add("key", apiKey)
	data.Add("steamids", strings.Join(strSteamIDs, ","))

	var resp playerBansJSON
	err := getPlayerBans.Request(data, &resp)
	if err != nil {
		return nil, err
	}

	return resp.Players, nil
}

package steamapi

import (
	"net/url"
	"strconv"
	"strings"
)

type playerBansJSON struct {
	Players []PlayerBan
}

// PlayerBan contains all ban status for community, VAC and economy
type PlayerBan struct {
	SteamID          uint64 `json:"SteamId,string"`
	CommunityBanned  bool
	VACBanned        bool
	EconomyBan       string
	NumberOfVACBans  uint
	DaysSinceLastBan uint
	NumberOfGameBans uint
}

// GetPlayerBans takes a list of steamIDs and returns PlayerBan slice
func GetPlayerBans(steamIDs []uint64, apiKey string) ([]PlayerBan, error) {
	var getPlayerBans = NewSteamMethod("ISteamUser", "GetPlayerBans", 1)
	strSteamIDs := make([]string, len(steamIDs))
	for _, id := range steamIDs {
		strSteamIDs = append(strSteamIDs, strconv.FormatUint(id, 10))
	}

	data := url.Values{}
	data.Add("key", apiKey)
	data.Add("steamids", strings.Join(strSteamIDs, ","))

	var resp playerBansJSON
	err := getPlayerBans.Request(data, &resp)
	if err != nil {
		return nil, err
	}

	return resp.Players, nil
}

Add missing fields from GetPlayerBans (v1) response


package main

import (
	"fmt"
	"testing"
)

func BenchmarkMapLookupKeyStringFromBytes(b *testing.B) {
	entries := 4096
	lookup := make(map[string]int, entries)
	for i := 0; i < entries; i++ {
		lookup[fmt.Sprintf("foo.%d", i)] = -1
	}

	find := []byte("foo.0")

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		// lookup[string(find)] = i
		if _, ok := lookup[string(find)]; !ok {
			b.Fatalf("key %s should exist", string(find))
		}
	}
}

func BenchmarkMapSetKeyStringFromBytes(b *testing.B) {
	entries := 4096
	lookup := make(map[string]int, entries)
	for i := 0; i < entries; i++ {
		lookup[fmt.Sprintf("foo.%d", i)] = -1
	}

	find := []byte("foo.0")

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		lookup[string(find)] = i
	}
}

package main

/*
Results
--
$ go test -v -bench BenchmarkMap -benchmem
testing: warning: no tests to run
BenchmarkMapLookupKeyStringFromBytes-4          100000000               19.6 ns/op             0 B/op          0 allocs/op
BenchmarkMapSetKeyStringFromBytes-4             20000000                73.8 ns/op             5 B/op          1 allocs/op
PASS
ok      github.com/robskillington/benchmarks-go 3.561s
*/

import (
	"fmt"
	"testing"
)

func BenchmarkMapLookupKeyStringFromBytes(b *testing.B) {
	entries := 4096
	lookup := make(map[string]int, entries)
	for i := 0; i < entries; i++ {
		lookup[fmt.Sprintf("foo.%d", i)] = -1
	}

	find := []byte("foo.0")

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		if _, ok := lookup[string(find)]; !ok {
			b.Fatalf("key %s should exist", string(find))
		}
	}
}

func BenchmarkMapSetKeyStringFromBytes(b *testing.B) {
	entries := 4096
	lookup := make(map[string]int, entries)
	for i := 0; i < entries; i++ {
		lookup[fmt.Sprintf("foo.%d", i)] = -1
	}

	find := []byte("foo.0")

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		lookup[string(find)] = i
	}
}

Add results for BenchmarkMapLookupKeyStringFromBytes and BenchmarkMapSetKeyStringFromBytes


package model

import (
	"github.com/guregu/null"
)

// Subscription represents user's notification settings.
type Subscription struct {
	ID          int      `json:"id"`
	UserID      null.Int `json:"user_id"`
	ProjectUUID string   `json:"project_uuid"`

	Email     string `json:"email"`
	DeletedAt Time   `json:"deleted_at"`
}

package model

import (
	"github.com/guregu/null"
)

// Subscription represents user's notification settings.
type Subscription struct {
	ID          int      `json:"id" gorm:"primary_key"`
	UserID      null.Int `json:"user_id" gorm:"ForeignKey:ID"`
	ProjectUUID string   `json:"project_uuid" gorm:"ForeignKey:UUID"`

	Email     string `json:"email"`
	DeletedAt Time   `json:"deleted_at"`
}

Set foreign key information to Subscription


package slack

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

	"github.com/pkg/errors"
)

type WebhookMessage struct {
	Username    string       `json:"username,omitempty"`
	IconEmoji   string       `json:"icon_emoji,omitempty"`
	IconURL     string       `json:"icon_url,omitempty"`
	Channel     string       `json:"channel,omitempty"`
	Text        string       `json:"text,omitempty"`
	Attachments []Attachment `json:"attachments,omitempty"`
}

func PostWebhook(url string, msg *WebhookMessage) error {
	raw, err := json.Marshal(msg)

	if err != nil {
		return errors.Wrap(err, "marshal failed")
	}

	response, err := http.Post(url, "application/json", bytes.NewReader(raw))

	if err != nil {
		return errors.Wrap(err, "failed to post webhook")
	}

	if response.StatusCode != http.StatusOK {
		return statusCodeError{Code: response.StatusCode, Status: response.Status}
	}

	return nil
}

package slack

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

	"github.com/pkg/errors"
)

type WebhookMessage struct {
	Username    string       `json:"username,omitempty"`
	IconEmoji   string       `json:"icon_emoji,omitempty"`
	IconURL     string       `json:"icon_url,omitempty"`
	Channel     string       `json:"channel,omitempty"`
	ThreadTS    string       `json:"thread_ts,omitempty"`
	Text        string       `json:"text,omitempty"`
	Attachments []Attachment `json:"attachments,omitempty"`
}

func PostWebhook(url string, msg *WebhookMessage) error {
	raw, err := json.Marshal(msg)

	if err != nil {
		return errors.Wrap(err, "marshal failed")
	}

	response, err := http.Post(url, "application/json", bytes.NewReader(raw))

	if err != nil {
		return errors.Wrap(err, "failed to post webhook")
	}

	if response.StatusCode != http.StatusOK {
		return statusCodeError{Code: response.StatusCode, Status: response.Status}
	}

	return nil
}

Support `thread_ts` parameter for Incoming Webhook


package tmdb

import (
	. "gopkg.in/check.v1"
)

func (s *TmdbSuite) TestConfiguration(c *C) {
	result, err := s.tmdb.Configuration()
	s.baseTest(&result, err, c)
	c.Assert(result.Images.BaseURL, Equals, "http://image.tmdb.org/t/p/")
	c.Assert(result.Images.SecureBaseURL, Equals, "https://image.tmdb.org/t/p/")
	c.Assert(len(result.Images.BackdropSizes), Equals, 4)
	c.Assert(len(result.ChangeKeys), Equals, 53)
}

package tmdb

import (
	. "gopkg.in/check.v1"
)

func (s *TmdbSuite) TestConfiguration(c *C) {
	result, err := s.tmdb.Configuration()
	s.baseTest(&result, err, c)
	c.Assert(result.Images.BaseURL, Equals, "http://image.tmdb.org/t/p/")
	c.Assert(result.Images.SecureBaseURL, Equals, "https://image.tmdb.org/t/p/")
	c.Assert(result.Images.BackdropSizes, HasLen, 4)
	c.Assert(result.ChangeKeys, HasLen, 53)
}

Switch assert to HasLen checker


// +build !js

package model

import (
	"context"

	"github.com/flimzy/kivik"
	_ "github.com/flimzy/kivik/driver/memory" // Memory driver
)

func localConnection() (kivikClient, error) {
	c, err := kivik.New(context.Background(), "memory", "local")
	if err != nil {
		return nil, err
	}
	return wrapClient(c), nil
}

func remoteConnection(_ string) (kivikClient, error) {
	c, err := kivik.New(context.Background(), "memory", "remote")
	if err != nil {
		return nil, err
	}
	return wrapClient(c), nil
}

// +build !js

package model

import (
	"context"

	"github.com/flimzy/kivik"
	_ "github.com/go-kivik/memorydb" // Kivik Memory driver
)

func localConnection() (kivikClient, error) {
	c, err := kivik.New(context.Background(), "memory", "local")
	if err != nil {
		return nil, err
	}
	return wrapClient(c), nil
}

func remoteConnection(_ string) (kivikClient, error) {
	c, err := kivik.New(context.Background(), "memory", "remote")
	if err != nil {
		return nil, err
	}
	return wrapClient(c), nil
}

Switch to new memory driver location


package main

import (
	. "fmt"
	"polydawn.net/dockctrl/confl"
	"polydawn.net/dockctrl/crocker"
)

/*
	Helps run anything that requires a docker connection.
	Handles creation & cleanup in one place.
	Docker daemon config is determined by looking around the cwd.
*/
func WithDocker(fn func(*crocker.Dock, *confl.ConfigLoad) error) error {
	//Load configuration, then find or start a docker
	settings := confl.NewConfigLoad(".")
	dock := crocker.NewDock("./dock")

	//Announce the docker
	if dock.IsChildProcess() {
		Println("Started a docker in", dock.Dir())
	} else {
		Println("Connecting to docker", dock.Dir())
	}

	//Run the closure, kill the docker if needed, and return any errors.
	err := fn(dock, settings)
	dock.Slay()
	return err
}

//Helper function: maps a TrionConfig struct to crocker function.
//Kinda ugly; this situation may improve once our config shenanigans solidifies a bit.
func Launch(dock *crocker.Dock, config crocker.ContainerConfig) *crocker.Container {
	return crocker.Launch(dock, config.Image, config.Command, config.Attach, config.Privileged, config.Folder, config.DNS, config.Mounts, config.Ports, config.Environment)
}

package main

import (
	. "fmt"
	"polydawn.net/dockctrl/confl"
	"polydawn.net/dockctrl/crocker"
)

/*
	Helps run anything that requires a docker connection.
	Handles creation & cleanup in one place.
	Docker daemon config is determined by looking around the cwd.
*/
func WithDocker(fn func(*crocker.Dock, *confl.ConfigLoad) error) error {
	//Load configuration, then find or start a docker
	settings := confl.NewConfigLoad(".")
	dock := crocker.NewDock(settings.Dock)

	//Announce the docker
	if dock.IsChildProcess() {
		Println("Started a docker in", dock.Dir())
	} else {
		Println("Connecting to docker", dock.Dir())
	}

	//Run the closure, kill the docker if needed, and return any errors.
	err := fn(dock, settings)
	dock.Slay()
	return err
}

//Helper function: maps a TrionConfig struct to crocker function.
//Kinda ugly; this situation may improve once our config shenanigans solidifies a bit.
func Launch(dock *crocker.Dock, config crocker.ContainerConfig) *crocker.Container {
	return crocker.Launch(dock, config.Image, config.Command, config.Attach, config.Privileged, config.Folder, config.DNS, config.Mounts, config.Ports, config.Environment)
}

Use a parent's dock folder if found.


package rpc

import (
	"cgl.tideland.biz/asserts"
	"net/rpc"
	"testing"
)

type testUi struct {
	sayCalled bool
	sayFormat string
	sayVars []interface{}
}

func (u *testUi) Say(format string, a ...interface{}) {
	u.sayCalled = true
	u.sayFormat = format
	u.sayVars = a
}

func TestUiRPC(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)

	// Create the UI to test
	ui := new(testUi)
	uiServer := &UiServer{ui}

	// Start the RPC server
	readyChan := make(chan int)
	stopChan := make(chan int)
	defer func() { stopChan <- 1 }()
	go testRPCServer(":1234", "Ui", uiServer, readyChan, stopChan)
	<-readyChan

	// Create the client over RPC and run some methods to verify it works
	client, err := rpc.Dial("tcp", ":1234")
	if err != nil {
		panic(err)
	}

	uiClient := &Ui{client}
	uiClient.Say("format", "arg0", 42)

	assert.Equal(ui.sayFormat, "format", "format should be correct")
}

package rpc

import (
	"cgl.tideland.biz/asserts"
	"net/rpc"
	"testing"
)

type testUi struct {
	sayCalled bool
	sayFormat string
	sayVars []interface{}
}

func (u *testUi) Say(format string, a ...interface{}) {
	u.sayCalled = true
	u.sayFormat = format
	u.sayVars = a
}

func TestUiRPC(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)

	// Create the UI to test
	ui := new(testUi)

	// Start the RPC server
	server := NewServer()
	server.RegisterUi(ui)
	server.Start()
	defer server.Stop()

	// Create the client over RPC and run some methods to verify it works
	client, err := rpc.Dial("tcp", server.Address())
	if err != nil {
		panic(err)
	}

	uiClient := &Ui{client}
	uiClient.Say("format", "arg0", 42)

	assert.Equal(ui.sayFormat, "format", "format should be correct")
}

Use the proper Server for tests


package storageconsul

import (
	"github.com/caddyserver/caddy/v2"
	"github.com/caddyserver/certmagic"
)

type TLSConsul struct {
	storage *ConsulStorage
}

func init() {
	caddy.RegisterModule(TLSConsul{})
}

func (TLSConsul) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "caddy.storage.tlsconsul",
		New: func() caddy.Module { return new(TLSConsul) },
	}
}

// Provision is called by Caddy to prepare the module
func (tlsc *TLSConsul) Provision(ctx caddy.Context) error {
	consulStorage, err := NewConsulStorage()
	if err != nil {
		return err
	}
	tlsc.storage = consulStorage
	return nil
}

func (tlsc *TLSConsul) CertMagicStorage() (certmagic.Storage, error) {
	return tlsc.storage, nil
}

package storageconsul

import (
	"github.com/caddyserver/caddy/v2"
	"github.com/caddyserver/certmagic"
)

type TLSConsul struct {
	storage *ConsulStorage
}

func init() {
	caddy.RegisterModule(&TLSConsul{})
}

func (TLSConsul) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "caddy.storage.tlsconsul",
		New: func() caddy.Module { return new(TLSConsul) },
	}
}

// Provision is called by Caddy to prepare the module
func (tlsc *TLSConsul) Provision(ctx caddy.Context) error {
	consulStorage, err := NewConsulStorage()
	if err != nil {
		return err
	}
	tlsc.storage = consulStorage
	return nil
}

func (tlsc *TLSConsul) CertMagicStorage() (certmagic.Storage, error) {
	return tlsc.storage, nil
}

Change to use pointer receiver


package main

import (
	"github.com/larzconwell/moln/config"
	"github.com/larzconwell/moln/loggers"
	"log"
	"os"
	"path/filepath"
)

func main() {
	env := "development"
	if len(os.Args) > 1 {
		env = os.Args[1]
	}

	conf, err := config.ReadFiles("config/environment.json", "config/"+env+".json")
	if err != nil {
		log.Fatalln(err)
	}

	errorLogger, errorLogFile, err := loggers.Error(filepath.Join(conf.LogDir, "errors"))
	if err != nil {
		log.Fatalln(err)
	}
	defer errorLogFile.Close()

	logFile, err := loggers.Access(conf.LogDir)
	if err != nil {
		errorLogger.Fatalln(err)
	}
	defer logFile.Close()
}

package main

import (
	"github.com/gorilla/mux"
	"github.com/larzconwell/moln/config"
	"github.com/larzconwell/moln/loggers"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

func main() {
	env := "development"
	if len(os.Args) > 1 {
		env = os.Args[1]
	}

	conf, err := config.ReadFiles("config/environment.json", "config/"+env+".json")
	if err != nil {
		log.Fatalln(err)
	}

	errorLogger, errorLogFile, err := loggers.Error(filepath.Join(conf.LogDir, "errors"))
	if err != nil {
		log.Fatalln(err)
	}
	defer errorLogFile.Close()

	logFile, err := loggers.Access(conf.LogDir)
	if err != nil {
		errorLogger.Fatalln(err)
	}
	defer logFile.Close()

	router := mux.NewRouter()
	server := &http.Server{
		Addr:         conf.ServerAddr,
		Handler:      router,
		ReadTimeout:  conf.MaxTimeout,
		WriteTimeout: conf.MaxTimeout,
	}

	if conf.TLS != nil {
		err = server.ListenAndServeTLS(conf.TLS.Cert, conf.TLS.Key)
	} else {
		err = server.ListenAndServe()
	}
	if err != nil {
		errorLogger.Fatal(err)
	}
}

Add router and start server


package frame

// Interface Sequence is used to manipulate with frames, which can be used more
// than one time (e.g. APIC, COMM, USLT, SYLT and etc.)
type Sequencer interface {
	AddFrame(Framer)
	Frames() []Framer
}

package frame

// Interface Sequence is used to manipulate with frames, which can be in tag
// more than one (e.g. APIC, COMM, USLT, SYLT and etc.)
type Sequencer interface {
	AddFrame(Framer)
	Frames() []Framer
}

Make clearer comment in Sequencer interface


package main

import (
  "github.com/simon-engledew/gocmdpev/gopev"
  "io/ioutil"
  "github.com/fatih/color"
  "log"
  "os"
)

func main() {
  buffer, err := ioutil.ReadAll(os.Stdin)

  if err != nil {
    log.Fatalf("%v", err)
  }

  // fmt.Println(string(buffer))

  err = gopev.Visualize(color.Output, buffer)

  if err != nil {
    log.Fatalf("%v", err)
  }
}

package main

import (
  "github.com/simon-engledew/gocmdpev/gopev"
  "gopkg.in/alecthomas/kingpin.v2"
  "io/ioutil"
  "github.com/fatih/color"
  "log"
  "os"
)

func main() {
  kingpin.CommandLine.HelpFlag.Short('h')
  kingpin.CommandLine.Version("1.0.0")
  kingpin.CommandLine.VersionFlag.Short('v')
  kingpin.Parse()

  buffer, err := ioutil.ReadAll(os.Stdin)

  if err != nil {
    log.Fatalf("%v", err)
  }

  // fmt.Println(string(buffer))

  err = gopev.Visualize(color.Output, buffer)

  if err != nil {
    log.Fatalf("%v", err)
  }
}

Use kingpin to add a -v/-h to use as Homebrew's test method


package meep

func Try(fn func(), plan TryPlan) {
	defer func() {
		if err := coerce(recover()); err != nil {
			plan.MustHandle(err)
		}
	}()
	fn()
}

func coerce(rcvrd interface{}) error {
	switch err := rcvrd.(type) {
	case nil:
		// Panics of nils are possible btw but super absurd.  Never do it.
		return nil
	case error:
		return err
	default:
		// Panics of non-error types are bad and you should feel bad.
		return New(&ErrUntypedPanic{Cause: rcvrd})
	}
}

/*
	A wrapper for non-error types raised from a panic.

	The `Try` system will coerce all non-error types to this automatically.
*/
type ErrUntypedPanic struct {
	TraitAutodescribing
	TraitTraceable
	Cause interface{}
}

package meep

func RecoverPanics(fn func()) (e error) {
	defer func() {
		e = coerce(recover())
	}()
	fn()
	return
}

func Try(fn func(), plan TryPlan) {
	plan.MustHandle(RecoverPanics(fn))
}

func coerce(rcvrd interface{}) error {
	switch err := rcvrd.(type) {
	case nil:
		// Panics of nils are possible btw but super absurd.  Never do it.
		return nil
	case error:
		return err
	default:
		// Panics of non-error types are bad and you should feel bad.
		return New(&ErrUntypedPanic{Cause: rcvrd})
	}
}

/*
	A wrapper for non-error types raised from a panic.

	The `Try` system will coerce all non-error types to this automatically.
*/
type ErrUntypedPanic struct {
	TraitAutodescribing
	TraitTraceable
	Cause interface{}
}

Add RecoverPanics helper function that's almost entirely unopinionated.


package server

import (
	"errors"
	"sync"
)

type ClientPool struct {
	mutex   sync.RWMutex
	clients map[string]*Client
}

func NewClientPool() *ClientPool {
	p := new(ClientPool)
	p.clients = make(map[string]*Client)
	return p
}

func (cp *ClientPool) Add(c *Client) error {
	cp.mutex.Lock()
	defer cp.mutex.Unlock()

	if _, ok := cp.clients[c.Name]; ok {
		return errors.New("Client with this name already exists")
	}

	cp.clients[c.Name] = c
	return nil
}

func (cp *ClientPool) Remove(c *Client) {
	cp.mutex.Lock()
	defer cp.mutex.Unlock()

	delete(cp.clients, c.Name)
}

func (cp *ClientPool) Broadcast(sender *Client, m []byte) {
	cp.mutex.RLock()
	defer cp.mutex.RUnlock()

	for _, client := range cp.clients {
		client.Send(sender, m)
	}
}

Remove broadcast from the client pool


package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
)

const FILE string = "Makefile"
const PROG string = "make"

/* TODO:
add stopping at homedir
configurable filename for aliases?
*/
func main() {
	checkDir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	for {
		//fmt.Println("Checking:", checkDir)
		if existsAtPath(checkDir) {
			//fmt.Println("FOUND IT in", checkDir)
			os.Exit(runAt(checkDir))
		} else {
			newdir := filepath.Dir(checkDir)
			//fmt.Println("Moving to:", newdir)
			checkDir = newdir
		}
	}
}

func runAt(dir string) int {
	cmd := exec.Command(PROG, os.Args[1:]...)
	cmd.Dir = dir
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		fmt.Printf("exit with errr %v\n", err)
		return 1
	} else {
		return 0
	}
}

func existsAtPath(dir string) bool {
	path := filepath.Join(dir, FILE)
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}
	//fmt.Println("found:", path)
	return true
}

package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
)

const FILE string = "Makefile"
const PROG string = "make"

/* TODO:
add stopping at homedir
configurable filename for aliases?
*/
func main() {
	checkDir, err := os.Getwd()
	if err != nil {
		fmt.Println("Error getting working directory:", err)
		os.Exit(1)
	}
	for {
		if existsAtPath(checkDir) {
			os.Exit(runAt(checkDir))
		} else if checkDir == "/" {
			fmt.Println("Unable to find", FILE)
			os.Exit(1)
		} else {
			newdir := filepath.Dir(checkDir)
			checkDir = newdir
		}
	}
}

func runAt(dir string) int {
	cmd := exec.Command(PROG, os.Args[1:]...)
	cmd.Dir = dir
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		fmt.Println(PROG, "exited with error", err)
		return 1
	} else {
		return 0
	}
}

func existsAtPath(dir string) bool {
	path := filepath.Join(dir, FILE)
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}
	return true
}

Fix infinite loop at root dir if nothing is found


package config

import (
	"log"
	"os"
	"path/filepath"

	"code.google.com/p/gcfg"
)

const Version = "0.1a"

const DEFAULT_NICKNAME = "perpetua"
const DEFAULT_USER = "perpetua"

var BASE_DIR = filepath.Join(os.ExpandEnv("$HOME"), ".perpetua")
var CONFIG_FILE = filepath.Join(BASE_DIR, "perpetua.gcfg")
var DATABASE_FILE = filepath.Join(BASE_DIR, "perpetua.sqlite3")

type Options struct {
	Server struct {
		Hostname           string
		Port               uint16
		UseTLS, SkipVerify bool
	}
	IRC struct {
		Nickname, User string
		Channel        []string
	}
}

func (o *Options) Read() {

	err := gcfg.ReadFileInto(o, CONFIG_FILE)

	if o.IRC.Nickname == "" {
		o.IRC.Nickname = DEFAULT_NICKNAME
	}
	if o.IRC.User == "" {
		o.IRC.User = DEFAULT_USER
	}

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

}

package config

import (
	"log"
	"os"
	"path/filepath"

	"code.google.com/p/gcfg"
)

const Version = "0.1a"

const DEFAULT_LANG = "en"

const DEFAULT_NICKNAME = "perpetua"
const DEFAULT_USER = "perpetua"

var BASE_DIR = filepath.Join(os.ExpandEnv("$HOME"), ".perpetua")
var CONFIG_FILE = filepath.Join(BASE_DIR, "perpetua.gcfg")
var DATABASE_FILE = filepath.Join(BASE_DIR, "perpetua.sqlite3")

// Options is used by Gcfg to store data read from CONFIG_FILE.
type Options struct {
	Server struct {
		Hostname           string
		Port               uint16
		UseTLS, SkipVerify bool
	}
	IRC struct {
		Nickname, User string
		Channel        []string
	}
	I18N struct {
		Lang string
	}
}

// Read configuration from default config file specified by
// CONFIG_FILE and set default values for not provided entries.
func (o *Options) Read() {

	err := gcfg.ReadFileInto(o, CONFIG_FILE)

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

	if o.IRC.Nickname == "" {
		o.IRC.Nickname = DEFAULT_NICKNAME
	}
	if o.IRC.User == "" {
		o.IRC.User = DEFAULT_USER
	}

	if o.I18N.Lang == "" {
		o.I18N.Lang = DEFAULT_LANG
	}

}

Add an option to handle language: default to en