package config

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

type Configuration struct {
	Username   string `json:"username"`
	Password   string
	RememberMe bool `json:"remember_me"`
}

func configWizard() *Configuration {
	configuration := new(Configuration)
	fmt.Println("Welcome to gotify !\nThis wizard will help you set up gotify, follow it carefully !")
	StartWizard(configuration)
	return configuration
}

func LoadConfig() *Configuration {
	if _, err := os.Stat("config.json"); os.IsNotExist(err) {
		configuration := configWizard()
		return configuration
	}
	file, err := ioutil.ReadFile("config.json")
	if err != nil {
		log.Fatal(err)
	}
	configuration := new(Configuration)
	err = json.Unmarshal(file, &configuration)
	if err != nil {
		log.Fatal(err)
	}
	return configuration
}

package config

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

type Configuration struct {
	Username   string `json:"username"`
	Password   string
	RememberMe bool `json:"remember_me"`
}

// Starts the wizard config
func configWizard() *Configuration {
	configuration := new(Configuration)
	fmt.Println("Welcome to gotify !\nThis wizard will help you set up gotify, follow it carefully !")
	StartWizard(configuration)
	err := saveConfig(configuration)
	if err != nil {
		log.Fatal(err)
	}
	return configuration
}

// Save the configuration in the config.json file
func saveConfig(configuration *Configuration) error {
	config, err := json.Marshal(configuration)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile("config.json", config, 0644)
	return err
}

// Load the configuration from config.json or launch the wizard if it does not exists
func LoadConfig() *Configuration {
	if _, err := os.Stat("config.json"); os.IsNotExist(err) {
		configuration := configWizard()
		return configuration
	}
	file, err := ioutil.ReadFile("config.json")
	if err != nil {
		log.Fatal(err)
	}
	configuration := new(Configuration)
	err = json.Unmarshal(file, &configuration)
	if err != nil {
		log.Fatal(err)
	}
	return configuration
}

Add some docstring and the saveConfiguration method


package main

import (
	"github.com/ligato/networkservicemesh/nsmdp"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	log.Println("Starting NSM")

	dp := nsmdp.NewNSMDevicePlugin()
	dp.Serve()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	select {
	case s := <-sigChan:
		log.Printf("Received signal \"%v\", shutting down.", s)
		dp.Stop()
	}

}

package main

import (
	"github.com/ligato/networkservicemesh/nsmdp"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	log.Println("Starting NSM")

	dp := nsmdp.NewNSMDevicePlugin()
	dp.Serve()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	go func() {
		s := <-sigChan
		log.Printf("Received signal \"%v\", shutting down.", s)
		dp.Stop()
	}()
}

Use a goroutine to block for the signal


package signature

import (
	"bytes"
	"encoding/base64"
	"testing"
)

const testTs = "1544544948"
const testQp = "abc=foo&def=bar"
const testBody = `{"a key":"some value"}`
const testSignature = "orb0adPhRCYND1WCAvPBr+qjm4STGtyvNDIDNBZ4Ir4="

func TestCalculateSignature(t *testing.T) {
	v := NewValidator("other-secret", 2, nil, nil)
	s, err := v.CalculateSignature(testTs, testQp, []byte(testBody))
	if err != nil {
		t.Errorf("Error calculating signature: %s, expected: orb0adPhRCYND1WCAvPBr+qjm4STGtyvNDIDNBZ4Ir4=", s)
	}
	drs, _ := base64.StdEncoding.DecodeString(testSignature)
	if bytes.Compare(s, drs) != 0 {
		t.Errorf("Unexpected signature: %s, expected: orb0adPhRCYND1WCAvPBr+qjm4STGtyvNDIDNBZ4Ir4=", s)
	}
}

Add basic test for calculating signature


package regexp_test

import (
	"github.com/Shopify/go-lua"
	"github.com/Shopify/goluago/regexp"
	"testing"
)

func TestLuaRegexp(t *testing.T) {
	l := lua.NewState()

	lua.OpenLibraries(l)
	regexp.Open(l)

	failHook := func(l *lua.State) int {
		str, ok := lua.ToString(l, -1)
		if !ok {
			t.Fatalf("need a string on the lua stack for calls to fail()")
		}
		lua.Pop(l, 1)
		t.Error(str)
		return 0
	}
	lua.Register(l, "fail", failHook)
	wantTop := lua.Top(l)

	if err := lua.LoadFile(l, "testdata/regexptest.lua", "t"); err != nil {
		t.Fatalf("loading lua test script in VM, %v", err)
	}

	if err := lua.ProtectedCall(l, 0, 0, 0); err != nil {
		t.Errorf("executing lua test script, %v", err)
	}
	gotTop := lua.Top(l)

	if wantTop != gotTop {
		t.Errorf("Unbalanced stack!, want %d, got %d", wantTop, gotTop)
	}
}

package regexp_test

import (
	"github.com/Shopify/go-lua"
	"github.com/Shopify/goluago/regexp"
	"testing"
)

func TestLuaRegexp(t *testing.T) {
	l := lua.NewState()

	lua.OpenLibraries(l)
	regexp.Open(l)

	failHook := func(l *lua.State) int {
		str := lua.CheckString(l, -1)
		lua.Pop(l, 1)
		t.Error(str)
		return 0
	}
	lua.Register(l, "fail", failHook)
	wantTop := lua.Top(l)

	if err := lua.LoadFile(l, "testdata/regexptest.lua", "t"); err != nil {
		t.Fatalf("loading lua test script in VM, %v", err)
	}

	if err := lua.ProtectedCall(l, 0, 0, 0); err != nil {
		t.Errorf("executing lua test script, %v", err)
	}
	gotTop := lua.Top(l)

	if wantTop != gotTop {
		t.Errorf("Unbalanced stack!, want %d, got %d", wantTop, gotTop)
	}
}

Use `CheckString` for test harness related func arguments.


package config

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

type Config struct {
	ConfigFile string
	Paths      map[string]string
}

func (c *Config) readConfig() error {
	c.Paths = make(map[string]string)

	file, err := os.Open(c.ConfigFile)
	defer file.Close()
	if err == nil {
		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			s := scanner.Text()
			ss := strings.Split(s, "|")
			c.Paths[strings.Trim(ss[0], " \t")] = strings.Trim(ss[1], " \t")
		}
		return scanner.Err()
	} else {
		return err
	}
}

func (c *Config) WriteConfig() error {
	file, err := os.Create(c.ConfigFile)
	defer file.Close()
	if err != nil {
		return err
	}
	for k, v := range c.Paths {
		if _, err := file.WriteString(fmt.Sprintf("%s| %s\n", k, v)); err != nil {
			return err
		}
	}
	return nil
}

func NewConfig(filename string) (*Config, error) {
	c := Config{ConfigFile: filename}
	if err := c.readConfig(); err == nil {
		return &c, nil
	} else {
		return nil, err
	}
}

package config

import (
	"io/ioutil"

	"gopkg.in/yaml.v2"
)

type Config struct {
	ConfigFile string
	Paths      map[string]string
}

func (c *Config) readConfig() error {
	c.Paths = make(map[string]string)

	content, err := ioutil.ReadFile(c.ConfigFile)
	if err != nil {
		return err
	}
	m := make(map[interface{}]interface{})
	err = yaml.Unmarshal(content, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		c.Paths[k.(string)] = v.(string)
	}
	return nil
}

func (c *Config) WriteConfig() error {
	content, err := yaml.Marshal(&(c.Paths))
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(c.ConfigFile, content, 0644)
	if err != nil {
		return err
	}
	return nil
}

func NewConfig(filename string) (*Config, error) {
	c := Config{ConfigFile: filename}
	if err := c.readConfig(); err == nil {
		return &c, nil
	} else {
		return nil, err
	}
}

Use yaml for file format...


package gohr

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/crypto/ssh/terminal"
)

// getWidth gets number of width of terminal from crypto subdirectory ssh/terminal
func getWidth() (int, error) {
	w, _, err := terminal.GetSize(int(os.Stdout.Fd()))
	if err != nil {
		return -1, err
	}
	return w, nil
}

// Draw fills a row with '#' by default (if no arguments are provided) or takes arguments and prints each pattern on a new line.
func Draw(args ...string) {
	w, err := getWidth()
	if err != nil {
		log.Fatalf("Error getting terminal width: %s\n", err)
	}

	if len(args) == 0 {
		for i := 0; i < w; i++ {
			fmt.Printf("#")
		}
		fmt.Printf("\n")
	} else {
		for _, arg := range args {
			l := len(arg)
			for i := 0; i < w/l; i++ {
				fmt.Printf(arg)
			}
			// Fills up the remaining columns in the row with part of the pattern
			fmt.Printf("%s\n", arg[:w%l])
		}
	}
}

package gohr

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/crypto/ssh/terminal"
)

// getWidth gets number of width of terminal from crypto subdirectory ssh/terminal
func getTerminalWidth() (int, error) {
	w, _, err := terminal.GetSize(int(os.Stdout.Fd()))
	if err != nil {
		return -1, err
	}
	return w, nil
}

// Draw fills a row with '#' by default (if no arguments are provided) or takes arguments and prints each pattern on a new line.
func Draw(patterns ...string) {
	w, err := getTerminalWidth()
	if err != nil {
		log.Fatalf("Error getting terminal width: %s\n", err)
	}

	if len(patterns) == 0 {
		for i := 0; i < w; i++ {
			fmt.Printf("#")
		}
		fmt.Printf("\n")
	} else {
		for _, pattern := range patterns {
			l := len(pattern)
			for i := 0; i < w/l; i++ {
				fmt.Printf(pattern)
			}
			// Fills up the remaining columns in the row with part of the pattern
			fmt.Printf("%s\n", pattern[:w%l])
		}
	}
}

Update function and variable names to be more descriptive


package tricks_test

import (
	"fmt"
	"strings"

	"github.com/aviddiviner/tricks"
)

var animals = []string{"dog", "cat", "bear", "cow", "bull", "pig", "iguana"}

func ExampleSlice() {
	bearCow := tricks.Slice(animals).
		Map(strings.ToUpper).
		Last(5).
		First(2).
		Value().([]string)

	fmt.Println(bearCow)

	// Output: [BEAR COW]
}

func ExampleSlice_groupBy() {
	byLength := tricks.Slice(animals).
		Copy().Sort().
		GroupBy(func(s string) int { return len(s) }).
		Value().(map[int][]string)

	fmt.Println(byLength[3])

	// Output: [cat cow dog pig]
}

func ExampleSlice_strings() {
	password := tricks.Slice([]rune("abracadabra")).Reverse().Value().([]rune)
	fmt.Println(string(password))

	// Output: arbadacarba
}

// TODO: Add variadic example.

package tricks_test

import (
	"fmt"
	"strings"

	"github.com/aviddiviner/tricks"
)

func ExampleSlice() {
	animals := []string{"dog", "cat", "bear", "cow", "bull", "pig", "iguana"}

	bearCow := tricks.Slice(animals).
		Map(strings.ToUpper).
		Last(5).
		First(2).
		Value().([]string)

	fmt.Println(bearCow)
	// Output: [BEAR COW]
}

func ExampleSlice_strings() {
	password := tricks.Slice([]rune("abracadabra")).Reverse().Value().([]rune)
	fmt.Println(string(password))
	// Output: arbadacarba
}

// TODO: Add variadic example.

func ExampleTrickSlice_GroupBy() {
	animals := []string{"dog", "cat", "bear", "cow", "bull", "pig", "iguana"}

	byLength := tricks.Slice(animals).
		Copy().
		Sort().
		Reverse().
		GroupBy(func(s string) int { return len(s) }).
		Value().(map[int][]string)

	fmt.Println(byLength[3])
	// Output: [pig dog cow cat]
}

Tweak examples to look better


package parser

func ParseInstruction(instruction string) ([]Instruction, error) {

	l := lexer{}
	tokens, err := l.lex([]byte(instruction))
	if err != nil {
		return nil, err
	}

	p := parser{}
	instructions, err := p.parse(tokens)
	if err != nil {
		return nil, err
	}

	return instructions, nil
}

package parser

import (
	"errors"
)

func ParseInstruction(instruction string) ([]Instruction, error) {

	l := lexer{}
	tokens, err := l.lex([]byte(instruction))
	if err != nil {
		return nil, err
	}

	p := parser{}
	instructions, err := p.parse(tokens)
	if err != nil {
		return nil, err
	}

	if len(instructions) == 0 {
		return nil, errors.New("Error in syntax near " + instruction)
	}

	return instructions, nil
}

Fix deadlock when no instructions are parsed


/*Package consts implements constants for the entire project
 */
package consts

// ConfigurationFileName is the configuration file name of Goyave
const ConfigurationFileName = ".goyave"

// GitFileName is the name of the git directory, in a git repository
const GitFileName = ".git"

////////////////
//// ERRORS ////
////////////////

// RepositoryAlreadyExists is an error that append an existing path repository in a list
const RepositoryAlreadyExists = "REPOSITORY_ALREADY_EXISTS"

/*Package consts implements constants for the entire project
 */
package consts

// VisibleFlag is the constant given for a visible repository
const VisibleFlag = "VISIBLE"

// HiddenFlag is the constant given for an hidden repository
const HiddenFlag = "HIDDEN"

// ConfigurationFileName is the configuration file name of Goyave
const ConfigurationFileName = ".goyave"

// GitFileName is the name of the git directory, in a git repository
const GitFileName = ".git"

////////////////
//// ERRORS ////
////////////////

// RepositoryAlreadyExists is an error that append an existing path repository in a list
const RepositoryAlreadyExists = "REPOSITORY_ALREADY_EXISTS"

Add two new constants to get the visibility of a given repository


package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"os/signal"

	"github.com/localhots/satan"
	"github.com/localhots/satan/example/daemons"
)

func main() {
	var debug bool
	flag.BoolVar(&debug, "v", false, "Verbose mode")
	flag.Parse()
	if !debug {
		log.SetOutput(ioutil.Discard)
	}

	s := satan.Summon()
	s.AddDaemon(&daemons.NumberPrinter{})
	s.StartDaemons()
	defer s.StopDaemons()

	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)

	for s := range sig {
		if s == os.Interrupt {
			return
		}
	}
}

package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"os/signal"

	"github.com/localhots/satan"
	"github.com/localhots/satan/example/daemons"
)

func main() {
	var debug bool
	flag.BoolVar(&debug, "v", false, "Verbose mode")
	flag.Parse()
	if !debug {
		log.SetOutput(ioutil.Discard)
	}

	s := satan.Summon()
	s.AddDaemon(&daemons.NumberPrinter{})
	s.StartDaemons()
	defer s.StopDaemons()

	sig := make(chan os.Signal)
	signal.Notify(sig, os.Interrupt)
	<-sig
}

Use less code to catch the interrupt signal


package core

import (
	"github.com/akutz/gofig"
)

func init() {
	initDrivers()
	gofig.Register(globalRegistration())
	gofig.Register(driverRegistration())
}

func globalRegistration() *gofig.Registration {
	r := gofig.NewRegistration("Global")
	r.Yaml(`
rexray:
    host: tcp://:7979
    logLevel: warn
`)
	r.Key(gofig.String, "h", "tcp://:7979",
		"The REX-Ray host", "rexray.host")
	r.Key(gofig.String, "l", "warn",
		"The log level (error, warn, info, debug)", "rexray.logLevel")
	return r
}

func driverRegistration() *gofig.Registration {
	r := gofig.NewRegistration("Driver")
	r.Yaml(`
rexray:
    osDrivers:
    - linux
    storageDrivers:
    - libstorage
    volumeDrivers:
    - docker
`)
	r.Key(gofig.String, "", "linux",
		"The OS drivers to consider", "rexray.osDrivers")
	r.Key(gofig.String, "", "",
		"The storage drivers to consider", "rexray.storageDrivers")
	r.Key(gofig.String, "", "docker",
		"The volume drivers to consider", "rexray.volumeDrivers")
	return r
}

package core

import (
	"fmt"

	"github.com/akutz/gofig"
	"github.com/akutz/gotil"

	"github.com/emccode/rexray/util"
)

func init() {
	initDrivers()
	gofig.SetGlobalConfigPath(util.EtcDirPath())
	gofig.SetUserConfigPath(fmt.Sprintf("%s/.rexray", gotil.HomeDir()))
	gofig.Register(globalRegistration())
	gofig.Register(driverRegistration())
}

func globalRegistration() *gofig.Registration {
	r := gofig.NewRegistration("Global")
	r.Yaml(`
rexray:
    host: tcp://:7979
    logLevel: warn
`)
	r.Key(gofig.String, "h", "tcp://:7979",
		"The REX-Ray host", "rexray.host")
	r.Key(gofig.String, "l", "warn",
		"The log level (error, warn, info, debug)", "rexray.logLevel")
	return r
}

func driverRegistration() *gofig.Registration {
	r := gofig.NewRegistration("Driver")
	r.Yaml(`
rexray:
    osDrivers:
    - linux
    storageDrivers:
    - libstorage
    volumeDrivers:
    - docker
`)
	r.Key(gofig.String, "", "linux",
		"The OS drivers to consider", "rexray.osDrivers")
	r.Key(gofig.String, "", "",
		"The storage drivers to consider", "rexray.storageDrivers")
	r.Key(gofig.String, "", "docker",
		"The volume drivers to consider", "rexray.volumeDrivers")
	return r
}

Fix for not setting Gofig config dirs (Rebased)


package meta

// CueSheet contains the track information of a cue sheet.
//
// https://www.xiph.org/flac/format.html#metadata_block_cuesheet
type CueSheet struct{}

package meta

// A CueSheet describes how tracks are layed out within a FLAC stream.
//
// ref: https://www.xiph.org/flac/format.html#metadata_block_cuesheet
type CueSheet struct {
	// Media catalog number.
	MCN string
	// Number of lead-in samples. This field only has meaning for CD-DA cue
	// sheets; for other uses it should be 0. Refer to the spec for additional
	// information.
	NLeadInSamples uint64
	// Specifies if the cue sheet corresponds to a Compact Disc.
	IsCompactDisc bool
	// One or more tracks. The last track of a cue sheet is always the lead-out
	// track.
	Tracks []CueSheetTrack
}

// CueSheetTrack contains the start offset of a track and other track specific
// metadata.
type CueSheetTrack struct {
	// Track offset in samples, relative to the beginning of the FLAC audio
	// stream.
	Offset uint64
	// Track number; never 0, always unique.
	Num uint8
	// International Standard Recording Code; empty string if not present.
	//
	// ref: http://isrc.ifpi.org/
	ISRC string
	// Specifies if the track contains audio or data.
	IsAudio bool
	// Specifies if the track has been recorded with pre-emphasis
	HasPreEmphasis bool
	// Every track has one or more track index points, except for the lead-out
	// track which has zero. Each index point specifies a position within the
	// track.
	Indicies []CueSheetTrackIndex
}

// A CueSheetTrackIndex specifies a position within a track.
type CueSheetTrackIndex struct {
	// Index point offset in samples, relative to the track offset.
	Offset uint64
	// Index point number; subsequently incrementing by 1 and always unique
	// within a track.
	Num uint8
}

Add CueSheet, CueSheetTrack and CueSheetTrackIndex definitions.


// Copyright 2013 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

package main

import (
	"fmt"

	"code.google.com/p/gettext-go/gettext"
)

func main() {
	gettext.SetLocale("zh_CN")
	gettext.BindTextdomain("hello", "../examples/local", nil)
	gettext.Textdomain("hello")

	fmt.Println(gettext.Gettext("Hello, world!"))
	// Output: 你好, 世界!
}

// Copyright 2013 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

package main

import (
	"fmt"

	"github.com/chai2010/gettext-go"
)

func main() {
	gettext.SetLocale("zh_CN")
	gettext.BindTextdomain("hello", "../examples/local", nil)
	gettext.Textdomain("hello")

	fmt.Println(gettext.Gettext("Hello, world!"))
	// Output: 你好, 世界!
}

Fix example import path for gvt-fetch support


package device

import (
	"sync"

	"github.com/tarm/serial"
)

type Manager struct {
	devices map[string]serial.Config
	mu      sync.RWMutex
}

func (m *Manager) AddDevice(name string) error {
	cfg := serial.Config{Name: name}
	m.mu.Lock()
	m.devices[name] = cfg
	m.mu.Unlock()
	return nil
}

func (m *Manager) RemoveDevice(name string) error {
	m.mu.RLock()
	delete(m.devices, name)
	m.mu.RUnlock()
	return nil
}

type Conn struct {
	device serial.Config
	port   *serial.Port
	isOpen bool
}

func (c *Conn) Open() error {
	p, err := serial.OpenPort(&c.device)
	if err != nil {
		return nil
	}
	c.port = p
	c.isOpen = true
	return nil
}

// Close closes the port helt by *Conn.
func (c *Conn) Close() error {
	if c.isOpen {
		return c.port.Close()
	}
	return nil
}

package device

import (
	"sync"

	"github.com/tarm/serial"
)

type Manager struct {
	devices map[string]serial.Config
	conn    []*Conn
	mu      sync.RWMutex
}

func (m *Manager) AddDevice(name string) error {
	cfg := serial.Config{Name: name}
	m.mu.Lock()
	m.devices[name] = cfg
	m.mu.Unlock()
	return nil
}

func (m *Manager) RemoveDevice(name string) error {
	m.mu.RLock()
	delete(m.devices, name)
	m.mu.RUnlock()
	return nil
}

type Conn struct {
	device serial.Config
	port   *serial.Port
	isOpen bool
}

func (c *Conn) Open() error {
	p, err := serial.OpenPort(&c.device)
	if err != nil {
		return nil
	}
	c.port = p
	c.isOpen = true
	return nil
}

// Close closes the port helt by *Conn.
func (c *Conn) Close() error {
	if c.isOpen {
		return c.port.Close()
	}
	return nil
}

Use slice of *Conn instead of a map


package uploader

import (
	"github.com/matthew-andrews/s3up/objects"
	"testing"
	"time"
)

type stubS3Client struct{}

func (stub stubS3Client) UploadFile(string, objects.File) error {
	time.Sleep(50 * time.Millisecond)
	return nil
}

func uploadThreeFilesWithConcurrency(concurrency int) int64 {
	startTime := time.Now()
	Upload(stubS3Client{}, "", make([]objects.File, 3), concurrency)
	duration := time.Since(startTime).Nanoseconds()
	return int64(duration / int64(time.Millisecond))
}

func TestOneAtATime(t *testing.T) {
	duration := uploadThreeFilesWithConcurrency(1)
	if duration < 100 {
		t.Fatalf("uploader was too quick.  3 times 50ms one at a time can't be less than 100ms.  but it was %v", duration)
	}
}

func TestThreeAtATime(t *testing.T) {
	duration := uploadThreeFilesWithConcurrency(3)
	if duration > 100 {
		t.Fatalf("uploader was too slow.  3 times 50ms three at a time can't be more than 100ms.  but it was %v", duration)
	}
}

package uploader

import (
	"github.com/matthew-andrews/s3up/objects"
	"strings"
	"testing"
	"time"
)

type stubS3Client struct{}

func (stub stubS3Client) UploadFile(string, objects.File) error {
	time.Sleep(50 * time.Millisecond)
	return nil
}

func uploadThreeFilesWithConcurrency(concurrency int) int64 {
	startTime := time.Now()
	Upload(stubS3Client{}, "", make([]objects.File, 3), concurrency)
	duration := time.Since(startTime).Nanoseconds()
	return int64(duration / int64(time.Millisecond))
}

func TestOneAtATime(t *testing.T) {
	duration := uploadThreeFilesWithConcurrency(1)
	if duration < 100 {
		t.Fatalf("uploader was too quick.  3 times 50ms one at a time can't be less than 100ms.  but it was %v", duration)
	}
}

func TestThreeAtATime(t *testing.T) {
	duration := uploadThreeFilesWithConcurrency(3)
	if duration > 100 {
		t.Fatalf("uploader was too slow.  3 times 50ms three at a time can't be more than 100ms.  but it was %v", duration)
	}
}

func TestNoFiles(t *testing.T) {
	err := Upload(stubS3Client{}, "", make([]objects.File, 0), 1)
	if strings.Contains(err.Error(), "No files found") == false {
		t.Fatal("The error that was expected was not thrown")
	}
}

Add a test for no files


package io

type Reader interface {
	Read([]byte) (int, error)
}

type Writer interface {
	Write([]byte) (int, error)
}

type ReadWriter interface {
	Reader
	Writer
}

type Closer interface {
	Close() error
}

type ReadCloser interface {
	Reader
	Closer
}

type WriteCloser interface {
	Writer
	Closer
}

type ReadWriteCloser interface {
	Reader
	Writer
	Closer
}

Add Closer, ReadCloser, WriteCloser, ReadWriteCloser.


package cli_test

import (
	"bytes"
	"testing"

	"github.com/codegangsta/cli"
)

func TestShowAppHelp(t *testing.T) {
	output := new(bytes.Buffer)
	app := cli.NewApp()
	app.Writer = output

	c := cli.NewContext(app, nil, nil)

	cli.ShowAppHelp(c)

	if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
		t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
	}
}

package cli_test

import (
	"bytes"
	"testing"

	"github.com/codegangsta/cli"
)

func Test_ShowAppHelp_NoAuthor(t *testing.T) {
	output := new(bytes.Buffer)
	app := cli.NewApp()
	app.Writer = output

	c := cli.NewContext(app, nil, nil)

	cli.ShowAppHelp(c)

	if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
		t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
	}
}

Rename TestShowAppHelp to be more verbose


package logger

import (
	"encoding/json"
	"log"

	"github.com/bsphere/le_go"
	"github.com/emreler/finch/config"
)

// Logger .
type Logger struct {
	conn *le_go.Logger
}

// NewLogger .
func NewLogger(token config.LogentriesConfig) *Logger {
	le, err := le_go.Connect(string(token))

	if err != nil {
		panic(err)
	}

	log.Println("Connected to Logentries")

	return &Logger{le}
}

// Info .
func (l *Logger) Info(data interface{}) {
	if str, ok := data.(string); ok {
		l.conn.Println(str)
	} else {
		jstring, _ := json.Marshal(data)
		l.conn.Println(string(jstring))
	}
}

func (l *Logger) Error(err error) {
	l.conn.Println(err.Error())
}

package logger

import (
	"encoding/json"
	"log"

	"github.com/bsphere/le_go"
	"github.com/emreler/finch/config"
)

const (
	levelInfo  = "INFO"
	levelError = "ERROR"
)

// Logger .
type Logger struct {
	conn *le_go.Logger
}

// LogMessage .
type LogMessage struct {
	Level   string `json:"level"`
	Message string `json:"message"`
}

// NewLogger .
func NewLogger(token config.LogentriesConfig) *Logger {
	le, err := le_go.Connect(string(token))

	if err != nil {
		panic(err)
	}

	log.Println("Connected to Logentries")

	return &Logger{le}
}

// Info .
func (l *Logger) Info(data interface{}) {
	var j []byte
	if str, ok := data.(string); ok {
		logMsg := &LogMessage{
			Level:   levelInfo,
			Message: str,
		}

		j, _ = json.Marshal(logMsg)

		l.conn.Println(j)
	} else {
		jstring, _ := json.Marshal(data)

		logMsg := &LogMessage{
			Level:   levelInfo,
			Message: string(jstring),
		}

		j, _ = json.Marshal(logMsg)

		l.conn.Println(string(j))
	}
}

func (l *Logger) Error(err error) {
	logMsg := &LogMessage{
		Level:   levelError,
		Message: err.Error(),
	}

	j, _ := json.Marshal(logMsg)

	l.conn.Println(string(j))
}

Add log levels to messages


// Copyright 2015 Eleme Inc. All rights reserved.

package metric

// Metric with name and value
type Metric struct {
	Name   string  // metric name
	Stamp  uint32  // metric timestamp (able to use for 90 years from now)
	Value  float64 // metric value
	Score  float64 // metric anomaly score
	AvgOld float64 // previous average value
	AvgNew float64 // current average value
}

// New creates a Metric.
func New() *Metric {
	m := new(Metric)
	m.Stamp = 0
	m.Score = 0
	return m
}

// Copyright 2015 Eleme Inc. All rights reserved.

package metric

// Metric with name and value
type Metric struct {
	// Name
	Name string
	// Timestamp in seconds, able to use for 90 years from now.
	Stamp uint32
	// Current value
	Value float64 // metric value
	// Current anomaly score
	Score float64
	// Current standard deviation
	Std float64
	// Current average
	Avg float64
	// Previous average
	AvgOld float64
	// Current datapoints count
	Count uint32
}

// New creates a Metric.
func New() *Metric {
	m := new(Metric)
	m.Stamp = 0
	m.Score = 0
	return m
}

Add `Std` field to Metric


// +build !linux,!darwin

package loadavg

import (
	"fmt"
	"runtime"
)

func LoadAvg() ([3]float64, error) {
	return [...]float64{-1, -1, -1}, fmt.Errorf("loadavg: unsupported platform %q", runtime.GOOS)
}

// +build !linux,!darwin

package loadavg

import (
	"fmt"
	"runtime"
)

func loadAvg() ([3]float64, error) {
	return [...]float64{-1, -1, -1}, fmt.Errorf("loadavg: unsupported platform %q", runtime.GOOS)
}

Fix bug with stub loadAvg function.


package main

import (
	"testing"
)

var sourceURITests = []struct {
	src string
	dst string
}{
	{
		"https://github.com/sunaku/vim-unbundle",
		"https://github.com/sunaku/vim-unbundle",
	},
}

func TestSourceURI(t *testing.T) {
	for _, test := range sourceURITests {
		expect := test.dst
		actual, err := ToSourceURI(test.src)
		if err != nil {
			t.Errorf("ToSourceURI(%q) returns %q, want nil", err)
		}
		if actual != expect {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}

package main

import (
	"testing"
)

var sourceURITests = []struct {
	src string
	dst string
}{
	{
		"https://github.com/sunaku/vim-unbundle",
		"https://github.com/sunaku/vim-unbundle",
	},

	{
		"Shougo/neobundle.vim",
		"https://github.com/Shougo/neobundle.vim",
	},
	{
		"thinca/vim-quickrun",
		"https://github.com/thinca/vim-quickrun",
	},
}

func TestSourceURI(t *testing.T) {
	for _, test := range sourceURITests {
		expect := test.dst
		actual, err := ToSourceURI(test.src)
		if err != nil {
			t.Errorf("ToSourceURI(%q) returns %q, want nil", err)
		}
		if actual != expect {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}

Add case of short GitHub URI for ToSourceURI


package main

import (
	"net"
	"os"
)

func handleConnection(conn net.Conn) {
	connection := NewConnection(conn)
	defer connection.Close()
	connection.Handle()
}

func acceptedConnsChannel(listener net.Listener) chan net.Conn {
	channel := make(chan net.Conn)
	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				logger.Info.Println("Could not accept socket:", err)
				continue
			}

			channel <- conn
		}
	}()
	return channel
}

func main() {
	InitLogger()

	logger.Info.Println("Prepare for takeoff...")
	server, err := net.Listen("tcp", ":25000")
	if err != nil {
		logger.Fatal.Println("Could not start server:", err)
		os.Exit(1)
	}

	logger.Info.Println("Server started on :25000")

	acceptedConnsChannel := acceptedConnsChannel(server)
	for {
		go handleConnection(<-acceptedConnsChannel)
	}
}

package main

import (
	"net"
	"os"
	"flag"
	"strconv"
)

func handleConnection(conn net.Conn) {
	connection := NewConnection(conn)
	defer connection.Close()
	connection.Handle()
}

func acceptedConnsChannel(listener net.Listener) chan net.Conn {
	channel := make(chan net.Conn)
	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				logger.Info.Println("Could not accept socket:", err)
				continue
			}

			channel <- conn
		}
	}()
	return channel
}

func main() {
	InitLogger()

	portPtr := flag.Int("port", 25000, "listen port")
	flag.Parse()

	logger.Info.Println("Prepare for takeoff...")

	listenOn := ":" + strconv.Itoa(*portPtr)
	server, err := net.Listen("tcp", listenOn)
	if err != nil {
		logger.Fatal.Println("Could not start server:", err)
		os.Exit(1)
	}

	logger.Info.Println("Server started on", listenOn)

	acceptedConnsChannel := acceptedConnsChannel(server)
	for {
		go handleConnection(<-acceptedConnsChannel)
	}
}

Make the proxy server listen port configurable


package main

import (
	"code.google.com/p/gcfg" //Ref: http://code.google.com/p/gcfg/
	"fmt"
	"os"
	"os/user"
)

type Config struct {
	Auth struct {
		AccessKey string
		SecretKey string
	}
}

//Get the configurations from ~/.s3upload.conf
func getConfigs() Config {
	usr, err := user.Current()
	if err != nil {
		fmt.Println(err)
		os.Exit(10)
	}

	var cfg Config
	cfg_err := gcfg.ReadFileInto(&cfg,
		usr.HomeDir+string(os.PathSeparator)+".s3upload.conf")
	if cfg_err != nil {
		fmt.Println(cfg_err)
		os.Exit(11)
	}
	return cfg
}

package main

import (
	"code.google.com/p/gcfg" //Ref: http://code.google.com/p/gcfg/
	"fmt"
	"os"
	"os/user"
)

type Config struct {
	Auth struct {
		AccessKey string
		SecretKey string
	}

	Locations struct {
		Source      []string
		Destination []string
	}
}

//Get the configurations from ~/.s3upload.conf
func getConfigs() Config {
	usr, err := user.Current()
	if err != nil {
		fmt.Println(err)
		os.Exit(10)
	}

	var cfg Config
	cfg_err := gcfg.ReadFileInto(&cfg,
		usr.HomeDir+string(os.PathSeparator)+".s3upload.conf")
	if cfg_err != nil {
		fmt.Println(cfg_err)
		os.Exit(11)
	}
	return cfg
}

Allow multiple sources and destination in config.


package scipipe

import (
	// "github.com/go-errors/errors"
	//"os"
	"os"
	"os/exec"
	re "regexp"
)

func ExecCmd(cmd string) string {
	Info.Println("Executing command: ", cmd)
	combOutput, err := exec.Command("bash", "-lc", cmd).CombinedOutput()
	if err != nil {
		Error.Println("Could not execute command `" + cmd + "`: " + string(combOutput))
		os.Exit(1)
	}
	return string(combOutput)
}

func Check(err error, errMsg string) {
	if err != nil {
		Error.Println(errMsg)
		panic(err)
	}
}

// Return the regular expression used to parse the place-holder syntax for in-, out- and
// parameter ports, that can be used to instantiate a SciProcess.
func getShellCommandPlaceHolderRegex() *re.Regexp {
	regex := "{(o|os|i|is|p):([^{}:]+)}"
	r, err := re.Compile(regex)
	Check(err, "Could not compile regex: "+regex)
	return r
}

package scipipe

import (
	// "github.com/go-errors/errors"
	//"os"
	"os"
	"os/exec"
	re "regexp"
)

func ExecCmd(cmd string) string {
	Info.Println("Executing command: ", cmd)
	combOutput, err := exec.Command("bash", "-lc", cmd).CombinedOutput()
	if err != nil {
		Error.Println("Could not execute command `" + cmd + "`: " + string(combOutput))
		os.Exit(1)
	}
	return string(combOutput)
}

func Check(err error, errMsg string) {
	if err != nil {
		Error.Println("Custom Error Message: " + errMsg)
		Error.Println("Original Error Message: " + err.Error())
		panic(err)
	}
}

// Return the regular expression used to parse the place-holder syntax for in-, out- and
// parameter ports, that can be used to instantiate a SciProcess.
func getShellCommandPlaceHolderRegex() *re.Regexp {
	regex := "{(o|os|i|is|p):([^{}:]+)}"
	r, err := re.Compile(regex)
	Check(err, "Could not compile regex: "+regex)
	return r
}

Print both custom and original error messages


package main

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

func runner(what string) {
	f, err := os.OpenFile("testlogfile", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		panic("NOOOOO")
	}
	defer f.Close()

	log.SetOutput(f)
	log.Println("### Starting:")
	cmd := exec.Command(what)
	cmd.Stdout = io.MultiWriter(f, os.Stdout)
	cmd.Stderr = os.Stderr
	cmd.Run()
	log.Println("### Done:")

}

func main() {
	runner("speedtest-cli")

	period := 10 * time.Minute
	for _ = range time.Tick(period) {
		runner("speedtest-cli")
	}

}

package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"time"
)

func runner(what string) {
	f, err := os.OpenFile("testlogfile", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		panic("NOOOOO")
	}
	defer f.Close()

	log.SetOutput(f)
	log.Println("### Starting:")
	defer log.Println("### Done:")

	cmd := exec.Command(what)

	output := io.MultiWriter(f, os.Stdout)
	cmd.Stdout = output
	cmd.Stderr = output

	err = cmd.Run()
	if err != nil {
		fmt.Fprintln(output, "Error running: ", what)
		fmt.Fprintln(output, err)
	}

}

func main() {
	runner("speedtest-cli")

	period := 10 * time.Minute
	for _ = range time.Tick(period) {
		runner("speedtest-cli")
	}

}

Fix issues with capturing stdout and error messages for the runner.


package main

import (
	"flag"
	"fmt"
	"github.com/nsf/termbox-go"
)

func MaybePanic(err error) {
	if err != nil {
		panic(err)
	}
}

var (
	Quit   chan struct{}
	Redraw chan struct{}
)

func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		fmt.Println("sux: no commands given")
		fmt.Println("Usage sux [command ...]")
		return
	}

	DefaultMode = InputMode
	CurrentMode = DefaultMode

	Quit = make(chan struct{})
	Redraw = make(chan struct{})

	MaybePanic(termbox.Init())

	termbox.SetInputMode(termbox.InputEsc)

	defer termbox.Close()
	defer EndPanes()

	go InputLoop()
	go OutputLoop()

	MaybePanic(RunPanes())

	<-Quit
}

package main

import (
	"flag"
	"fmt"
	"github.com/nsf/termbox-go"
)

func MaybePanic(err error) {
	if err != nil {
		panic(err)
	}
}

var (
	Quit   chan struct{}
	Redraw chan struct{}
)

func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		fmt.Println("sux: no commands given")
		fmt.Println("Usage sux [command ...]")
		return
	}

	DefaultMode = InputMode
	CurrentMode = DefaultMode

	Quit = make(chan struct{})
	Redraw = make(chan struct{})

	MaybePanic(termbox.Init())

	termbox.SetInputMode(termbox.InputEsc)
	termbox.SetOutputMode(termbox.Output256)

	defer termbox.Close()
	defer EndPanes()

	go InputLoop()
	go OutputLoop()

	MaybePanic(RunPanes())

	<-Quit
}

Set output mode to 256 by default


package api

import (
  "net/http"
  "fmt"
)

var AboutPath = "/about/"

func AboutHandler(w http.ResponseWriter, r *http.Request)  {
  fmt.Fprintf(w, "About, %s!", r.URL.Path[1:])
}

package api

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

type Message struct{
  Text string
}

var AboutPath = "/about/"

func AboutHandler(w http.ResponseWriter, r *http.Request)  {
  msg := Message{"goapi API v0a (alpha)"}
  jsonMsg, err := json.Marshal(msg)

  if err != nil {
    panic(err)
  }

  w.Write(jsonMsg)
}

Add send json in api response for AboutHandler


package venom

import (
	"testing"

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

func TestParseEmpty(t *testing.T) {
	m, err := parseMapStringString("", ",", "=")
	assert.Nil(t, err)
	assert.Equal(t, m, map[string]string{})
}

func TestParseSingle(t *testing.T) {
	m, err := parseMapStringString("foo=bar", ",", "=")
	assert.Nil(t, err)
	assert.Equal(t, m, map[string]string{
		"foo": "bar",
	})
}

func TestParseMultiple(t *testing.T) {
	m, err := parseMapStringString("foo=bar,moo=goo", ",", "=")
	assert.Nil(t, err)
	assert.Equal(t, m, map[string]string{
		"foo": "bar",
		"moo": "goo",
	})
}

func TestFailNoSep(t *testing.T) {
	m, err := parseMapStringString("foo", ",", "=")
	assert.NotNil(t, err)
	assert.Nil(t, m)
}

package venom

import (
	"testing"

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

type setup struct {
	s string
	m map[string]string
}

var (
	table = map[string]setup{
		"empty": {
			s: "",
			m: map[string]string{},
		},
		"single": {
			s: "foo=bar",
			m: map[string]string{
				"foo": "bar",
			},
		},
		"multiple": {
			s: "foo=bar,goo=moo",
			m: map[string]string{
				"foo": "bar",
				"goo": "moo",
			},
		},
	}
)

func TestParse(t *testing.T) {
	for name, x := range table {
		t.Run(name, func(t *testing.T) {
			m, err := parseMapStringString(x.s, ",", "=")
			assert.Nil(t, err)
			assert.Equal(t, m, x.m)
		})
	}
}

func TestSerialize(t *testing.T) {
	for name, x := range table {
		t.Run(name, func(t *testing.T) {
			s, err := serializeMapStringString(x.m, ",", "=")
			assert.Nil(t, err)
			assert.Equal(t, s, x.s)
		})
	}
}

func TestFailNoSep(t *testing.T) {
	m, err := parseMapStringString("foo", ",", "=")
	assert.NotNil(t, err)
	assert.Nil(t, m)
}

Add tests for parse & serialize


package tumblr

import (
	"encoding/json"
)

// Blog Info
func (blog Blog) Info() (*BlogInfo, error) {
	url, err := blog.blogEntityURL("info")
	if err != nil {
		return nil, err
	}
	data, err := callAPI(url)
	var v BlogInfo
	json.Unmarshal(data, &v)

	return nil, nil
}

// Type returned by blog.Info()
type BlogInfo struct {
	Title       string
	Posts       int64
	Name        string
	Updated     int64
	Description string
	Ask         bool
	AskAnon     bool
	Likes       int64
}

package tumblr

import (

)

// Blog Info
func (blog Blog) Info() (*BlogInfo, error) {
	// url, err := blog.blogEntityURL("info")
	// if err != nil {
	// 	return nil, err
	// }

	//res, err := callAPI(url)

	return nil, nil
}

// Type returned by blog.Info()
type BlogInfo struct {
	Title       string
	Posts       int64
	Name        string
	Updated     int64
	Description string
	Ask         bool
	AskAnon     bool
	Likes       int64
}

Comment this out so it compiles for now


package vaultutil

import (
	vaultapi "github.com/hashicorp/vault/api"
)

func GetGroups(c *vaultapi.Client) (*vaultapi.Secret, error) {
	resp, err := c.Logical().List("auth/ldap/groups")
	if err != nil {
		return resp, err
	}
	return resp, err
}

func DeleteGroups(c *vaultapi.Client, groupname string) (*vaultapi.Secret, error) {
	resp, err := c.Logical().Delete("auth/ldap/groups" + groupname)
	if err != nil {
		return resp, err
	}
	return resp, err
}

func GetGroupPolicy(c *vaultapi.Client, group_name string) (*vaultapi.Secret, error) {
	resp, err := c.Logical().Read("auth/ldap/groups/" + group_name)
	if err != nil {
		return resp, err
	}
	return resp, err
}

package vaultutil

import (
	vaultapi "github.com/hashicorp/vault/api"
)

func GetGroups(c *vaultapi.Client) (*vaultapi.Secret, error) {
	resp, err := c.Logical().List("auth/ldap/groups")
	if err != nil {
		return resp, err
	}
	return resp, err
}

func DeleteGroup(c *vaultapi.Client, groupname string) (*vaultapi.Secret, error) {
	resp, err := c.Logical().Delete("auth/ldap/groups/" + groupname)
	if err != nil {
		return resp, err
	}
	return resp, err
}

func GetGroupPolicy(c *vaultapi.Client, group_name string) (*vaultapi.Secret, error) {
	resp, err := c.Logical().Read("auth/ldap/groups/" + group_name)
	if err != nil {
		return resp, err
	}
	return resp, err
}

Fix logical path for DeleteGroup call


package main

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

func hello(resp http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(resp, "<title>How about them apples?!</title>
")
	fmt.Fprintln(resp, "Hello world!")
	fmt.Fprintln(resp, "
")
}

func main() {
	http.HandleFunc("/", hello)
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

package main

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

func hello(resp http.ResponseWriter, req *http.Request) {
	content, err := template.New("").Parse("<title>{{.title}}</title>
{{range .envs}}
{{.}}
{{end}}
")
	if err != nil {
		panic(err)
	}

	ctx := map[string]interface{} {
		"title": "How about them apples?!",
		"envs": os.Environ(),
	}

	content.Execute(resp, ctx)
}

func main() {
	http.HandleFunc("/", hello)
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

Use templates to print env.


package main

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

	rat "github.com/ericfreese/rat/lib"
	flag "github.com/spf13/pflag"
)

var (
	RatVersion = "0.0.2"
)

var flags struct {
	cmd     string
	mode    string
	version bool
}

func init() {
	flag.StringVarP(&flags.cmd, "cmd", "c", "cat ~/.config/rat/ratrc", "command to run")
	flag.StringVarP(&flags.mode, "mode", "m", "default", "name of mode")
	flag.BoolVarP(&flags.version, "version", "v", false, "display version and exit")

	flag.Parse()
}

func main() {
	var err error

	if flags.version {
		fmt.Println(RatVersion)
		return
	}

	if err = rat.Init(); err != nil {
		panic(err)
	}

	defer rat.Close()

	if config, err := os.Open(filepath.Join(rat.ConfigDir, "ratrc")); err == nil {
		rat.LoadConfig(config)
		config.Close()
	}

	rat.PushPager(rat.NewCmdPager(flags.mode, flags.cmd, rat.Context{}))

	rat.Run()
}

package main

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

	rat "github.com/ericfreese/rat/lib"
	flag "github.com/spf13/pflag"
)

var (
	RatVersion = "0.0.2"
)

var flags struct {
	cmd     string
	mode    string
	version bool
}

func init() {
	flag.StringVarP(&flags.cmd, "cmd", "c", "", "command to run (required)")
	flag.StringVarP(&flags.mode, "mode", "m", "default", "name of mode")
	flag.BoolVarP(&flags.version, "version", "v", false, "display version and exit")

	flag.Parse()
}

func validateFlags() bool {
	if len(flags.cmd) == 0 {
		fmt.Fprintln(os.Stderr, "flag 'cmd' is required")
		return false
	}

	return true
}

func main() {
	var err error

	if flags.version {
		fmt.Println(RatVersion)
		return
	}

	if !validateFlags() {
		flag.Usage()
		os.Exit(1)
	}

	if err = rat.Init(); err != nil {
		panic(err)
	}

	defer rat.Close()

	if config, err := os.Open(filepath.Join(rat.ConfigDir, "ratrc")); err == nil {
		rat.LoadConfig(config)
		config.Close()
	}

	rat.PushPager(rat.NewCmdPager(flags.mode, flags.cmd, rat.Context{}))

	rat.Run()
}

Remove default for 'cmd' flag


package minion

import (
	"mime/multipart"

	"github.com/pressly/chi"
)

func (c *Context) ByGet(name string) string {
	return chi.URLParam(c.Req, name)
}

func (c *Context) ByQuery(name string) string {
	values := c.Req.URL.Query()
	if len(values) == 0 {
		return ""
	}

	return values[name][0]
}

func (c *Context) ByPost(name string) string {
	return c.Req.FormValue(name)
}

func (c *Context) File(name string) (multipart.File, *multipart.FileHeader, error) {
	return c.Req.FormFile(name)
}

package minion

import (
	"mime/multipart"

	"github.com/pressly/chi"
)

// ByGet shortcut to chi.URLParam
// returns the url parameter from a http.Request object.
func (c *Context) ByGet(name string) string {
	return chi.URLParam(c.Req, name)
}

// ByQuery shortcut to (u *URL) Query()
// parses RawQuery and returns the corresponding values
func (c *Context) ByQuery(name string) string {
	values := c.Req.URL.Query()
	if len(values) == 0 {
		return ""
	}

	return values[name][0]
}

// ByPost shortcut to (r *Request) FormValue
// returns the first value for the named component of the query.
func (c *Context) ByPost(name string) string {
	return c.Req.FormValue(name)
}

// File shortcut to (r *Request) FormFile
// returns the first file for the provided form key
func (c *Context) File(name string) (multipart.File, *multipart.FileHeader, error) {
	return c.Req.FormFile(name)
}

Add comment to params funcs


package main

import (
	"errors"
	"sdl"
)

const (
	defaultWidth, defaultHeight = 1024, 768
	gameName = "gogame"
)

func main() {
	ctx, err := sdl.NewContext(gameName, defaultWidth, defaultHeight)
	if err != nil {
		panic(err)
	}
	defer ctx.Close()

	quit := 	errors.New("quitting")
	for {
		err = sdl.HandleEvents(func(e interface{}) error {
			switch v := e.(type) {
			case sdl.QuitEvent:
				return quit
			case sdl.KeyEvent:
				if v.Type == sdl.KeyUp && v.KeyCode == 'q' {
					return quit
				}
			}
			return nil
		})
		if err == quit {
			return
		}
		ctx.Render()
		sdl.Delay(1)
	}
}

package main

import (
	"errors"
	"sdl"
)

const (
	defaultWidth, defaultHeight = 1024, 768
	gameName = "gogame"
)

var (
	quitting = errors.New("quitting")
)

func eventHandler(e interface{}) error {
	switch v := e.(type) {
	case sdl.QuitEvent:
		return quitting
	case sdl.KeyEvent:
		if v.Type == sdl.KeyUp {
			switch v.KeyCode {
			case 'q':
				return quitting
			}
		}
	}
	return nil
}

func main() {
	ctx, err := sdl.NewContext(gameName, defaultWidth, defaultHeight)
	if err != nil {
		panic(err)
	}
	defer ctx.Close()

	for {
		err = sdl.HandleEvents(eventHandler)
		if err == quitting {
			return
		}
		ctx.Render()
		sdl.Delay(1)
	}
}

Put event handler in separate func


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

// +build !js

package ui

// #cgo LDFLAGS: -lgdi32
//
// #include <windows.h>
//
// static int getDPI() {
//   HDC dc = GetWindowDC(0);
//   int dpi = GetDeviceCaps(dc, LOGPIXELSX);
//   ReleaseDC(0, dc);
//   return dpi;
// }
import "C"

func deviceScale() float64 {
	dpi := int(C.getDPI())
	return float64(dpi) / 96
}

func glfwScale() float64 {
	return deviceScale()
}

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

// +build !js

package ui

// #cgo LDFLAGS: -lgdi32
//
// #include <windows.h>
//
// static char* getDPI(int* dpi) {
//   HDC dc = GetWindowDC(0);
//   *dpi = GetDeviceCaps(dc, LOGPIXELSX);
//   if (!ReleaseDC(0, dc)) {
//     return "ReleaseDC failed";
//   }
//   return "";
// }
import "C"

func deviceScale() float64 {
	dpi := C.int(0)
	if errmsg := C.GoString(C.getDPI(&dpi)); errmsg != "" {
		panic(errmsg)
	}
	return float64(dpi) / 96
}

func glfwScale() float64 {
	return deviceScale()
}

Check the return value of ReleaseDC()


package pdf

import "testing"

func TestTestFile (t *testing.T) {
	f := NewFile("/tmp/foo.pdf")
	f.Close()
}

package pdf

import "testing"

func TestTestFile (t *testing.T) {
	f := NewFile("/tmp/foo.pdf")
	obj1 := f.AddObject (NewNumeric(3.14))
	obj2 := f.AddObject (NewNumeric(2.718))
	f.DeleteObject (obj1)
	f.AddObject (NewNumeric(3))
	f.DeleteObject (obj2)
	f.Close()
}

Add File.AddObject() and File.DeleteObject() to unit test.


package slackapi

import (
	"encoding/json"
	"testing"
)

func CheckResponse(t *testing.T, x interface{}, y string) {
	out, err := json.Marshal(x)
	if err != nil {
		t.Fatal("json fromat;", err)
	}
	if string(out) != y {
		t.Fatalf("invalid json response;\n- %s\n+ %s\n", y, out)
	}
}

func TestAPITest(t *testing.T) {
	s := New()
	x := s.APITest()
	y := `{"ok":true}`
	CheckResponse(t, x, y)
}

func TestAppsList(t *testing.T) {
	s := New()
	x := s.AppsList()
	y := `{"ok":false,"error":"not_authed","apps":null,"cache_ts":""}`
	CheckResponse(t, x, y)
}

Remove apps.list unit test due to API uncertanties


// Copyright 2015 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package errors

import (
	"fmt"

	"github.com/google/mtail/internal/vm/position"
	"github.com/pkg/errors"
)

type compileError struct {
	pos position.Position
	msg string
}

func (e compileError) Error() string {
	return e.pos.String() + ": " + e.msg
}

// ErrorList contains a list of compile errors.
type ErrorList []*compileError

// Add appends an error at a position to the list of errors.
func (p *ErrorList) Add(pos *position.Position, msg string) {
	*p = append(*p, &compileError{*pos, msg})
}

// Append puts an ErrorList on the end of this ErrorList.
func (p *ErrorList) Append(l ErrorList) {
	*p = append(*p, l...)
}

// ErrorList implements the error interface.
func (p ErrorList) Error() string {
	switch len(p) {
	case 0:
		return "no errors"
	case 1:
		return p[0].Error()
	}
	var r string
	for _, e := range p {
		r = r + fmt.Sprintf("%s\n", e)
	}
	return r[:len(r)-1]
}

func Errorf(format string, args ...interface{}) error {
	return errors.Errorf(format, args...)
}

// Copyright 2015 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

package errors

import (
	"fmt"
	"strings"

	"github.com/google/mtail/internal/vm/position"
	"github.com/pkg/errors"
)

type compileError struct {
	pos position.Position
	msg string
}

func (e compileError) Error() string {
	return e.pos.String() + ": " + e.msg
}

// ErrorList contains a list of compile errors.
type ErrorList []*compileError

// Add appends an error at a position to the list of errors.
func (p *ErrorList) Add(pos *position.Position, msg string) {
	*p = append(*p, &compileError{*pos, msg})
}

// Append puts an ErrorList on the end of this ErrorList.
func (p *ErrorList) Append(l ErrorList) {
	*p = append(*p, l...)
}

// ErrorList implements the error interface.
func (p ErrorList) Error() string {
	switch len(p) {
	case 0:
		return "no errors"
	case 1:
		return p[0].Error()
	}
	var r strings.Builder
	for _, e := range p {
		r.WriteString(fmt.Sprintf("%s\n", e))
	}
	return r.String()
}

func Errorf(format string, args ...interface{}) error {
	return errors.Errorf(format, args...)
}

Use strings.Builder instead of string concatenation.


package websocket

import(
    "net/http"
    "log"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

type WebSocketHandler struct {}

func NewWebSocketHandler() *WebSocketHandler {
    return &WebSocketHandler{}
}

func (handler *WebSocketHandler) ServeHTTP(
    responseWriter http.ResponseWriter,
    request *http.Request,
) {
    connection, err := upgrader.Upgrade(responseWriter, request, nil)

    if err != nil {
        log.Println(err.Error())
        return
    }

    defer connection.Close()
    for {
        messageType, message, err := connection.ReadMessage()

        if err != nil {
            log.Println("read: ", err.Error())
            break
        }

        log.Printf("recv: %s", message)
        err = connection.WriteMessage(messageType, message)
        if err != nil {
            log.Println("write: ", err)
            break
        }
    }
}

package websocket

import(
    "net/http"
    "log"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

type WebSocketHandler struct {}

type Data struct {
    Id int `json:"id"`
    Test interface{} `json:"test"`
}

func NewWebSocketHandler() *WebSocketHandler {
    return &WebSocketHandler{}
}

func (handler *WebSocketHandler) ServeHTTP(
    responseWriter http.ResponseWriter,
    request *http.Request,
) {
    connection, err := upgrader.Upgrade(responseWriter, request, nil)

    if err != nil {
        log.Println(err.Error())
        return
    }

    defer connection.Close()
    data := Data{}
    for {
        err := connection.ReadJSON(&data)

        if err != nil {
            log.Println("read: ", err.Error())
            break
        }

        log.Printf("recv: ", data)
        err = connection.WriteJSON(data)
        if err != nil {
            log.Println("write: ", err.Error())
            break
        }
    }
}

Add json reader/writer for websocket connection


package util

import (
	"strings"

	"k8s.io/apiserver/pkg/authentication/user"
	"k8s.io/apiserver/pkg/authorization/authorizer"

	authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
)

// ToDefaultAuthorizationAttributes coerces Action to authorizer.Attributes.
func ToDefaultAuthorizationAttributes(user user.Info, namespace string, in authorizationapi.Action) authorizer.Attributes {
	tokens := strings.SplitN(in.Resource, "/", 2)
	resource := ""
	subresource := ""
	switch {
	case len(tokens) == 2:
		subresource = tokens[1]
		fallthrough
	case len(tokens) == 1:
		resource = tokens[0]
	}

	return authorizer.AttributesRecord{
		User:            user,
		Verb:            in.Verb,
		Namespace:       namespace,
		APIGroup:        in.Group,
		APIVersion:      in.Version,
		Resource:        resource,
		Subresource:     subresource,
		Name:            in.ResourceName,
		ResourceRequest: !in.IsNonResourceURL,
		Path:            in.Path,
	}
}

package util

import (
	"strings"

	"k8s.io/apiserver/pkg/authentication/user"
	"k8s.io/apiserver/pkg/authorization/authorizer"

	authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
)

// ToDefaultAuthorizationAttributes coerces Action to authorizer.Attributes.
func ToDefaultAuthorizationAttributes(user user.Info, namespace string, in authorizationapi.Action) authorizer.Attributes {
	tokens := strings.SplitN(in.Resource, "/", 2)
	resource := ""
	subresource := ""
	switch {
	case len(tokens) == 2:
		subresource = tokens[1]
		fallthrough
	case len(tokens) == 1:
		resource = tokens[0]
	}

	return &authorizer.AttributesRecord{
		User:            user,
		Verb:            in.Verb,
		Namespace:       namespace,
		APIGroup:        in.Group,
		APIVersion:      in.Version,
		Resource:        resource,
		Subresource:     subresource,
		Name:            in.ResourceName,
		ResourceRequest: !in.IsNonResourceURL,
		Path:            in.Path,
	}
}

Return a pointer instead of a copy.


package slack9gag

import (
	"fmt"
	"net/http"
)

func init() {
	http.HandleFunc("/", handler)
	fmt.Println("listening...")
}

func handler(w http.ResponseWriter, r *http.Request) {
	// Read the Request Parameter "command"
	command := r.FormValue("command")

	if command == "/9gag" {
		fmt.Fprint(w, "Hello World")
	} else {
		fmt.Fprint(w, "I do not understand your command.")
	}
}

package main

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

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("listening...")
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	// Read the Request Parameter "command"
	command := r.FormValue("command")

	if command == "/9gag" {
		fmt.Fprint(w, "Hello World")
	} else {
		fmt.Fprint(w, "I do not understand your command.")
	}
}

Change package name to main. Add ListenAndServ.


package main

import (
	"fmt"
	"time"

	"github.com/bgv/workerpool"
)

func main() {
	// Number of workers, and Size of the job queue
	pool := workerpool.New(10, 50)
	// Release the resources after we finish
	defer pool.Stop()

	// create and submit 10 jobs to the pool
	for i := 0; i < 100; i++ {
		count := i

		pool.JobQueue <- func() {
			fmt.Printf("I am job! Number %d\n", count)
		}
	}

	// dummy wait until jobs are finished
	time.Sleep(1 * time.Second)

	// release resources used by workerpool
	pool.Stop()

}

package main

import (
	"fmt"
	"time"

	"github.com/bgv/workerpool"
)

func main() {
	// Number of workers, and Size of the job queue
	pool := workerpool.New(10, 50)

	// create and submit 10 jobs to the pool
	for i := 0; i < 100; i++ {
		count := i

		pool.JobQueue <- func() {
			fmt.Printf("I am job! Number %d\n", count)
		}
	}

	// dummy wait until jobs are finished
	time.Sleep(1 * time.Second)

	// release resources used by workerpool
	pool.Stop()
}

Remove double Stop() in the example causing deadlock


package util

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"syscall"
)

func CallBrowser(url string) error {
	fmt.Fprintf(os.Stderr, "Running a browser to open %s...\r\n", url)

	var attr os.ProcAttr
	attr.Sys = &syscall.SysProcAttr{HideWindow: false}
	attr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}

	path, err := exec.LookPath("cmd")
	if err != nil {
		return err
	}
	proc, err := os.StartProcess(path, []string{path, "/C", "start", strings.Replace(url, "&", "^&", -1)}, &attr)
	if err != nil {

		return err
	}

	_, err = proc.Wait()
	return err
}

package util

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
	"syscall"
)

func CallBrowser(url string) error {
	fmt.Fprintf(os.Stderr, "Running a browser to open %s...\r\n", url)

	var attr os.ProcAttr
	attr.Sys = &syscall.SysProcAttr{HideWindow: false}
	attr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}

	path, err := exec.LookPath("cmd")
	if err != nil {
		return err
	}
	// so on windows when you're using cmd you have to escape ampersands with the ^ character.
	// ¯\(º_o)/¯
	url = strings.Replace(url, "&", "^&", -1)
	proc, err := os.StartProcess(path, []string{path, "/C", "start", url }, &attr)
	if err != nil {

		return err
	}

	_, err = proc.Wait()
	return err
}

Refactor the Windows CallBrowser slightly.


package main

import (
	"delay"
	"fmt"

	"stm32/hal/gpio"
	"stm32/hal/system"
	"stm32/hal/system/timer/systick"
)

var led gpio.Pin

func init() {
	system.Setup(-48, 6, 20, 0, 0, 2)
	systick.Setup()

	gpio.A.EnableClock(false)
	led = gpio.A.Pin(5)

	cfg := gpio.Config{Mode: gpio.Out, Speed: gpio.Low}
	led.Setup(&cfg)
}

func main() {
	delay.Millisec(500)
	buses := []system.Bus{
		system.Core,
		system.AHB,
		system.APB1,
		system.APB2,
	}
	fmt.Printf("\r\n")
	for _, bus := range buses {
		fmt.Printf("%s: %d MHz\r\n", bus, bus.Clock())
	}
	for {
		led.Set()
		delay.Millisec(50)
		led.Clear()
		delay.Millisec(950)
	}
}

package main

import (
	"delay"
	"fmt"

	"stm32/hal/gpio"
	"stm32/hal/system"
	"stm32/hal/system/timer/systick"
)

var led gpio.Pin

func init() {
	system.Setup(-48, 6, 20, 0, 0, 2) // 80 MHz (fastest for voltage Range 1).
	//system.Setup(-4, 1, 26, 0, 0, 4) // 26 MHz (fastest for voltage Range 2).
	systick.Setup()

	gpio.A.EnableClock(false)
	led = gpio.A.Pin(5)

	cfg := gpio.Config{Mode: gpio.Out, Speed: gpio.Low}
	led.Setup(&cfg)
}

func main() {
	delay.Millisec(500)
	buses := []system.Bus{
		system.Core,
		system.AHB,
		system.APB1,
		system.APB2,
	}
	fmt.Printf("\r\n")
	for _, bus := range buses {
		fmt.Printf("%4s: %9d Hz\r\n", bus, bus.Clock())
	}
	for {
		led.Set()
		delay.Millisec(50)
		led.Clear()
		delay.Millisec(950)
	}
}

Fix unit for bus clock.


package main

import (
	"fmt"

	log "github.com/Sirupsen/logrus"
	"github.com/ehazlett/interlock/plugins"
	"github.com/samalba/dockerclient"
)

type (
	EventHandler struct {
		Manager *Manager
	}
)

func NewEventHandler(mgr *Manager) *EventHandler {
	return &EventHandler{
		Manager: mgr,
	}
}

func (l *EventHandler) Handle(e *dockerclient.Event, ec chan error, args ...interface{}) {
	plugins.Log("interlock", log.DebugLevel,
		fmt.Sprintf("event: date=%d type=%s image=%s container=%s", e.Time, e.Status, e.From, e.Id[:12]))

	go plugins.DispatchEvent(l.Manager.Config, l.Manager.Client, e, ec)
}

package main

import (
	"fmt"

	log "github.com/Sirupsen/logrus"
	"github.com/ehazlett/interlock/plugins"
	"github.com/samalba/dockerclient"
)

type (
	EventHandler struct {
		Manager *Manager
	}
)

func NewEventHandler(mgr *Manager) *EventHandler {
	return &EventHandler{
		Manager: mgr,
	}
}

func (l *EventHandler) Handle(e *dockerclient.Event, ec chan error, args ...interface{}) {
	plugins.Log("interlock", log.DebugLevel,
		fmt.Sprintf("event: date=%d type=%s image=%s container=%s", e.Time, e.Status, e.From, e.Id))

	go plugins.DispatchEvent(l.Manager.Config, l.Manager.Client, e, ec)
}

Fix crash when event Id is less than 12 chars


/*
Copyright IBM Corp. 2016 All Rights Reserved.

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

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

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

package kvledger

import (
	"os"
	"testing"

	"github.com/hyperledger/fabric/core/config"
	"github.com/spf13/viper"
)

type testEnv struct {
	t testing.TB
}

func newTestEnv(t testing.TB) *testEnv {
	return createTestEnv(t, "/tmp/fabric/ledgertests/kvledger")
}

func createTestEnv(t testing.TB, path string) *testEnv {
	viper.Set("peer.fileSystemPath", path)
	env := &testEnv{t}
	env.cleanup()
	return env
}

func (env *testEnv) cleanup() {
	path := config.GetPath("peer.fileSystemPath")
	os.RemoveAll(path)
}

/*
Copyright IBM Corp. 2016 All Rights Reserved.

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

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

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

package kvledger

import (
	"math/rand"
	"os"
	"path/filepath"
	"strconv"
	"testing"

	"github.com/spf13/viper"
)

type testEnv struct {
	t    testing.TB
	path string
}

func newTestEnv(t testing.TB) *testEnv {
	path := filepath.Join(
		os.TempDir(),
		"fabric",
		"ledgertests",
		"kvledger",
		strconv.Itoa(rand.Int()))
	return createTestEnv(t, path)
}

func createTestEnv(t testing.TB, path string) *testEnv {
	env := &testEnv{
		t:    t,
		path: path}
	env.cleanup()
	viper.Set("peer.fileSystemPath", env.path)
	return env
}

func (env *testEnv) cleanup() {
	os.RemoveAll(env.path)
}

Fix ledger test race condition


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

package utils

import (
	"github.com/gogo/protobuf/proto"
)

// ProtoToString converts proto message to string.
func ProtoToString(message proto.Message) string {
	if message == nil {
		return "<NIL>"
	}
	// wrap with curly braces, it is easier to read
	return "{ " + message.String() + " }"
}

// ErrorToString converts error to string.
func ErrorToString(err error) string {
	if err == nil {
		return "<NIL>"
	}
	return err.Error()
}

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

package utils

import (
	"github.com/gogo/protobuf/proto"
	prototypes "github.com/gogo/protobuf/types"
)

// ProtoToString converts proto message to string.
func ProtoToString(message proto.Message) string {
	if message == nil {
		return "<NIL>"
	}
	if _, isEmpty := message.(*prototypes.Empty); isEmpty {
		return "<EMPTY>"
	}
	// wrap with curly braces, it is easier to read
	return "{ " + message.String() + " }"
}

// ErrorToString converts error to string.
func ErrorToString(err error) string {
	if err == nil {
		return "<NIL>"
	}
	return err.Error()
}

Print Empty proto message nicely.


package sofa

import (
	"net/url"
	"strings"
)

// FutonURL attempts to correctly convert any CouchDB path into a URL to be used to
// access the same documents through the Futon web GUI.
func (con *Connection) FutonURL(path string) url.URL {
	patharr := strings.Split(strings.Trim(path, "/"), "/")

	furl := con.URL("/")
	furl.Path = urlConcat(furl.Path, "_utils/")

	if len(patharr) == 0 || patharr[0] == "" {
		return furl
	}

	isDatabaseURL := false
	if len(patharr) == 1 {
		isDatabaseURL = true
	} else {
		switch patharr[1] {
		case "_design", "_all_docs":
			isDatabaseURL = true
		}
	}

	furl.RawQuery = strings.TrimLeft(path, "/")

	if isDatabaseURL {
		furl.Path = urlConcat(furl.Path, "database.html")
		return furl
	}

	furl.Path = urlConcat(furl.Path, "document.html")
	return furl
}

func Boolean(b bool) BooleanParameter {
	if b {
		return True
	}

	return False
}

package sofa

import (
	"net/url"
	"strings"
)

// FutonURL attempts to correctly convert any CouchDB path into a URL to be used to
// access the same documents through the Futon web GUI.
func (con *Connection) FutonURL(path string) url.URL {
	patharr := strings.Split(strings.Trim(path, "/"), "/")

	furl := con.URL("/")
	furl.Path = urlConcat(furl.Path, "_utils/")

	if len(patharr) == 0 || patharr[0] == "" {
		return furl
	}

	isDatabaseURL := false
	if len(patharr) == 1 {
		isDatabaseURL = true
	} else {
		switch patharr[1] {
		case "_design", "_all_docs":
			isDatabaseURL = true
		}
	}

	furl.RawQuery = strings.TrimLeft(path, "/")

	if isDatabaseURL {
		furl.Path = urlConcat(furl.Path, "database.html")
		return furl
	}

	furl.Path = urlConcat(furl.Path, "document.html")
	return furl
}

func FromBoolean(b bool) BooleanParameter {
	if b {
		return True
	}

	return False
}

func ToBoolean(b BooleanParameter) bool {
	return b == True
}

Add a function to convert to normal Go booleans too


package main

import (
	"encoding/json"
	"fmt"
	"github.com/imdario/mergo"
	"io/ioutil"
)

// Configuration is the configuration type
type Configuration struct {
	Environment
	Environments map[string]Environment `json:"environments"`
}

// Load open, read and parse the given configuration file
func Load(filename string) (Configuration, error) {
	var c Configuration

	raw, err := ioutil.ReadFile(filename)
	if err != nil {
		return c, err
	}

	err = json.Unmarshal(raw, &c)
	if err != nil {
		return c, err
	}

	return c, nil
}

// Env return the requested environment from the configuration
func (c Configuration) Env(name string) (Environment, error) {
	if name == "default" {
		return c.Environment, nil
	}

	overrides, found := c.Environments[name]
	if !found {
		return Environment{}, fmt.Errorf("unknown environment %s", name)
	}

	_ = mergo.Merge(&overrides, c.Environment) // No error can possibly occur here
	return overrides, nil
}

package main

import (
	"encoding/json"
	"fmt"
	"github.com/imdario/mergo"
	"io/ioutil"
)

// Configuration is the configuration type
type Configuration struct {
	Environment
	Environments map[string]Environment `json:"environments"`
}

// Load open, read and parse the given configuration file
func Load(filename string) (Configuration, error) {
	var c Configuration

	raw, err := ioutil.ReadFile(filename)
	if err != nil {
		return c, err
	}

	err = json.Unmarshal(raw, &c)
	if err != nil {
		return c, err
	}

	return c, nil
}

// Env return the requested environment from the configuration
func (c Configuration) Env(name string) (Environment, error) {
	if name == "default" {
		return c.Environment, nil
	}

	env, found := c.Environments[name]
	if !found {
		return Environment{}, fmt.Errorf("unknown environment %s", name)
	}

	_ = mergo.Merge(&env, c.Environment) // No error can possibly occur here
	return env, nil
}

Refactor the Configuration.Env function to be easier to understand


package server

import (
	"errors"
	"net/url"
)

type getExternalLinksResponse struct {
	StatusFeed  *string      `json:"statusFeed,omitempty"` // Location of the a JSON Feed for client's Status page News Feed
	CustomLinks []CustomLink `json:"custom,omitempty"`     // Any custom external links for client's User menu
}

// CustomLink is a handler that returns a custom link to be used in server's routes response, within ExternalLinks
type CustomLink struct {
	Name string `json:"name,omitempty"`
	URL  string `json:"url,omitempty"`
}

// NewCustomLinks transforms `--custom-link` CLI flag data or `CUSTOM_LINKS` ENV
// var data into a data structure that the Chronograf client will expect
func NewCustomLinks(links map[string]string) ([]CustomLink, error) {
	var customLinks []CustomLink
	for name, link := range links {
		if name == "" {
			return nil, errors.New("CustomLink missing key for Name")
		}
		if link == "" {
			return nil, errors.New("CustomLink missing value for URL")
		}
		_, err := url.Parse(link)
		if err != nil {
			return nil, err
		}

		customLinks = append(customLinks, CustomLink{
			Name: name,
			URL:  link,
		})
	}
	return customLinks, nil
}

package server

import (
	"errors"
	"net/url"
)

type getExternalLinksResponse struct {
	StatusFeed  *string      `json:"statusFeed,omitempty"` // Location of the a JSON Feed for client's Status page News Feed
	CustomLinks []CustomLink `json:"custom,omitempty"`     // Any custom external links for client's User menu
}

// CustomLink is a handler that returns a custom link to be used in server's routes response, within ExternalLinks
type CustomLink struct {
	Name string `json:"name"`
	URL  string `json:"url"`
}

// NewCustomLinks transforms `--custom-link` CLI flag data or `CUSTOM_LINKS` ENV
// var data into a data structure that the Chronograf client will expect
func NewCustomLinks(links map[string]string) ([]CustomLink, error) {
	var customLinks []CustomLink
	for name, link := range links {
		if name == "" {
			return nil, errors.New("CustomLink missing key for Name")
		}
		if link == "" {
			return nil, errors.New("CustomLink missing value for URL")
		}
		_, err := url.Parse(link)
		if err != nil {
			return nil, err
		}

		customLinks = append(customLinks, CustomLink{
			Name: name,
			URL:  link,
		})
	}
	return customLinks, nil
}

Remove omitempty from CustomLink definition since should never b


package common

import (
	bosherr "github.com/cloudfoundry/bosh-utils/errors"
)

type AgentOptions struct {
	// e.g. "https://user:password@127.0.0.1:4321/agent"
	Mbus string

	// e.g. ["0.us.pool.ntp.org"]. Ok to be empty
	NTP []string

	Blobstore BlobstoreOptions

	//vcap password
	VcapPassword string
}

type RegistryOptions struct {
	Host     string
	Port     int
	Username string
	Password string
}

type BlobstoreOptions struct {
	Provider string                 `json:"provider"`
	Options  map[string]interface{} `json:"options"`
}

func (o AgentOptions) Validate() error {
	if o.Mbus == "" {
		return bosherr.Error("Must provide non-empty Mbus")
	}

	err := o.Blobstore.Validate()
	if err != nil {
		return bosherr.WrapError(err, "Validating Blobstore configuration")
	}

	return nil
}

func (o BlobstoreOptions) Validate() error {
	if o.Provider == "" {
		return bosherr.Error("Must provide non-empty provider")
	}

	return nil
}

package common

import (
	bosherr "github.com/cloudfoundry/bosh-utils/errors"
)

type AgentOptions struct {
	// e.g. "https://user:password@127.0.0.1:4321/agent"
	Mbus string

	// e.g. ["0.us.pool.ntp.org"]. Ok to be empty
	NTP []string

	Blobstore BlobstoreOptions

	//The SHA-512 encrypted vcap password
	VcapPassword string
}

type RegistryOptions struct {
	Host     string
	Port     int
	Username string
	Password string
}

type BlobstoreOptions struct {
	Provider string                 `json:"provider"`
	Options  map[string]interface{} `json:"options"`
}

func (o AgentOptions) Validate() error {
	if o.Mbus == "" {
		return bosherr.Error("Must provide non-empty Mbus")
	}

	err := o.Blobstore.Validate()
	if err != nil {
		return bosherr.WrapError(err, "Validating Blobstore configuration")
	}

	return nil
}

func (o BlobstoreOptions) Validate() error {
	if o.Provider == "" {
		return bosherr.Error("Must provide non-empty provider")
	}

	return nil
}

Update the comment for VcapPassword


package engine

import (
	"archive/tar"
	"bytes"
	"io"
)

type Stream struct {
	io.ReadCloser
	Size int64
}

func NewStream(data io.ReadCloser, size int64) Stream {
	return Stream{data, size}
}

func (s Stream) Out(dst io.Writer) error {
	defer s.Close()
	if _, err := io.CopyN(dst, s, s.Size); err != nil {
		return err
	}
	return nil
}

func tarFile(name string, contents io.Reader, size, mode int64) (io.Reader, error) {
	tarBuffer := &bytes.Buffer{}
	tarball := tar.NewWriter(tarBuffer)
	defer tarball.Close()
	header := &tar.Header{Name: name, Size: size, Mode: mode}
	if err := tarball.WriteHeader(header); err != nil {
		return nil, err
	}
	if _, err := io.CopyN(tarball, contents, size); err != nil {
		return nil, err
	}
	return tarBuffer, nil
}

package engine

import (
	"archive/tar"
	"bytes"
	"errors"
	"io"
)

type Stream struct {
	io.ReadCloser
	Size   int64
	closed bool
}

func NewStream(data io.ReadCloser, size int64) Stream {
	return Stream{data, size, false}
}

func (s *Stream) Out(dst io.Writer) error {
	if s.closed {
		return errors.New("closed")
	}
	defer s.ReadCloser.Close()
	n, err := io.CopyN(dst, s, s.Size)
	s.Size -= n
	return err
}

func (s *Stream) Close() error {
	if s.closed {
		return nil
	}
	if err := s.ReadCloser.Close(); err != nil {
		return err
	}
	s.closed = true
	return nil
}

func tarFile(name string, contents io.Reader, size, mode int64) (io.Reader, error) {
	tarBuffer := &bytes.Buffer{}
	tarball := tar.NewWriter(tarBuffer)
	defer tarball.Close()
	header := &tar.Header{Name: name, Size: size, Mode: mode}
	if err := tarball.WriteHeader(header); err != nil {
		return nil, err
	}
	if _, err := io.CopyN(tarball, contents, size); err != nil {
		return nil, err
	}
	return tarBuffer, nil
}

Add close method to stream


package addrs

import (
	"fmt"
)

// InputVariable is the address of an input variable.
type InputVariable struct {
	referenceable
	Name string
}

func (v InputVariable) String() string {
	return "var." + v.Name
}

// AbsInputVariableInstance is the address of an input variable within a
// particular module instance.
type AbsInputVariableInstance struct {
	Module   ModuleInstance
	Variable InputVariable
}

// InputVariable returns the absolute address of the input variable of the
// given name inside the receiving module instance.
func (m ModuleInstance) InputVariable(name string) AbsInputVariableInstance {
	return AbsInputVariableInstance{
		Module: m,
		Variable: InputVariable{
			Name: name,
		},
	}
}

func (v AbsInputVariableInstance) String() string {
	if len(v.Module) == 0 {
		return v.String()
	}

	return fmt.Sprintf("%s.%s", v.Module.String(), v.Variable.String())
}

package addrs

import (
	"fmt"
)

// InputVariable is the address of an input variable.
type InputVariable struct {
	referenceable
	Name string
}

func (v InputVariable) String() string {
	return "var." + v.Name
}

// AbsInputVariableInstance is the address of an input variable within a
// particular module instance.
type AbsInputVariableInstance struct {
	Module   ModuleInstance
	Variable InputVariable
}

// InputVariable returns the absolute address of the input variable of the
// given name inside the receiving module instance.
func (m ModuleInstance) InputVariable(name string) AbsInputVariableInstance {
	return AbsInputVariableInstance{
		Module: m,
		Variable: InputVariable{
			Name: name,
		},
	}
}

func (v AbsInputVariableInstance) String() string {
	if len(v.Module) == 0 {
		return v.Variable.String()
	}

	return fmt.Sprintf("%s.%s", v.Module.String(), v.Variable.String())
}

Fix infinite recursion in AbsInputVariableInstance.String


package main

import (
	"bufio"
	"fmt"
	"os"

	"github.com/harlow/kinesis-connectors"
	"github.com/joho/godotenv"
	"github.com/sendgridlabs/go-kinesis"
)

func main() {
	godotenv.Load()

	// Initialize Kinesis client
	auth := kinesis.NewAuth()
	ksis := kinesis.New(&auth, kinesis.Region{})

	// Create stream
	connector.CreateStream(ksis, "userStream", 2)

	// read file
	// https://s3.amazonaws.com/kinesis.test/users.txt
	file, _ := os.Open("tmp/users.txt")
	defer file.Close()
	scanner := bufio.NewScanner(file)

	args := kinesis.NewArgs()
	args.Add("StreamName", "userStream")
	ctr := 0

	for scanner.Scan() {
		l := scanner.Text()
		ctr = ctr + 1
		key := fmt.Sprintf("partitionKey-%d", ctr)

		args := kinesis.NewArgs()
		args.Add("StreamName", "userStream")
		args.AddRecord([]byte(l), key)
		ksis.PutRecords(args)
		fmt.Print(".")
	}

	fmt.Println(".")
	fmt.Println("Finished populating userStream")
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sync"

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

// Note: download file with test data
// curl https://s3.amazonaws.com/kinesis.test/users.txt -o /tmp/users.txt

func main() {
	wg := &sync.WaitGroup{}
	jobCh := make(chan string)

	// read sample data
	file, _ := os.Open("/tmp/users.txt")
	defer file.Close()
	scanner := bufio.NewScanner(file)

	// initialize kinesis client
	svc := kinesis.New(session.New())

	for i := 0; i < 4; i++ {
		wg.Add(1)
		go func() {
			for data := range jobCh {
				params := &kinesis.PutRecordInput{
					Data:         []byte(data),
					PartitionKey: aws.String("partitionKey"),
					StreamName:   aws.String("hw-test-stream"),
				}

				_, err := svc.PutRecord(params)

				if err != nil {
					fmt.Println(err.Error())
					return
				} else {
					fmt.Print(".")
				}
			}
			wg.Done()
		}()
	}

	for scanner.Scan() {
		data := scanner.Text()
		jobCh <- data
	}

	fmt.Println(".")
	fmt.Println("Finished populating stream")
}

Use AWS SDK and concurrency


package main

import (
	"os"
	"os/exec"
)

const (
	// BtrfsCommand is the name of the btrfs command-line tool binary.
	BtrfsCommand = "btrfs"
)

// Snapshot creates a Btrfs snapshot of src at dst, optionally making
// it writable. If dst already exists, the snapshot is not created and
// an error is returned.
func Snapshot(src, dst string, rw bool) error {
	args := make([]string, 0, 6)
	args = append(args, "btrfs", "subvolume", "snapshot")
	if !rw {
		args = append(args, "-r")
	}
	args = append(args, src, dst)

	btrfs := exec.Command(BtrfsCommand, args...)
	btrfs.Stdin = os.Stdin
	btrfs.Stdout = os.Stdout
	btrfs.Stderr = os.Stderr

	return btrfs.Run()
}

package main

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

const (
	// BtrfsCommand is the name of the btrfs command-line tool binary.
	BtrfsCommand = "btrfs"
)

// Snapshot creates a Btrfs snapshot of src at dst, optionally making
// it writable. If dst already exists, the snapshot is not created and
// an error is returned.
func Snapshot(src, dst string, rw bool) error {
	_, err := os.Stat(dst)
	switch {
	case os.IsNotExist(err):

	case err == nil:
		return &SnapshotDestExistsError{dst}
	default:
		return err
	}

	args := make([]string, 0, 6)
	args = append(args, "btrfs", "subvolume", "snapshot")
	if !rw {
		args = append(args, "-r")
	}
	args = append(args, src, dst)

	btrfs := exec.Command(BtrfsCommand, args...)
	btrfs.Stdin = os.Stdin
	btrfs.Stdout = os.Stdout
	btrfs.Stderr = os.Stderr

	return btrfs.Run()
}

type SnapshotDestExistsError struct {
	Dest string
}

func (err SnapshotDestExistsError) Error() string {
	return fmt.Sprintf("Snapshot destination %q already exists", err.Dest)
}

Make Snapshot() actually check for an existing destination as documented.


package scraperService

import (
	"math/rand"
	"net"

	"github.com/ewhal/nyaa/model"
)

const InitialConnectionID = 0x41727101980

type Bucket struct {
	Addr         net.Addr
	transactions map[uint32]*Transaction
}

func (b *Bucket) NewTransaction(swarms []model.Torrent) (t *Transaction) {
	id := rand.Uint32()
	// get good id
	_, ok := b.transactions[id]
	for !ok {
		id = rand.Uint32()
		_, ok = b.transactions[id]
	}
	t = &Transaction{
		TransactionID: id,
		swarms:        swarms,
		state:         stateSendID,
	}
	b.transactions[id] = t
	return

}

func (b *Bucket) VisitTransaction(tid uint32, v func(*Transaction)) {
	t, ok := b.transactions[tid]
	if ok {
		go v(t)
	} else {
		v(nil)
	}
}

func NewBucket(a net.Addr) *Bucket {
	return &Bucket{
		transactions: make(map[uint32]*Transaction),
		Addr:         a,
	}
}

package scraperService

import (
	"math/rand"
	"net"

	"github.com/ewhal/nyaa/model"
)

const InitialConnectionID = 0x41727101980

type Bucket struct {
	Addr         net.Addr
	transactions map[uint32]*Transaction
}

func (b *Bucket) NewTransaction(swarms []model.Torrent) (t *Transaction) {
	id := rand.Uint32()
	// get good id
	_, ok := b.transactions[id]
	for ok {
		id = rand.Uint32()
		_, ok = b.transactions[id]
	}
	t = &Transaction{
		TransactionID: id,
		swarms:        swarms,
		state:         stateSendID,
	}
	b.transactions[id] = t
	return

}

func (b *Bucket) VisitTransaction(tid uint32, v func(*Transaction)) {
	t, ok := b.transactions[tid]
	if ok {
		go v(t)
	} else {
		v(nil)
	}
}

func NewBucket(a net.Addr) *Bucket {
	return &Bucket{
		transactions: make(map[uint32]*Transaction),
		Addr:         a,
	}
}

Revert "fix infinite loop shit"


package util

import (
	"encoding/json"
	"io"
)

// DecodeJSON decodes json
func DecodeJSON(src io.Reader, dst interface{}) error {
	decoder := json.NewDecoder(src)
	err := decoder.Decode(dst)
	return err
}

// EncodeJSON encodes json
func EncodeJSON(dst io.Writer, src interface{}) error {
	encoder := json.NewEncoder(dst)
	err := encoder.Encode(src)
	return err
}

func WriteErrorJSON(dst io.Writer, errorMsg string) error {
	response := make(map[string]interface{})
	response["ok"] = false
	response["failureReason"] = "Request does not have the header \"Content-Type: application-json\""
	return EncodeJSON(dst, response)
}

package util

import (
	"encoding/json"
	"io"
)

// DecodeJSON decodes json
func DecodeJSON(src io.Reader, dst interface{}) error {
	decoder := json.NewDecoder(src)
	err := decoder.Decode(dst)
	return err
}

// EncodeJSON encodes json
func EncodeJSON(dst io.Writer, src interface{}) error {
	encoder := json.NewEncoder(dst)
	err := encoder.Encode(src)
	return err
}

func WriteErrorJSON(dst io.Writer, errorMsg string) error {
	response := make(map[string]interface{})
	response["ok"] = false
	response["failureReason"] = errorMsg
	return EncodeJSON(dst, response)
}

Fix message written to by util function


package horizon

import (
	. "github.com/smartystreets/goconvey/convey"
	"github.com/stellar/go-horizon/test"
	"github.com/zenazn/goji/web"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestRootAction(t *testing.T) {

	Convey("GET /", t, func() {
		test.LoadScenario("base")
		app := NewTestApp()

		r, _ := http.NewRequest("GET", "/", nil)
		w := httptest.NewRecorder()
		c := web.C{
			Env: map[interface{}]interface{}{},
		}

		app.web.router.ServeHTTPC(c, w, r)

		So(w.Code, ShouldEqual, 200)
	})
}

package horizon

import (
	. "github.com/smartystreets/goconvey/convey"
	"github.com/stellar/go-horizon/test"
	"testing"
)

func TestRootAction(t *testing.T) {

	Convey("GET /", t, func() {
		test.LoadScenario("base")
		app := NewTestApp()
		rh := NewRequestHelper(app)

		w := rh.Get("/", test.RequestHelperNoop)

		So(w.Code, ShouldEqual, 200)
	})
}

Use test.RequestHelper in root action test


package translations_test

import (
	"github.com/XenoPhex/jibber_jabber"

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

var _ = Describe("i18n support and language detection", func() {
	BeforeEach(func() {
		userLocale, err := jibber_jabber.DetectIETF()
		Expect(err).NotTo(HaveOccurred())
		Expect(userLocale).To(Equal("fr-FR"), "This test can only be run when the system's language is set to french")
	})

	It("does nothing yet", func() {

	})
})

package translations_test

import (
	"github.com/XenoPhex/jibber_jabber"

	. "github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
)

var _ = Describe("i18n support and language detection", func() {
	BeforeEach(func() {
		userLocale, err := jibber_jabber.DetectIETF()
		Expect(err).NotTo(HaveOccurred())
		Expect(userLocale).To(Equal("fr-FR"), "This test can only be run when the system's language is set to french")
	})

	It("returns the french translation for cf quota", func() {
		Eventually(Cf("help", "quota")).Should(Say("Montrez l'information de quota"))
	})
})

Add a simple assertion for the quota command in french


package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestIsVersion2(t *testing.T) {
	workingDir, _ := os.Getwd()

	v1FilePath := filepath.Join(workingDir, "fixtures", "docker-compose-v1.yml")
	v1ComposeFile, _ := NewComposeFile(v1FilePath)

	if v1ComposeFile.IsVersion2() {
		t.Fatalf(v1FilePath + " is actually not based on Compose File Version 2.")
	}

	v2FilePath := filepath.Join(workingDir, "fixtures", "docker-compose-v2.yml")
	v2ComposeFile, _ := NewComposeFile(v2FilePath)

	if !v2ComposeFile.IsVersion2() {
		t.Fatalf(v2FilePath + " is actually based on Compose File Version 2.")
	}
}

package main

import (
	"os"
	"path/filepath"
	"testing"
)

var (
	V1FilePath, V2FilePath       string
	V1ComposeFile, V2ComposeFile *ComposeFile
)

func setup() {
	workingDir, _ := os.Getwd()

	V1FilePath = filepath.Join(workingDir, "fixtures", "docker-compose-v1.yml")
	V2FilePath = filepath.Join(workingDir, "fixtures", "docker-compose-v2.yml")
	V1ComposeFile, _ = NewComposeFile(V1FilePath)
	V2ComposeFile, _ = NewComposeFile(V2FilePath)
}

func TestIsVersion2(t *testing.T) {
	setup()

	if V1ComposeFile.IsVersion2() {
		t.Fatalf(V1FilePath + " is actually not based on Compose File Version 2.")
	}

	if !V2ComposeFile.IsVersion2() {
		t.Fatalf(V2FilePath + " is actually based on Compose File Version 2.")
	}
}

Define setup function in test


package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/ciarand/notify"
)

var (
	text     *string
	title    *string
	subtitle *string
	sound    *string
)

func init() {
	text = flag.String("text", "", "The required text for the notification")
	title = flag.String("title", "", "The required title of the notification")
	subtitle = flag.String("subtitle", "", "An optional subtitle for the notification")
	sound = flag.String("sound", "", "An optional sound name to play")
}

func main() {
	flag.Parse()
	if len(os.Args) == 1 {
		flag.Usage()
		return
	}

	if *title == "" {
		dief("Title cannot be blank")
	}

	if *text == "" {
		dief("Text cannot be blank")
	}

	n := notify.NewSubtitledNotificationWithSound(*title, *subtitle, *text, *sound)

	if err := notify.Show(n); err != nil {
		dief("Error showing notification: %s", err)
	}
}

func dief(s string, args ...interface{}) {
	fmt.Printf(s+"\n", args...)

	os.Exit(1)
}

package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/ciarand/notify"
)

var (
	text     *string
	title    *string
	subtitle *string
	sound    *string
)

func init() {
	text = flag.String("text", "", "The required text for the notification")
	title = flag.String("title", "", "The required title of the notification")
	subtitle = flag.String("subtitle", "", "An optional subtitle for the notification")
	sound = flag.String("sound", "", "An optional sound name to play")
}

func main() {
	flag.Parse()
	if len(os.Args) == 1 {
		flag.Usage()
		return
	}

	if *title == "" {
		dief("Title cannot be blank")
	}

	if *text == "" {
		dief("Text cannot be blank")
	}

	n := notify.NewSubtitledNotificationWithSound(*title, *subtitle, *text, *sound)

	if err := n.Display(); err != nil {
		dief("Error showing notification: %s", err)
	}
}

func dief(s string, args ...interface{}) {
	fmt.Printf(s+"\n", args...)

	os.Exit(1)
}

Update cmd/notify with new API (Display not Show)


package command

import (
	"strings"

	"github.com/mitchellh/cli"
)

type OperatorAutopilotCommand struct {
	Meta
}

func (c *OperatorAutopilotCommand) Run(args []string) int {
	return cli.RunResultHelp
}

func (c *OperatorAutopilotCommand) Synopsis() string {
	return "Provides tools for modifying Autopilot configuration"
}

func (c *OperatorAutopilotCommand) Help() string {
	helpText := `
Usage: nomad operator autopilot <subcommand> [options]

  This command groups subcommands for interacting with Nomad's Autopilot
  subsystem. Autopilot provides automatic, operator-friendly management of Nomad
  servers. The command can be used to view or modify the current Autopilot
  configuration.

  Get the current Autopilot configuration:

      $ nomad operator autopilot get-config

  Set a new Autopilot configuration, enabling automatic dead server cleanup:

      $ nomad operator autopilot set-config -cleanup-dead-servers=true

  Please see the individual subcommand help for detailed usage information.
  `
	return strings.TrimSpace(helpText)
}

package command

import (
	"strings"

	"github.com/mitchellh/cli"
)

type OperatorAutopilotCommand struct {
	Meta
}

func (c *OperatorAutopilotCommand) Run(args []string) int {
	return cli.RunResultHelp
}

func (c *OperatorAutopilotCommand) Synopsis() string {
	return "Provides tools for modifying Autopilot configuration"
}

func (c *OperatorAutopilotCommand) Help() string {
	helpText := `
Usage: nomad operator autopilot <subcommand> [options]

  This command groups subcommands for interacting with Nomad's Autopilot
  subsystem. Autopilot provides automatic, operator-friendly management of Nomad
  servers. The command can be used to view or modify the current Autopilot
  configuration. For a full guide see: https://www.nomadproject.io/guides/autopilot.html

  Get the current Autopilot configuration:

      $ nomad operator autopilot get-config

  Set a new Autopilot configuration, enabling automatic dead server cleanup:

      $ nomad operator autopilot set-config -cleanup-dead-servers=true

  Please see the individual subcommand help for detailed usage information.
  `
	return strings.TrimSpace(helpText)
}

Add link to autopilot guide in operator autopilot CLI help text


package quotas_test

import(
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
	. "github.com/pivotal-cf-experimental/cf-test-helpers/cf"
)

var _ = Describe("CF Quota commands", func() {
	It("can Create, Read, Update, and Delete quotas", func() {
		AsUser(context.AdminUserContext(), func() {
			Eventually(Cf("create-quota",
				"quota-name-goes-here",
				"-m", "512M",
			), 5.0).Should(Exit(0))

			quotaOutput := Cf("quotas")
			Eventually(quotaOutput, 5).Should(Say("quota-name-goes-here"))

			Eventually(Cf("update-quota",
				"quota-name-goes-here",
				"-m", "513M",
			), 5).Should(Exit(0))

			Eventually(Cf("quotas")).Should(Say("513M"))

			Eventually(Cf("delete-quota",
				"quota-name-goes-here",
				"-f,",
			)).Should(Exit(0))

			Eventually(Cf("quotas")).ShouldNot(Say("quota-name-goes-here"))
		})
	})
})

package quotas_test

import(
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
	. "github.com/pivotal-cf-experimental/cf-test-helpers/cf"
)

var _ = Describe("CF Quota commands", func() {
	It("can Create, Read, Update, and Delete quotas", func() {
		AsUser(context.AdminUserContext(), func() {
			Eventually(Cf("create-quota",
				"quota-name-goes-here",
				"-m", "512M",
			), 5.0).Should(Exit(0))

			Eventually(Cf("quota", "quota-name-goes-here"), 5.0).Should(Say("512M"))

			quotaOutput := Cf("quotas")
			Eventually(quotaOutput, 5).Should(Say("quota-name-goes-here"))

			Eventually(Cf("update-quota",
				"quota-name-goes-here",
				"-m", "513M",
			), 5).Should(Exit(0))

			Eventually(Cf("quotas")).Should(Say("513M"))

			Eventually(Cf("delete-quota",
				"quota-name-goes-here",
				"-f,",
			)).Should(Exit(0))

			Eventually(Cf("quotas")).ShouldNot(Say("quota-name-goes-here"))
		})
	})
})

Add a test for the 'cf quota $QUOTA_NAME' command


package models

type Word struct {
	Romaji     string
	Common     bool
	Dialects   []string
	Fields     []string
	Glosses    []Gloss
	English    []string
	EnglishHL  []string // highlighted english
	Furigana   string
	FuriganaHL string // highlighted furigana
	Japanese   string
	JapaneseHL string // highlighted japanese
	Tags       []string
	Pos        []string
}

package models

import (
	"github.com/gojp/nihongo/app/helpers"
	"regexp"
	"strings"
)

type Word struct {
	Romaji     string
	Common     bool
	Dialects   []string
	Fields     []string
	Glosses    []Gloss
	English    []string
	EnglishHL  []string // highlighted english
	Furigana   string
	FuriganaHL string // highlighted furigana
	Japanese   string
	JapaneseHL string // highlighted japanese
	Tags       []string
	Pos        []string
}

// Wrap the query in <strong> tags so that we can highlight it in the results
func (w *Word) HighlightQuery(query string) {
	// make regular expression that matches the original query
	re := regexp.MustCompile(`\b` + regexp.QuoteMeta(query) + `\b`)
	// convert original query to kana
	h, k := helpers.ConvertQueryToKana(query)
	// wrap the query in strong tags
	queryHighlighted := helpers.MakeStrong(query)
	hiraganaHighlighted := helpers.MakeStrong(h)
	katakanaHighlighted := helpers.MakeStrong(k)

	// if the original input is Japanese, then the original input converted
	// to hiragana and katakana will be equal, so just choose one
	// to highlight so that we only end up with one pair of strong tags
	if hiraganaHighlighted == katakanaHighlighted {
		w.JapaneseHL = strings.Replace(w.Japanese, h, hiraganaHighlighted, -1)
	} else {
		// The original input is romaji, so we convert it to hiragana and katakana
		// and highlight both.
		w.JapaneseHL = strings.Replace(w.Japanese, h, hiraganaHighlighted, -1)
		w.JapaneseHL = strings.Replace(w.JapaneseHL, k, katakanaHighlighted, -1)
	}

	// highlight the furigana too, same as above
	w.FuriganaHL = strings.Replace(w.Furigana, h, hiraganaHighlighted, -1)
	w.FuriganaHL = strings.Replace(w.FuriganaHL, k, katakanaHighlighted, -1)
	// highlight the query inside the list of English definitions
	w.EnglishHL = []string{}
	for _, e := range w.English {
		e = re.ReplaceAllString(e, queryHighlighted)
		w.EnglishHL = append(w.EnglishHL, e)
	}
}

Add HighlightQuery to Word model


package bletchley

import (
	"crypto/aes"
	"crypto/cipher"
)

const (
	symmetricNonceLength = 12
	symmetricKeyLength   = 32
)

// We are allowed to use an empty nonce because we never re-use keys
// see Section 8.2.1 of NIST Special Publication 800-38D
// http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
var zeroNonce []byte = make([]byte, symmetricNonceLength)

func symmetricDecrypt(aesKey, ciphertext []byte) ([]byte, error) {
	blockCipher, err := aes.NewCipher(aesKey)
	if err != nil {
		return nil, err
	}

	streamCipher, err := cipher.NewGCM(blockCipher)
	if err != nil {
		return nil, err
	}

	return streamCipher.Open(nil, zeroNonce, ciphertext, nil)
}

func symmetricEncrypt(aesKey, plaintext []byte) ([]byte, error) {
	blockCipher, err := aes.NewCipher(aesKey)
	if err != nil {
		return []byte{}, err
	}

	streamCipher, err := cipher.NewGCM(blockCipher)
	if err != nil {
		return []byte{}, err
	}

	ciphertext := streamCipher.Seal(nil, zeroNonce, plaintext, nil)
	return ciphertext, nil
}

package bletchley

import (
	"crypto/aes"
	"crypto/cipher"
)

const (
	symmetricNonceLength = 12
	symmetricKeyLength   = 32
)

// We are allowed to use an empty nonce because we never re-use keys
// see Section 8.2.1 of NIST Special Publication 800-38D
// http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
var zeroNonce []byte = make([]byte, symmetricNonceLength)

func makeAESGCM(aesKey []byte) (cipher.AEAD, error) {
	blockCipher, err := aes.NewCipher(aesKey)
	if err != nil {
		return nil, err
	}

	return cipher.NewGCM(blockCipher)
}

func symmetricDecrypt(aesKey, ciphertext []byte) ([]byte, error) {
	gcm, err := makeAESGCM(aesKey)
	if err != nil {
		return nil, err
	}

	return gcm.Open(nil, zeroNonce, ciphertext, nil)
}

func symmetricEncrypt(aesKey, plaintext []byte) ([]byte, error) {
	gcm, err := makeAESGCM(aesKey)
	if err != nil {
		return nil, err
	}

	return gcm.Seal(nil, zeroNonce, plaintext, nil), nil
}

Consolidate creation of AES-GCM cipher mode into a single function


package io_throttler

import (
	"fmt"
	"io"

	"io/ioutil"

	"github.com/efarrer/iothrottler"
)

//CopyThrottled does a normal io.Copy but with throttling
func CopyThrottled(bandwidth iothrottler.Bandwidth, dest io.Writer, src io.Reader) (written int64, returnErr error) {
	pool := iothrottler.NewIOThrottlerPool(bandwidth)
	defer pool.ReleasePool()

	var readCloser io.ReadCloser
	if rc, ok := src.(io.ReadCloser); ok {
		readCloser = rc
	} else {
		readCloser = ioutil.NopCloser(readCloser)
	}

	throttledFile, err := pool.AddReader(readCloser)
	if err != nil {
		return 0, fmt.Errorf("Cannot add reader to copy throttler, error: %s", err.Error())
	}

	return io.Copy(dest, throttledFile)
}

package io_throttler

import (
	"fmt"
	"io"

	"io/ioutil"

	"github.com/efarrer/iothrottler"
)

//CopyThrottled does a normal io.Copy but with throttling
func CopyThrottled(bandwidth iothrottler.Bandwidth, dest io.Writer, src io.Reader) (written int64, returnErr error) {
	pool := iothrottler.NewIOThrottlerPool(bandwidth)
	defer pool.ReleasePool()

	var readCloser io.ReadCloser
	if rc, ok := src.(io.ReadCloser); ok {
		readCloser = rc
	} else {
		readCloser = ioutil.NopCloser(src)
	}

	throttledFile, err := pool.AddReader(readCloser)
	if err != nil {
		return 0, fmt.Errorf("Cannot add reader to copy throttler, error: %s", err.Error())
	}

	return io.Copy(dest, throttledFile)
}

Fix bug in previous commit