package verstr

import (
	"testing"
)

func TestLess(t *testing.T) {
	var tests = []struct {
		left, right string
		want        bool
	}{
		{"file.1.ext", "file.10.ext", true},
		{"file.10.ext", "file.1.ext", false},
		{"sparse", "sparse.0", true},
		{"sparse.0", "sparse", false},
	}
	for _, test := range tests {
		if got := Less(test.left, test.right); got != test.want {
			t.Errorf("Less(%q, %q) = %v", test.left, test.right, got)
		}
	}
}

package verstr

import (
	"testing"
)

func TestLess(t *testing.T) {
	var tests = []struct {
		left, right string
		want        bool
	}{
		{"file.0.ext", "file.1.ext", true},
		{"file.1.ext", "file.0.ext", false},
		{"file.1.ext", "file.10.ext", true},
		{"file.10.ext", "file.1.ext", false},
		{"sparse", "sparse.0", true},
		{"sparse.0", "sparse", false},
	}
	for _, test := range tests {
		if got := Less(test.left, test.right); got != test.want {
			t.Errorf("Less(%q, %q) = %v", test.left, test.right, got)
		}
	}
}

Add another pair to test for lib/verstr.Less().


package controllers

import (
  "net"
  "github.com/ohrite/gopher"
  . "github.com/ohrite/gopherchan/models"
)

type PostCreateController struct {
  Host string
  Port string
}

func NewPostCreateController(host string, port string) (*PostCreateController) {
  return &PostCreateController{
    Host: host,
    Port: port,
  }
}

func (controller *PostCreateController) Handle(conn net.Conn, request *gopher.Request, params map[string]string) {
  post := Post{Body:params["body"]}
  post.Save()

  response := BuildResponse(
    gopher.NewPromptResponseLine("New Post", "/new", controller.Host, controller.Port),
    gopher.NewCommentResponseLine(""),
  )
  AddPostResponseLines(response, controller.Host, controller.Port)
  response.WriteResponse(conn)
}

package controllers

import (
  "net"
  "github.com/ohrite/gopher"
  . "github.com/ohrite/gopherchan/models"
)

type PostCreateController struct {
  Host string
  Port string
}

func NewPostCreateController(host string, port string) (*PostCreateController) {
  return &PostCreateController{
    Host: host,
    Port: port,
  }
}

func (controller *PostCreateController) Handle(conn net.Conn, request *gopher.Request, params map[string]string) {
  post := Post{Body:request.Body}
  post.Save()

  response := BuildResponse(
    gopher.NewPromptResponseLine("New Post", "/new", controller.Host, controller.Port),
    gopher.NewCommentResponseLine(""),
  )
  AddPostResponseLines(response, controller.Host, controller.Port)
  response.WriteResponse(conn)
}

Use request body instead of body url part


// +build freebsd darwin

package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem"

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

// GetOperatingSystem gets the name of the current operating system.
func GetOperatingSystem() (string, error) {
	cmd := exec.Command("uname", "-s")
	osName, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return string(osName), nil
}

// GetOperatingSystemVersion gets the version of the current operating system, as a string.
func GetOperatingSystemVersion() (string, error) {
	// there's no standard unix way of getting this, sadly...
	return "", fmt.Error("Unsupported on generic unix")
}

// IsContainerized returns true if we are running inside a container.
// No-op on FreeBSD and Darwin, always returns false.
func IsContainerized() (bool, error) {
	// TODO: Implement jail detection for freeBSD
	return false, errors.New("Cannot detect if we are in container")
}

// +build freebsd darwin

package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem"

import (
	"errors"
	"os/exec"
)

// GetOperatingSystem gets the name of the current operating system.
func GetOperatingSystem() (string, error) {
	cmd := exec.Command("uname", "-s")
	osName, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return string(osName), nil
}

// GetOperatingSystemVersion gets the version of the current operating system, as a string.
func GetOperatingSystemVersion() (string, error) {
	// there's no standard unix way of getting this, sadly...
	return "", errors.New("Unsupported on generic unix")
}

// IsContainerized returns true if we are running inside a container.
// No-op on FreeBSD and Darwin, always returns false.
func IsContainerized() (bool, error) {
	// TODO: Implement jail detection for freeBSD
	return false, errors.New("Cannot detect if we are in container")
}

Fix compiling pkg/parsers/operatingsystem on unix


package executor

import (
	"os/exec"
	"time"

	"golang.org/x/sys/windows"
)

func (e *UniversalExecutor) LaunchSyslogServer(ctx *ExecutorContext) (*SyslogServerState, error) {
	return nil, nil
}

func (e *UniversalExecutor) wait() {
	defer close(e.processExited)
	err := e.cmd.Wait()
	ic := &cstructs.IsolationConfig{Cgroup: e.groups, CgroupPaths: e.cgPaths}
	if err == nil {
		e.exitState = &ProcessState{Pid: 0, ExitCode: 0, IsolationConfig: ic, Time: time.Now()}
		return
	}
	exitCode := 1
	var signal int
	if exitErr, ok := err.(*exec.ExitError); ok {
		if status, ok := exitErr.Sys().(windows.WaitStatus); ok {
			exitCode = status.ExitStatus()
			if status.Signaled() {
				signal = int(status.Signal())
				exitCode = 128 + signal
			}
		}
	} else {
		e.logger.Printf("[DEBUG] executor: unexpected Wait() error type: %v", err)
	}

	e.exitState = &ProcessState{Pid: 0, ExitCode: exitCode, Signal: signal, IsolationConfig: ic, Time: time.Now()}
}

package executor

import (
	"os/exec"
	"time"

	cstructs "github.com/hashicorp/nomad/client/driver/structs"
	"golang.org/x/sys/windows"
)

func (e *UniversalExecutor) LaunchSyslogServer(ctx *ExecutorContext) (*SyslogServerState, error) {
	return nil, nil
}

func (e *UniversalExecutor) wait() {
	defer close(e.processExited)
	err := e.cmd.Wait()
	ic := &cstructs.IsolationConfig{Cgroup: e.groups, CgroupPaths: e.cgPaths}
	if err == nil {
		e.exitState = &ProcessState{Pid: 0, ExitCode: 0, IsolationConfig: ic, Time: time.Now()}
		return
	}
	exitCode := 1
	var signal int
	if exitErr, ok := err.(*exec.ExitError); ok {
		if status, ok := exitErr.Sys().(windows.WaitStatus); ok {
			exitCode = status.ExitStatus()
			if status.Signaled() {
				signal = int(status.Signal())
				exitCode = 128 + signal
			}
		}
	} else {
		e.logger.Printf("[DEBUG] executor: unexpected Wait() error type: %v", err)
	}

	e.exitState = &ProcessState{Pid: 0, ExitCode: exitCode, Signal: signal, IsolationConfig: ic, Time: time.Now()}
}

Fix executor builds on Windows


package clique

import "fmt"

type BitVector uint64

func (b *BitVector) Set(i int) {
	checkBitIndex(i)
	*b |= (1 << uint(i))
}

func (b BitVector) Has(i int) bool {
	checkBitIndex(i)
	return b&(1<<uint(i)) != 0
}

func (b BitVector) Intersect(c BitVector) BitVector {
	return b & c
}

func (b BitVector) Slice() []int {
	s := []int{}
	for i := 0; i < 64; i++ {
		if b.Has(i) {
			s = append(s, i)
		}
	}
	return s
}

func checkBitIndex(i int) {
	if i < 0 || i >= 64 {
		panic(fmt.Sprintf("Invalid bit index: %d, must be between 0 and 63", i))
	}
}

package clique

type BitVector uint64

func (b *BitVector) Set(i int) {
	*b |= (1 << uint(i))
}

func (b BitVector) Has(i int) bool {
	return b&(1<<uint(i)) != 0
}

func (b BitVector) Intersect(c BitVector) BitVector {
	return b & c
}

func (b BitVector) Slice() []int {
	s := []int{}
	for i := 0; i < 64; i++ {
		if b.Has(i) {
			s = append(s, i)
		}
	}
	return s
}

Remove bit vector index check


package controllers

import (
	"github.com/astaxie/beego"
)

type MainController struct {
	beego.Controller
}

func (this *PingController) Prepare() {
  this.Ctx.Output.Context.ResponseWriter.Header().Set("X-Docker-Registry-Version", beego.AppConfig.String("Version"))
  this.Ctx.Output.Context.ResponseWriter.Header().Set("X-Docker-Registry-Standalone", beego.AppConfig.String("Standalone"))
}

func (this *MainController) Get() {
	this.Ctx.Output.Body([]byte("Docker Registry"))
}

package controllers

import (
	"github.com/astaxie/beego"
)

type MainController struct {
	beego.Controller
}

func (this *MainController) Prepare() {
	this.Ctx.Output.Context.ResponseWriter.Header().Set("X-Docker-Registry-Version", beego.AppConfig.String("Version"))
	this.Ctx.Output.Context.ResponseWriter.Header().Set("X-Docker-Registry-Standalone", beego.AppConfig.String("Standalone"))
}

func (this *MainController) Get() {
	this.Ctx.Output.Body([]byte("Docker Registry"))
}

Fix the error controller name.


// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package charmstore

import (
	"io"

	"gopkg.in/juju/charm.v6-unstable"
)

// Client exposes the functionality of a charm store client as needed
// for charm store operations for Juju resources.
type Client interface {
	io.Closer

	// GetResource returns a reader for the resource's data. That data
	// is streamed from the charm store.
	GetResource(cURL *charm.URL, resourceName string, revision int) (io.ReadCloser, error)
}

// Copyright 2016 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package charmstore

import (
	"io"

	"gopkg.in/juju/charm.v6-unstable"
	charmresource "gopkg.in/juju/charm.v6-unstable/resource"
)

// Client exposes the functionality of a charm store client as needed
// for charm store operations for Juju resources.
type Client interface {
	BaseClient
	io.Closer
}

// BaseClient exposes the functionality of charmrepo/csclient.Client,
// as used for charm store operations for Juju resources.
type BaseClient interface {
	// ListResources composes, for each of the identified charms, the
	// list of details for each of the charm's resources. Those details
	// are those associated with the specific charm revision. They
	// include the resource's metadata and revision.
	ListResources(charmURLs []charm.URL) ([][]charmresource.Resource, error)

	// GetResource returns a reader for the resource's data. That data
	// is streamed from the charm store. The charm's revision, if any,
	// is ignored. If the identified resource is not in the charm store
	// then errors.NotFound is returned.
	GetResource(cURL *charm.URL, resourceName string, revision int) (io.ReadCloser, error)
}

Split out a BaseClient interface and add a ListResources() method.


package leetcode

func searchMatrix(matrix [][]int, target int) bool {
	for _, nums := range matrix {
		left, right := 0, len(nums)-1
		for left <= right {
			mid := (left + right) / 2
			if nums[mid] == target {
				return true
			} else if nums[mid] < target {
				left = mid + 1
			} else {
				right = mid - 1
			}
		}
	}
	return false
}

package leetcode

func searchMatrix(matrix [][]int, target int) bool {
	if matrix == nil || len(matrix) == 0 || len(matrix[0]) == 0 {
		return false
	}

	col, row := len(matrix[0])-1, 0
	for col >= 0 && row < len(matrix) {
		if matrix[row][col] == target {
			return true
		} else if matrix[row][col] < target {
			row++
		} else {
			col--
		}
	}
	return false
}

Fix 240. Search a 2D Matrix II to implement O(n+m) solution


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

package gitea

// MarkdownOption markdown options
type MarkdownOption struct {
	Text    string
	Mode    string
	Context string
	Wiki    bool
}

type ServerVersion struct {
	Version string
}

func (c *Client) ServerVersion() (string, error) {
	v := ServerVersion{}
	return v.Version, c.getParsedResponse("GET", "/api/v1/version", nil, nil, &v)
}

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

package gitea

// MarkdownOption markdown options
type MarkdownOption struct {
	Text    string
	Mode    string
	Context string
	Wiki    bool
}

// ServerVersion wraps the version of the server
type ServerVersion struct {
	Version string
}

// ServerVersion returns the version of the server
func (c *Client) ServerVersion() (string, error) {
	v := ServerVersion{}
	return v.Version, c.getParsedResponse("GET", "/api/v1/version", nil, nil, &v)
}

Add comment for exported struct and method


package manager

import (
	"strings"

	"github.com/pkg/errors"
)

func trimExeSuffix(s string) (string, error) {
	exe := ".exe"
	if !strings.HasSuffix(s, exe) {
		return "", errors.Errorf("lacks required %q suffix", exe)
	}
	return strings.TrimSuffix(s, exe), nil
}

func addExeSuffix(s string) string {
	return s + ".exe"
}

package manager

import (
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
)

// This is made slightly more complex due to needing to be case insensitive.
func trimExeSuffix(s string) (string, error) {
	ext := filepath.Ext(s)
	if ext == "" {
		return "", errors.Errorf("path %q lacks required file extension", s)
	}

	exe := ".exe"
	if !strings.EqualFold(ext, exe) {
		return "", errors.Errorf("path %q lacks required %q suffix", s, exe)
	}
	return strings.TrimSuffix(s, ext), nil
}

func addExeSuffix(s string) string {
	return s + ".exe"
}

Check for `.exe` case insensitively


package main

import (
	"errors"
	"fmt"
	"os"
)

type lockerEXNB struct {
}

func newLockerEXNB() *lockerEXNB {
	return new(lockerEXNB)
}

func (l *lockerEXNB) lock(file *os.File) error {
	msg := "setlock: fatal: windows doesn't support no delay mode"
	fmt.Fprintf(os.Stderr, msg)
	return errors.New(msg)
}

package main

import (
	"errors"
	"fmt"
	"os"
)

type lockerEXNB struct {
}

func newLockerEXNB() *lockerEXNB {
	return new(lockerEXNB)
}

func (l *lockerEXNB) lock(file *os.File) error {
	msg := "setlock: fatal: windows doesn't support no delay mode"
	fmt.Fprintf(os.Stderr, "%s\n", msg)
	return errors.New(msg)
}

Append a new line to error message


package reply

import (
	"regexp"

	"github.com/tucnak/telebot"
	"github.com/asdine/storm"

	"github.com/focusshifter/muxgoob/registry"
)

type ReplyPlugin struct {
}

var db *storm.DB

func init() {
	registry.RegisterPlugin(&ReplyPlugin{})
}

func (p *ReplyPlugin) Start(sharedDb *storm.DB) {
	db = sharedDb
}

func (p *ReplyPlugin) Run(message telebot.Message) {
	highlightedExp := regexp.MustCompile(`^.*(gooby|губи|губ(я)+н).*$`)

	if highlightedExp.MatchString(message.Text) {
		bot := registry.Bot

		bot.SendMessage(message.Chat, "herp derp", nil)
	}
}

func (p *ReplyPlugin) Stop() {
}

package reply

import (
	"regexp"
	"math/rand"
	"time"

	"github.com/tucnak/telebot"
	"github.com/asdine/storm"

	"github.com/focusshifter/muxgoob/registry"
)

type ReplyPlugin struct {
}

var db *storm.DB
var rng *rand.Rand

func init() {
	registry.RegisterPlugin(&ReplyPlugin{})
}

func (p *ReplyPlugin) Start(sharedDb *storm.DB) {
	db = sharedDb
    rng = rand.New(rand.NewSource(time.Now().UnixNano()))
}

func (p *ReplyPlugin) Run(message telebot.Message) {
	bot := registry.Bot

	techExp := regexp.MustCompile(`(?i)^\!ттх$`)
	questionExp := regexp.MustCompile(`^.*(gooby|губи|губ(я)+н).*\?$`)
	highlightedExp := regexp.MustCompile(`^.*(gooby|губи|губ(я)+н).*$`)

	switch {
		case techExp.MatchString(message.Text):
			bot.SendMessage(message.Chat,
						"ТТХ: https://drive.google.com/open?id=139ZWbP-CAV_u5nzQ6skbHRjb7eofzfdh8eA4_q7McFM",
						&telebot.SendOptions{DisableWebPagePreview: true, DisableNotification: true})

		case questionExp.MatchString(message.Text):
			var replyText string

			rngInt := rng.Int()

			switch {
				case rngInt % 100 == 0:
					replyText = "Заткнись, пидор"
				case rngInt % 2 == 0:
					replyText = "Да"
				default:
					replyText = "Нет"
			}

			bot.SendMessage(message.Chat, replyText, &telebot.SendOptions{ReplyTo: message})

		case highlightedExp.MatchString(message.Text):
			bot.SendMessage(message.Chat, "herp derp", nil)
	}
}

func (p *ReplyPlugin) Stop() {
}

Allow to react to the questions and printing 'chat specs'


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

package crontask

import (
	"log"
	"time"

	"github.com/gorhill/cronexpr"
)

type CronTask struct {
	task     func()
	cronTime string
}

func New(task func(), cronTime string) *CronTask {
	return &CronTask{task, cronTime}
}

func (t *CronTask) Run() {
	go func() {
		for {
			nextTime := cronexpr.MustParse(t.cronTime).Next(time.Now())
			log.Println("Next execution", nextTime, t.task)
			time.Sleep(nextTime.Sub(time.Now()))
			log.Println("Execution start")
			t.task()
			log.Println("Execution end")
		}
	}()
}

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

package crontask

import (
	"log"
	"time"

	"github.com/gorhill/cronexpr"
)

type CronTask struct {
	task     func()
	cronTime string
}

func New(task func(), cronTime string) *CronTask {
	return &CronTask{task, cronTime}
}

func (t *CronTask) Run() {
	go func() {
		for {
			nextTime := cronexpr.MustParse(t.cronTime).Next(time.Now())
			log.Println("Next execution", nextTime)
			time.Sleep(nextTime.Sub(time.Now()))
			log.Println("Execution start")
			t.task()
			log.Println("Execution end")
		}
	}()
}

Remove senseless trace log of a function_memory_address


package metrics

import (
	"testing"

	"github.com/icecrime/octostats/fixtures"
	"github.com/icecrime/octostats/github"
)

func TestCollectIssues(t *testing.T) {
	fixtures.Setup()
	fixtures.SetupMux(t, "issues")
	defer fixtures.TearDown()

	r := github.NewGitHubRepositoryWithClient("docker", "docker", fixtures.Client)
	m := New(r)

	feed := make(chan Metric, 100)

	collectOpenedIssues(r, feed)
	close(feed)

	for e := range feed {
		m.Items = append(m.Items, e)
	}

	// 1 global counter + 4 issues + 4 labels
	if len(m.Items) != 9 {
		t.Fatalf("Expected 8 metrics but got %d\n", len(m.Items))
	}
}

package metrics

import (
	"testing"

	"github.com/icecrime/octostats/fixtures"
	"github.com/icecrime/octostats/github"
)

func TestCollectIssues(t *testing.T) {
	fixtures.Setup()
	fixtures.SetupMux(t, "issues")
	defer fixtures.TearDown()

	r := github.NewGitHubRepositoryWithClient("docker", "docker", fixtures.Client)
	items := collectOpenedIssues(r)

	// 1 global counter + 4 issues + 4 labels
	if len(items) != 9 {
		t.Fatalf("Expected 8 metrics but got %d\n", len(items))
	}
}

Remove buffered channel from the metrics test.


package config

import (
	"encoding/json"
	"io"

	"github.com/gsamokovarov/jump/scoring"
)

// ReadEntries returns the current entries for the config.
//
// If the scores file is empty, the returned entries are empty.
func (c *Config) ReadEntries() (*scoring.Entries, error) {
	var entries *scoring.Entries

	scoresFile, err := c.scoresFile()
	if err != nil {
		return entries, nil
	}

	defer closeLockedFile(scoresFile)

	decoder := json.NewDecoder(scoresFile)
	for {
		if err := decoder.Decode(&entries); err == io.EOF {
			break
		} else if err != nil {
			return entries, err
		}
	}

	return entries, nil
}

// WriteEntries the input scoring entries to a file.
//
// Sorts the entries before writing them to disk.
func (c *Config) WriteEntries(entries *scoring.Entries) error {
	scoresFile, err := c.scoresFile()
	if err != nil {
		return err
	}

	defer closeLockedFile(scoresFile)

	if err := scoresFile.Truncate(0); err != nil {
		return err
	}

	entries.Sort()
	encoder := json.NewEncoder(scoresFile)

	return encoder.Encode(entries)
}

package config

import (
	"encoding/json"
	"io"

	"github.com/gsamokovarov/jump/scoring"
)

// ReadEntries returns the current entries for the config.
//
// If the scores file is empty, the returned entries are empty.
func (c *Config) ReadEntries() (*scoring.Entries, error) {
	var entries scoring.Entries

	scoresFile, err := c.scoresFile()
	if err != nil {
		return &entries, nil
	}

	defer closeLockedFile(scoresFile)

	decoder := json.NewDecoder(scoresFile)
	for {
		if err := decoder.Decode(&entries); err == io.EOF {
			break
		} else if err != nil {
			return &entries, err
		}
	}

	return &entries, nil
}

// WriteEntries the input scoring entries to a file.
//
// Sorts the entries before writing them to disk.
func (c *Config) WriteEntries(entries *scoring.Entries) error {
	scoresFile, err := c.scoresFile()
	if err != nil {
		return err
	}

	defer closeLockedFile(scoresFile)

	if err := scoresFile.Truncate(0); err != nil {
		return err
	}

	entries.Sort()
	encoder := json.NewEncoder(scoresFile)

	return encoder.Encode(entries)
}

Fix a null pointer reference on the very first run of jump


// +build !windows,!darwin,!linux

package credentials

const defaultCredentialsStore = ""

// +build !windows,!darwin,!linux

package credentials

func defaultCredentialsStore() string {
	return ""
}

Fix compilation of defaultCredentialStore() on unsupported platforms


package main

import (
	"testing"
)

func TestRunRandom(t *testing.T) {
	tests := []struct {
		name    string
		args    []string
		wantErr bool
	}{
		{
			name:    "success",
			args:    nil,
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if err := runRandom(nil, tt.args); (err != nil) != tt.wantErr {
				t.Errorf("runRandom() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

package main

import "testing"

func TestRunRandom(t *testing.T) {
	tests := []cmdTestCase{{
		name:      "random",
		args:      []string{"random"},
		wantError: false,
	}}
	runTestCmd(t, tests)
}

Refactor test for random cmd


package codabar

import (
	"image/color"
	"testing"
)

func Test_Encode(t *testing.T) {
	_, err := Encode("FOOBAR")
	if err == nil {
		t.Error("\"FOOBAR\" should not be encodable")
	}

	testEncode := func(txt, testResult string) {
		code, err := Encode(txt)
		if err != nil || code == nil {
			t.Fail()
		} else {
			if code.Bounds().Max.X != len(testResult) {
				t.Errorf("%v: length missmatch", txt)
			} else {
				for i, r := range testResult {
					if (code.At(i, 0) == color.Black) != (r == '1') {
						t.Errorf("%v: code missmatch on position %d", txt, i)
					}
				}
			}
		}
	}

	testEncode("A40156B", "10110010010101101001010101001101010110010110101001010010101101010010011")
}

package codabar

import (
	"image/color"
	"testing"
)

func Test_Encode(t *testing.T) {
	_, err := Encode("FOOBAR")
	if err == nil {
		t.Error("\"FOOBAR\" should not be encodable")
	}

	testEncode := func(txt, testResult string) {
		code, err := Encode(txt)
		if err != nil || code == nil {
			t.Fail()
		} else {
			if code.Bounds().Max.X != len(testResult) {
				t.Errorf("%v: length missmatch", txt)
			} else {
				for i, r := range testResult {
					if (code.At(i, 0) == color.Black) != (r == '1') {
						t.Errorf("%v: code missmatch on position %d", txt, i)
					}
				}
			}
		}
	}

	testEncode("A40156B", "10110010010101101001010101001101010110010110101001010010101101001001011")
}

Update test case for updated 'B' codabar character


// +build windows

package config

import (
	"os"
	"path"
)

func defaultDirectory() string {
	base := path.Base(os.Args[0])
	ext := path.Ext(base)

	drv := os.Getenv("SystemDrive")
	pdDir := "ProgramData"
	name := base[0 : len(base)-len(ext)]

	return path.Join(drv, pdDir, name, name)
}

// +build windows

package config

import (
	"os"
	"path/filepath"
)

func defaultDirectory() string {
	base := filepath.Base(os.Args[0])
	ext := filepath.Ext(base)

	drv := os.Getenv("SystemDrive")
	pdDir := "ProgramData"
	name := base[0 : len(base)-len(ext)]

	return filepath.Join(drv, pdDir, name, name)
}

Use filepath in place of path for windows code.


package codec

import (
	"github.com/luopengift/transport"
    "time"
)

// add a enter symbol at end of line, classic written into file
type DebugInjectHandler struct {
	*transport.Inject
}

func (h *DebugInjectHandler) Init(config transport.Configer) error {
	return nil
}

func (h *DebugInjectHandler) Handle(in, out []byte) (int, error) {
    time.Sleep(1 * time.Second) // make program run slow down
	h.InjectInput(in)
	n := copy(out, in)
	return n, nil
}

func init() {
	transport.RegistHandler("DEBUG_InjectInput", new(DebugInjectHandler))
}

Add Inject feature && go fmt ./...


package version

// Flag contains extra info about the version. It is helpul for tracking
// versions while developing. It should always be empty on the master branch.
// This is inforced in a continuous integration test.
const Flag = "export"

var (
	// Version is The full version string
	Version = "0.5.9"

	// GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse HEAD)"
	GitCommit string
)

func init() {
	Version += "-" + Flag

	if GitCommit != "" {
		Version += "-" + GitCommit[:8]
	}
}

package version

// Flag contains extra info about the version. It is helpul for tracking
// versions while developing. It should always be empty on the master branch.
// This is inforced in a continuous integration test.
const Flag = "develop"

var (
	// Version is The full version string
	Version = "0.5.9"

	// GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse HEAD)"
	GitCommit string
)

func init() {
	Version += "-" + Flag

	if GitCommit != "" {
		Version += "-" + GitCommit[:8]
	}
}

Set branch back to develop after export branch merge


// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris

package main

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

	"github.com/vlifesystems/rulehunter/internal/testhelpers"
)

func TestSubMain_interrupt(t *testing.T) {
	configDir := testhelpers.BuildConfigDirs(t, false)
	flags := &cmdFlags{install: false, serve: true, configDir: configDir}
	defer os.RemoveAll(configDir)
	testhelpers.CopyFile(t, filepath.Join("fixtures", "config.yaml"), configDir)

	l := testhelpers.NewLogger()
	hasQuitC := make(chan bool)
	go func() {
		wantExitCode := 0
		exitCode, err := subMain(flags, l)
		if exitCode != wantExitCode {
			t.Errorf("subMain(%v) exitCode: %d, want: %d",
				flags, exitCode, wantExitCode)
		}
		if err != nil {
			t.Errorf("subMain(%v): %s", flags, err)
		}
		hasQuitC <- true
	}()
	interruptC := time.NewTimer(time.Second).C
	timeoutC := time.NewTimer(6 * time.Second).C
	for {
		select {
		case <-interruptC:
			interruptProcess(t)
		case <-timeoutC:
			t.Fatal("subMain() hasn't stopped")
		case <-hasQuitC:
			return
		}
	}

}

// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris

package main

import (
	"os"
	"testing"
	"time"

	"github.com/vlifesystems/rulehunter/internal/testhelpers"
)

func TestSubMain_interrupt(t *testing.T) {
	cfgDir := testhelpers.BuildConfigDirs(t, false)
	flags := &cmdFlags{install: false, serve: true, configDir: cfgDir}
	defer os.RemoveAll(cfgDir)
	mustWriteConfig(t, cfgDir, 100)

	l := testhelpers.NewLogger()
	hasQuitC := make(chan bool)
	go func() {
		wantExitCode := 0
		exitCode, err := subMain(flags, l)
		if exitCode != wantExitCode {
			t.Errorf("subMain(%v) exitCode: %d, want: %d",
				flags, exitCode, wantExitCode)
		}
		if err != nil {
			t.Errorf("subMain(%v): %s", flags, err)
		}
		hasQuitC <- true
	}()
	interruptC := time.NewTimer(time.Second).C
	timeoutC := time.NewTimer(6 * time.Second).C
	for {
		select {
		case <-interruptC:
			interruptProcess(t)
		case <-timeoutC:
			t.Fatal("subMain() hasn't stopped")
		case <-hasQuitC:
			return
		}
	}

}

Fix test loading config.yaml with wrong locations


package main

import (
  "fmt"
  "os"
  "github.com/mattn/go-gtk/gtk"
  "ghighlighter/windows"
  "ghighlighter/models"
  "ghighlighter/utils"
)

func main() {
  initializeEnvironment()
  gtk.Init(nil)

  mainWindow := windows.MainWindow()
  window := mainWindow.GtkWindow
  window.ShowAll()

  gtk.Main()
}

func initializeEnvironment() {
  dataDir := utils.DataDir()
  error := os.Mkdir(dataDir, 0755)
  if error != nil && !os.IsExist(error) { os.Exit(1) }
}

package main

import (
  "fmt"
  "os"
  "github.com/mattn/go-gtk/gtk"
  "ghighlighter/windows"
  "ghighlighter/models"
  "ghighlighter/utils"
)

func main() {
  initializeEnvironment()
  gtk.Init(nil)

  mainWindow := windows.MainWindow()
  window := mainWindow.GtkWindow
  window.ShowAll()

  config := models.Config()
  if config.AccessToken == "" {
    fmt.Println("No access token, show authentication window")
  }

  gtk.Main()
}

func initializeEnvironment() {
  dataDir := utils.DataDir()
  error := os.Mkdir(dataDir, 0755)
  if error != nil && !os.IsExist(error) { os.Exit(1) }
}

Add dummy handling of empty access token on startup


package watchdog

import (
	"time"
)

// BackOff is the interface to a back-off interval generator.
type BackOff interface {
	// Mark the next call to NextInterval as the "first" retry in a sequence.
	// If the generated intervals are dependent on the number of consecutive
	// (unsuccessful) retries, previous retries should be forgotten here.
	Reset()

	// Generate the next back-off interval.
	NextInterval() time.Duration
}

//
//

type zeroBackOff struct{}

func (b *zeroBackOff) Reset() {}

func (b *zeroBackOff) NextInterval() time.Duration {
	return 0 * time.Millisecond
}

// A back-off interval generator which always returns a zero interval.
func NewZeroBackOff() BackOff {
	return &zeroBackOff{}
}

//
//

type constantBackOff struct {
	interval time.Duration
}

func (b *constantBackOff) Reset() {}

func (b *constantBackOff) NextInterval() time.Duration {
	return b.interval
}

// A back-off interval generator which always returns the same interval.
func NewConstantBackOff(interval time.Duration) BackOff {
	return &constantBackOff{
		interval: interval,
	}
}

package watchdog

import (
	"time"
)

// BackOff is the interface to a back-off interval generator.
type BackOff interface {
	// Mark the next call to NextInterval as the "first" retry in a sequence.
	// If the generated intervals are dependent on the number of consecutive
	// (unsuccessful) retries, previous retries should be forgotten here.
	Reset()

	// Generate the next back-off interval.
	NextInterval() time.Duration
}

//
//

type zeroBackOff struct{}

func (b *zeroBackOff) Reset() {}

func (b *zeroBackOff) NextInterval() time.Duration {
	return 0 * time.Second
}

// A back-off interval generator which always returns a zero interval.
func NewZeroBackOff() BackOff {
	return &zeroBackOff{}
}

//
//

type constantBackOff struct {
	interval time.Duration
}

func (b *constantBackOff) Reset() {}

func (b *constantBackOff) NextInterval() time.Duration {
	return b.interval
}

// A back-off interval generator which always returns the same interval.
func NewConstantBackOff(interval time.Duration) BackOff {
	return &constantBackOff{
		interval: interval,
	}
}

Change zero back-off next interval default.


/*-
 * Copyright (c) 2016, Jörg Pernfuß <joerg.pernfuss@1und1.de>
 * All rights reserved
 *
 * Use of this source code is governed by a 2-clause BSD license
 * that can be found in the LICENSE file.
 */

package msg

type Result struct {
	Type  string
	Error error
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix

/*-
 * Copyright (c) 2016, Jörg Pernfuß <joerg.pernfuss@1und1.de>
 * All rights reserved
 *
 * Use of this source code is governed by a 2-clause BSD license
 * that can be found in the LICENSE file.
 */

package msg

type Result struct {
	Type   string
	Action string
	Error  error

	Super *Supervisor
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix

Update msg.Result for its first usecase


package sort_test

import (
	"fmt"

	"github.com/goSTL/sort"
)

func main() {
	sample := []int{3, 138, 1, 674, 213, 23, 5, 2}
	fmt.Println(sample)

	sort.HeapSortInt(sample)
	fmt.Println(sample)
	//Output:
	//[3 138 1 674 213 23 5 2]
	//[1 2 3 5 23 138 213 674]
}

package sort_test

import (
	"fmt"

	"github.com/goSTL/sort"
)

func ExampleHeapSortInt() {
	sample := []int{3, 138, 1, 674, 213, 23, 5, 2}
	fmt.Println(sample)

	sort.HeapSortInt(sample)
	fmt.Println(sample)
	//Output:
	//[3 138 1 674 213 23 5 2]
	//[1 2 3 5 23 138 213 674]
}

Fix bug of test file


package main

import "fmt"
import "os"
import "os/exec"
import "strconv"
import "time"

func main() {
    cmd := exec.Command("paplay", "/usr/share/sounds/freedesktop/stereo/complete.oga")
    cmd.Start()

    var interval int

    if len(os.Args) == 2 {
        tmp, err := strconv.Atoi(os.Args[1])
        if err != nil{
            fmt.Println("Podaj prawidłowy argument (liczba)!")
            os.Exit(1)
        }
        interval = tmp
    } else {
        fmt.Println("Podaj prawidłową częstotliwość ding!")
        os.Exit(1)
    }

    counter := 0
    for true {
        fmt.Println("Ding!", counter)
        time.Sleep(time.Second * time.Duration(interval))
        cmd := exec.Command("paplay", "/usr/share/sounds/freedesktop/stereo/complete.oga")
        cmd.Start()
        counter++
    }
}

package main

import "fmt"
import "os"
import "os/exec"
import "strconv"
import "time"

const DEFAULT_SOUND = "/usr/share/sounds/freedesktop/stereo/complete.oga"

func main() {
    cmd := exec.Command("paplay", DEFAULT_SOUND)
    cmd.Start()

    var interval int

    if len(os.Args) == 2 {
        tmp, err := strconv.Atoi(os.Args[1])
        if err != nil{
            fmt.Println("Podaj prawidłowy argument (liczba)!")
            os.Exit(1)
        }
        interval = tmp
    } else {
        fmt.Println("Podaj prawidłową częstotliwość ding!")
        os.Exit(1)
    }

    counter := 0
    for true {
        fmt.Println("Ding!", counter)
        time.Sleep(time.Second * time.Duration(interval))
        cmd := exec.Command("paplay", DEFAULT_SOUND)
        cmd.Start()
        counter++
    }
}

Store path to default sound in a constant


package hamming

import (
	"testing"
)

var testCases = []struct {
	expected         int
	strandA, strandB string
	description      string
}{
	{0, "", "", "no difference between empty strands"},
	{2, "AG", "CT", "complete hamming distance for small strand"},
	{0, "A", "A", "no difference between identical strands"},
	{1, "A", "G", "complete distance for single nucleotide strand"},
	{1, "AT", "CT", "small hamming distance"},
	{1, "GGACG", "GGTCG", "small hamming distance in longer strand"},
	{0, "AAAG", "AAA", "ignores extra length on first strand when longer"},
	{0, "AAA", "AAAG", "ignores extra length on second strand when longer"},
	{4, "GATACA", "GCATAA", "large hamming distance"},
	{9, "GGACGGATTCTG", "AGGACGGATTCT", "hamming distance in very long strand"},
}

func TestHamming(t *testing.T) {
	for _, tc := range testCases {

		observed := Distance(tc.strandA, tc.strandB)

		if tc.expected != observed {
			t.Fatalf(`%s:
expected: %v
observed: %v`,
				tc.description,
				tc.expected,
				observed,
			)
		}
	}
}

package hamming

import (
	"testing"
)

var testCases = []struct {
	expected         int
	strandA, strandB string
	description      string
}{
	{0, "", "", "no difference between empty strands"},
	{2, "AG", "CT", "complete hamming distance for small strands"},
	{0, "A", "A", "no difference between identical strands"},
	{1, "A", "G", "complete distance for single nucleotide strands"},
	{1, "AT", "CT", "small hamming distance"},
	{1, "GGACG", "GGTCG", "small hamming distance in longer strands"},
	{0, "AAAG", "AAA", "ignores extra length on first strand when longer"},
	{0, "AAA", "AAAG", "ignores extra length on second strand when longer"},
	{4, "GATACA", "GCATAA", "large hamming distance"},
	{9, "GGACGGATTCTG", "AGGACGGATTCT", "hamming distance in very long strands"},
}

func TestHamming(t *testing.T) {
	for _, tc := range testCases {

		observed := Distance(tc.strandA, tc.strandB)

		if tc.expected != observed {
			t.Fatalf(`%s:
{%v,%v}
expected: %v
observed: %v`,
				tc.description,
				tc.strandA,
				tc.strandB,
				tc.expected,
				observed,
			)
		}
	}
}

Tweak hamming test suite in Go


//go:build linux || zos

package tcp

import (
	"fmt"
	"net"
	"time"

	"golang.org/x/sys/unix"
)

// SetUserTimeout sets the TCP user timeout on a connection's socket.
func SetUserTimeout(conn *net.TCPConn, timeout time.Duration) error {
	rawConn, err := conn.SyscallConn()
	if err != nil {
		return fmt.Errorf("Error getting raw connection: %w", err)
	}

	err = rawConn.Control(func(fd uintptr) {
		err = unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, int(timeout/time.Millisecond))
	})
	if err != nil {
		return fmt.Errorf("Error setting option on socket: %w", err)
	}

	return nil
}

//go:build linux || zos

package tcp

import (
	"fmt"
	"net"
	"time"

	"golang.org/x/sys/unix"
)

// SetUserTimeout sets the TCP user timeout on a connection's socket.
func SetUserTimeout(conn *net.TCPConn, timeout time.Duration) error {
	rawConn, err := conn.SyscallConn()
	if err != nil {
		return fmt.Errorf("Error getting raw connection: %w", err)
	}

	err = rawConn.Control(func(fd uintptr) {
		err = unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, int(timeout/time.Millisecond))
	})
	if err != nil {
		return fmt.Errorf("Error setting TCP_USER_TIMEOUT option on socket: %w", err)
	}

	return nil
}

Improve error message in SetUserTimeout


package main

import (
	"net/http"
)

type Checker func(*MonitorConf) (bool, error)

func checkHTTPStatus(mc *MonitorConf) (bool, error) {
	resp, err := http.Get("http://" + mc.Url)
	if err != nil {
		return false, err
	}

	if resp.StatusCode != 200 {
		return false, nil
	}

	return true, nil
}

package main

import (
	"net/http"
)

type Checker func(*MonitorConf) (bool, error)

func checkHTTPStatus(mc *MonitorConf) (bool, error) {
	resp, err := http.Head("http://" + mc.Url)
	if err != nil {
		return false, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return false, nil
	}

	return true, nil
}

Add resp.body.Close() & use http.Head() in checkHTTPStatus()


package sensu

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

// ...
func (api *API) doRequest(req *http.Request) ([]byte, *http.Response, error) {
	if api.User != "" && api.Pass != "" {
		req.SetBasicAuth(api.User, api.Pass)
	}

	res, err := api.Client.Do(req)
	if err != nil {
		status, ok := err.(*url.Error)
		if !ok {
			return nil, nil, fmt.Errorf("Unexpected error, got %T, wanted *url.Error", err)
		}
		return nil, nil, status.Err
	}

	defer res.Body.Close()

	if res.StatusCode >= 400 {
		return nil, nil, fmt.Errorf("%v", res.Status)
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, nil, fmt.Errorf("Parsing response body returned: %v", err)
	}

	return body, res, nil
}

package sensu

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
)

// ...
func (api *API) doRequest(req *http.Request) ([]byte, *http.Response, error) {
	if api.User != "" && api.Pass != "" {
		req.SetBasicAuth(api.User, api.Pass)
	}

	res, err := api.Client.Do(req)
	if err != nil {
		status, ok := err.(*url.Error)
		if !ok {
			return nil, nil, fmt.Errorf("Unexpected error, got %T, wanted *url.Error", err)
		}
		return nil, nil, status.Err
	}

	defer res.Body.Close()

	if res.StatusCode >= 400 {
		return nil, nil, fmt.Errorf("%v", res.Status)
	}

	body := make([]byte, res.ContentLength)
	_, err = io.ReadFull(res.Body, body)
	if err != nil {
		return nil, nil, fmt.Errorf("Parsing response body returned: %v", err)
	}

	return body, res, nil
}

Use io.ReadFull instead of ioutil.ReadAll when reading Sensu API responses


package audited_test

import (
	"fmt"
	"testing"

	"github.com/jinzhu/gorm"
	"github.com/qor/qor/audited"
	"github.com/qor/qor/test/utils"
)

type Product struct {
	gorm.Model
	Name string
	audited.AuditedModel
}

type User struct {
	gorm.Model
	Name string
}

var db *gorm.DB

func init() {
	db = utils.TestDB()
	db.AutoMigrate(&User{}, &Product{})
	audited.RegisterCallbacks(db)
}

func TestCreateUser(t *testing.T) {
	user := User{Name: "user1"}
	db.Save(&user)
	db := db.Set("qor:current_user", user)

	product := Product{Name: "product1"}
	db.Save(&product)
	if product.CreatedBy != fmt.Sprintf("%v", user.ID) {
		t.Errorf("created_by is not equal current user")
	}

	product.Name = "product_new"
	db.Save(&product)
	if product.UpdatedBy != fmt.Sprintf("%v", user.ID) {
		t.Errorf("updated_by is not equal current user")
	}
}

package audited_test

import (
	"fmt"
	"testing"

	"github.com/jinzhu/gorm"
	"github.com/qor/qor/audited"
	"github.com/qor/qor/test/utils"
)

type Product struct {
	gorm.Model
	Name string
	audited.AuditedModel
}

type User struct {
	gorm.Model
	Name string
}

var db *gorm.DB

func init() {
	db = utils.TestDB()
	db.DropTable(&User{}, &Product{})
	db.AutoMigrate(&User{}, &Product{})
	audited.RegisterCallbacks(db)
}

func TestCreateUser(t *testing.T) {
	user := User{Name: "user1"}
	db.Save(&user)
	db := db.Set("qor:current_user", user)

	product := Product{Name: "product1"}
	db.Save(&product)
	if product.CreatedBy != fmt.Sprintf("%v", user.ID) {
		t.Errorf("created_by is not equal current user")
	}

	product.Name = "product_new"
	db.Save(&product)
	if product.UpdatedBy != fmt.Sprintf("%v", user.ID) {
		t.Errorf("updated_by is not equal current user")
	}
}

Drop tables for audited before run tests


/*
Copyright 2021 The Kubernetes Authors 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 types

const (
	DefaultCriCtl        = "/usr/bin/crictl"
	DefaultCriSocketPath = "unix:///var/run/containerd/containerd.sock"
	UptimeTimeLayout     = "Mon 2006-01-02 15:04:05 UTC"
)

/*
Copyright 2021 The Kubernetes Authors 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 types

const (
	DefaultCriCtl        = "/usr/bin/crictl"
	DefaultCriSocketPath = "unix:///var/run/containerd/containerd.sock"
	UptimeTimeLayout     = "Mon 2006-01-02 15:04:05 MST"
)

Fix the uptime timestamp parsing.


package hyperdb_test

import (
	. "github.com/mysza/hyperdb"

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

var _ = Describe("DB", func() {

})

package hyperdb_test

import (
	"github.com/mysza/hyperdb"

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

	"os"
)

var _ = Describe("DB", func() {
	Describe("Opening the database", func() {
		Context("with defaults", func() {
			It("should open default database", func() {
				// calling Open with empty string should use default file name
				db, err := hyperdb.Open("")
				_, pathErr := os.Stat(hyperdb.DefaultDataFileName)
				defer func() {
					db.Close()
					os.Remove(hyperdb.DefaultDataFileName)
				}()
				Expect(db).ToNot(BeNil())
				Expect(err).To(BeNil())
				Expect(pathErr).To(BeNil())
			})
			It("should open named database", func() {
				const dbname = "very_unique_name.db"
				db, err := hyperdb.Open(dbname)
				_, pathErr := os.Stat(dbname)
				defer func() {
					db.Close()
					os.Remove(dbname)
				}()
				Expect(db).ToNot(BeNil())
				Expect(err).To(BeNil())
				Expect(pathErr).To(BeNil())
			})
		})
	})
})

Add test for opening default and named database


package goexamplepackage
import "fmt"
func DoTest(foo int) int {
     fmt.Println("Example:", foo)
     return 42
}

package goexamplepackage
import "fmt"
func DoExample(foo int) int {
     fmt.Println("Example:", foo)
     return 42
}

Change from DoTest to DoExample.


package lib

import (
	"encoding/json"
	"fmt"
)

func (bigv *Client) GetVirtualMachine(name VirtualMachineName) (vm *VirtualMachine, err error) {
	vm = new(VirtualMachine)
	path := fmt.Sprintf("/accounts/%s/groups/%s/virtual_machines/%s?view=overview", name.Account, name.Group, name.VirtualMachine)
	data, err := bigv.Request("GET", path, "")

	fmt.Printf("'%s'\r\n", data)

	if err != nil {
		//TODO(telyn): good error handling here
		panic("Couldn't make request")
	}

	err = json.Unmarshal(data, vm)
	if err != nil {
		fmt.Printf("Data returned was not a VirtualMachine\r\n")
		fmt.Printf("%+v\r\n")

		return nil, err
	}
	return vm, nil
}

package lib

import (
	"encoding/json"
	"fmt"
)

func (bigv *Client) GetVirtualMachine(name VirtualMachineName) (vm *VirtualMachine, err error) {
	vm = new(VirtualMachine)
	path := fmt.Sprintf("/accounts/%s/groups/%s/virtual_machines/%s?view=overview", name.Account, name.Group, name.VirtualMachine)
	data, err := bigv.Request("GET", path, "")

	//TODO(telyn): extract to Request
	if bigv.DebugLevel >= 3 {
		fmt.Printf("'%s'\r\n", data)
	}

	if err != nil {
		//TODO(telyn): good error handling here
		panic("Couldn't make request")
	}

	err = json.Unmarshal(data, vm)
	if err != nil {
		fmt.Printf("Data returned was not a VirtualMachine\r\n")
		fmt.Printf("%+v\r\n")

		return nil, err
	}
	return vm, nil
}

Make JSON output in GetVirtualMachine require a high debug-level


package mux

import (
	"log"
	"net/http"
	"time"
)

type WrapperFunc func(handlerFunc http.Handler) http.Handler

// Wraps handler func with slice of wrapper functions one by one.
func Wrap(h http.Handler, wrappers ...WrapperFunc) http.Handler {
	for _, w := range wrappers {
		h = w(h)
	}
	return h
}

// Logs requests
func Logger(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		h.ServeHTTP(w, r)

		log.Printf(
			"%s\t%s\t%s",
			r.Method,
			r.RequestURI,
			time.Since(start),
		)
	})
}

// Creates wrapper functions that adds timeout to requests
func Timeout(timeout time.Duration) WrapperFunc {
	return func(h http.Handler) http.Handler {
		return http.TimeoutHandler(h, timeout, "timeout exceed")
	}
}

package mux

import (
	"log"
	"net/http"
	"time"
)

type WrapperFunc func(handlerFunc http.Handler) http.Handler

// Wraps handler func with slice of wrapper functions one by one.
func Wrap(h http.Handler, wrappers ...WrapperFunc) http.Handler {
	for _, w := range wrappers {
		h = w(h)
	}
	return h
}

// Logs requests
func Logger(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		defer log.Printf(
			"%s\t%s\t%s",
			r.Method,
			r.RequestURI,
			time.Since(start),
		)

		h.ServeHTTP(w, r)
	})
}

// Creates wrapper functions that adds timeout to requests
func Timeout(timeout time.Duration) WrapperFunc {
	return func(h http.Handler) http.Handler {
		return http.TimeoutHandler(h, timeout, "timeout exceed")
	}
}

Add defer to ensure that logger will be called after serve http.


package main

import (
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// Sanitises to make a filesystem-safe name.
func sanitiseForFilesystem(s string) string {
	return strings.Replace(s, "/", "-", -1)
}

func getImageIfNeeded(image string, size string, folder string, filename string) {
	path := filepath.Join(folder, filename)
	if _, statErr := os.Stat(path); os.IsNotExist(statErr) {
		image, imageErr := tmdbDownloadImage(image, size)
		if imageErr == nil {
			ioutil.WriteFile(path, image, os.ModePerm)
		} else {
			log.Println("Couldn't download image:", imageErr)
		}
	}
}

package main

import (
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// Sanitises to make a filesystem-safe name.
func sanitiseForFilesystem(s string) string {
	s = strings.Replace(s, "/", "-", -1) // For linux.
	s = strings.Replace(s, "<", "-", -1) // For windows or FAT disks on linux.
	s = strings.Replace(s, ">", "-", -1)
	s = strings.Replace(s, ":", "-", -1)
	s = strings.Replace(s, "\"", "-", -1)
	s = strings.Replace(s, "\\", "-", -1)
	s = strings.Replace(s, "|", "-", -1)
	s = strings.Replace(s, "?", "-", -1)
	s = strings.Replace(s, "*", "-", -1)
	return s
}

func getImageIfNeeded(image string, size string, folder string, filename string) {
	path := filepath.Join(folder, filename)
	if _, statErr := os.Stat(path); os.IsNotExist(statErr) {
		image, imageErr := tmdbDownloadImage(image, size)
		if imageErr == nil {
			ioutil.WriteFile(path, image, os.ModePerm)
		} else {
			log.Println("Couldn't download image:", imageErr)
		}
	}
}

Handle colons and forbidden filenames


package cayley

import (
	"github.com/google/cayley/graph"
	_ "github.com/google/cayley/graph/memstore"
	"github.com/google/cayley/graph/path"
	"github.com/google/cayley/quad"
	_ "github.com/google/cayley/writer"
)

type Iterator graph.Iterator
type QuadStore graph.QuadStore
type QuadWriter graph.QuadWriter

type Path path.Path

var StartMorphism = path.StartMorphism
var StartPath = path.StartPath

var RawNext = graph.Next

type Handle struct {
	graph.QuadStore
	graph.QuadWriter
}

func Quad(subject, predicate, object, label string) quad.Quad {
	return quad.Quad{subject, predicate, object, label}
}

func NewMemoryGraph() (*Handle, error) {
	qs, err := graph.NewQuadStore("memstore", "", nil)
	if err != nil {
		return nil, err
	}
	qw, err := graph.NewQuadWriter("single", qs, nil)
	if err != nil {
		return nil, err
	}
	return &Handle{qs, qw}, nil
}

func (h *Handle) Close() {
	h.QuadStore.Close()
	h.QuadWriter.Close()
}

package cayley

import (
	"github.com/google/cayley/graph"
	_ "github.com/google/cayley/graph/memstore"
	"github.com/google/cayley/graph/path"
	"github.com/google/cayley/quad"
	_ "github.com/google/cayley/writer"
)

type Iterator graph.Iterator
type QuadStore graph.QuadStore
type QuadWriter graph.QuadWriter

type Path path.Path

var StartMorphism = path.StartMorphism
var StartPath = path.StartPath

var RawNext = graph.Next

type Handle struct {
	graph.QuadStore
	graph.QuadWriter
}

func Quad(subject, predicate, object, label string) quad.Quad {
	return quad.Quad{subject, predicate, object, label}
}

func NewGraph(name, dbpath string, opts graph.Options) (*Handle, error) {
	qs, err := graph.NewQuadStore(name, dbpath, opts)
	if err != nil {
		return nil, err
	}
	qw, err := graph.NewQuadWriter("single", qs, nil)
	if err != nil {
		return nil, err
	}
	return &Handle{qs, qw}, nil
}

func NewMemoryGraph() (*Handle, error) {
	return NewGraph("memstore", "", nil)
}

func (h *Handle) Close() {
	h.QuadStore.Close()
	h.QuadWriter.Close()
}

Allow opening a database (bolt, leveldb, mongo) through Go API


package main

import (
	"github.com/mitchellh/packer/builder/amazon/ebsnoami"
	"github.com/mitchellh/packer/packer/plugin"
)

func main() {
	server, err := plugin.Server()
	if err != nil {
		panic(err)
	}
	server.RegisterBuilder(new(ebsnoami.Builder))
	server.Serve()
}

package main

import (
	"github.com/emate/packer-ebsnoami/builder/amazon/ebsnoami"
	"github.com/mitchellh/packer/packer/plugin"
)

func main() {
	server, err := plugin.Server()
	if err != nil {
		panic(err)
	}
	server.RegisterBuilder(new(ebsnoami.Builder))
	server.Serve()
}

Fix import path for plugin


package prefer

type filterable func(identifier string) bool

type Configuration struct {
	identifier  string
	loaders     map[Loader]filterable
	serializers map[Serializer]filterable
}

func NewConfiguration(identifier string) *Configuration {
	return &Configuration{
		identifier: identifier,
	}
}

func (configuration *Configuration) Load(out *interface{}) error {
	loader, err := NewLoader(configuration.identifier)
	if err != nil {
		return err
	}

	content, err := loader.Load(configuration.identifier)
	if err != nil {
		return err
	}

	serializer, err := NewSerializer(configuration.identifier, content)
	if err != nil {
		return err
	}

	err = serializer.Deserialize(content, out)
	return err
}

package prefer

type filterable func(identifier string) bool

type Configuration struct {
	identifier  string
	loaders     map[Loader]filterable
	serializers map[Serializer]filterable
}

func Load(identifier string, out interface{}) (*Configuration, error) {
	configuration := NewConfiguration(identifier)
	err := configuration.Reload(out)
	return configuration, err
}

func NewConfiguration(identifier string) *Configuration {
	return &Configuration{
		identifier: identifier,
	}
}

func (configuration *Configuration) Reload(out interface{}) error {
	loader, err := NewLoader(configuration.identifier)
	if err != nil {
		return err
	}

	content, err := loader.Load(configuration.identifier)
	if err != nil {
		return err
	}

	serializer, err := NewSerializer(configuration.identifier, content)
	if err != nil {
		return err
	}

	err = serializer.Deserialize(content, out)
	return err
}

Fix semantics of Load vs NewConfiguration.


package handlers

import (
	"encoding/json"
	"fmt"
	html "html/template"
	"net/http"
)

var helloTemplate *html.Template

func init() {
	fmt.Println("Try: /hello/world")
	var err error
	helloTemplate, err = html.ParseFiles("templates/hello.html")
	if err != nil {
		panic(err)
	}
}

func HelloWorld(w http.ResponseWriter, r *http.Request) {
	// write the response
	//fmt.Fprintf(w, "Hello %s!", r.URL.Path[len("/hello/"):])
	page := Page{Title: r.URL.Path[len("/hello/"):], Body: "This is a test"}
	contentType := resolveContentType(r)
	if contentType == "text/html" {
		helloTemplate.Execute(w, page)
	} else {
		// json
		var b []byte
		var err error
		w.Header().Set("Content-Type", "application/json")
		b, err = json.Marshal(page)
		if err != nil {
			fmt.Println(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Write(b)
	}
}

package handlers

import (
	"encoding/json"
	"fmt"
	html "html/template"
	"net/http"
)

var helloTemplate *html.Template

func init() {
	fmt.Println("Try: /hello/world")
	var err error
	helloTemplate, err = html.ParseFiles("../templates/hello.html")
	if err != nil {
		panic(err)
	}
}

func HelloWorld(w http.ResponseWriter, r *http.Request) {
	// write the response
	//fmt.Fprintf(w, "Hello %s!", r.URL.Path[len("/hello/"):])
	page := Page{Title: r.URL.Path[len("/hello/"):], Body: "This is a test"}
	contentType := resolveContentType(r)
	if contentType == "text/html" {
		helloTemplate.Execute(w, page)
	} else {
		// json
		var b []byte
		var err error
		w.Header().Set("Content-Type", "application/json")
		b, err = json.Marshal(page)
		if err != nil {
			fmt.Println(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Write(b)
	}
}

Fix template path after moving it to init


/*
httperr defines a simple HTTP error which has a message and status code. This
can be useful for returning errors with relevant HTTP status codes, which the
standard errors package allow for.

Example:
	func Foo() httperr.Error {
	  if err := Bar(); err != nil {
	    return httperr.New(err.Error(), http.StatusInternalServerError)
	  }
	  return nil
	}

	func FooHandler(w http.ResponseWriter, r *http.Request) {
	  if httpErr := Foo(); httpErr != nil {
	    http.Error(w, httpErr.Error(), httpErr.Code())
	  }
	}
*/
package httperr

// Error represents a simple HTTP error which has a message and status code.
type Error interface {
	error
	// Code returns the error's HTTP status code.
	Code() int
}

type httpError struct {
	message string
	code    int
}

// New returns a new Error with the given message and code.
func New(message string, code int) Error {
	return &httpError{message, code}
}

// Error returns the error's message.
func (e *httpError) Error() string {
	return e.message
}

// Code returns the error's HTTP status code.
func (e *httpError) Code() int {
	return e.code
}

/*
Package httperr defines a simple HTTP error which has a message and status code.
This can be useful for returning errors with relevant HTTP status codes, which
the standard errors package allow for.

Example:
	func Foo() httperr.Error {
	  if err := Bar(); err != nil {
	    return httperr.New(err.Error(), http.StatusInternalServerError)
	  }
	  return nil
	}

	func FooHandler(w http.ResponseWriter, r *http.Request) {
	  if httpErr := Foo(); httpErr != nil {
	    http.Error(w, httpErr.Error(), httpErr.Code())
	  }
	}
*/
package httperr

// Error represents a simple HTTP error which has a message and status code.
type Error interface {
	error
	// Code returns the error's HTTP status code.
	Code() int
}

type httpError struct {
	message string
	code    int
}

// New returns a new Error with the given message and code.
func New(message string, code int) Error {
	return &httpError{message, code}
}

// Error returns the error's message.
func (e *httpError) Error() string {
	return e.message
}

// Code returns the error's HTTP status code.
func (e *httpError) Code() int {
	return e.code
}

Fix package description according to golint reccomendation


package main

import (
	corelog "log"
	"log/syslog"
	"os"
)

var log *corelog.Logger

func init() {
	log = corelog.New(os.Stderr, "", 0)
	log.SetFlags(corelog.LstdFlags)
}

func initLogger(slog bool) {
	if slog {
		l, err := syslog.NewLogger(syslog.LOG_INFO, 0)
		if err != nil {
			corelog.Fatalf("Can't initialize logger: %v", err)
		}
		log = l
	}
}

package main

import (
	corelog "log"
	"log/syslog"
	"os"
)

var log *corelog.Logger

func init() {
	log = corelog.New(os.Stderr, "", 0)
	log.SetFlags(corelog.LstdFlags)
}

func initLogger(slog bool) {
	if slog {
		lw, err := syslog.New(syslog.LOG_INFO, "cbfs")
		if err != nil {
			corelog.Fatalf("Can't initialize logger: %v", err)
		}
		log = corelog.New(lw, "", 0)
	}
}

Send a proper process name.


/*
Package mal provides a client for accessing the MyAnimeList API.

Construct a new client, then use one of the client's services to access the
different MyAnimeList API methods. For example, to get the anime list of the
user "Xinil":

	c := mal.NewClient()
	c.SetCredentials("YOUR_MYANIMELIST_USERNAME", "YOUR_MYANIMELIST_PASSWORD")
	c.SetUserAgent("YOUR_WHITELISTED_USER_AGENT")

	list, _, err := c.Anime.List("Xinil")
	// handle err

	// do something with list
*/
package mal

/*
Package mal provides a client for accessing the MyAnimeList API.

Construct a new client, then use one of the client's services to access the
different MyAnimeList API methods. For example, to get the anime list of the
user "Xinil":

	c := mal.NewClient(nil)
	c.SetCredentials("YOUR_MYANIMELIST_USERNAME", "YOUR_MYANIMELIST_PASSWORD")
	c.SetUserAgent("YOUR_WHITELISTED_USER_AGENT")

	list, _, err := c.Anime.List("Xinil")
	// handle err

	// do something with list
*/
package mal

Update mal.NewClient to receive nil as argument


package opts

import (
	"fmt"
	"net"
)

type IpOpt struct {
	*net.IP
}

func NewIpOpt(ref *net.IP, defaultVal string) *IpOpt {
	o := &IpOpt{
		IP: ref,
	}
	o.Set(defaultVal)
	return o
}

func (o *IpOpt) Set(val string) error {
	ip := net.ParseIP(val)
	if ip == nil {
		return fmt.Errorf("%s is not an ip address", val)
	}
	(*o.IP) = net.ParseIP(val)
	return nil
}

func (o *IpOpt) String() string {
	return (*o.IP).String()
}

package opts

import (
	"fmt"
	"net"
)

type IpOpt struct {
	*net.IP
}

func NewIpOpt(ref *net.IP, defaultVal string) *IpOpt {
	o := &IpOpt{
		IP: ref,
	}
	o.Set(defaultVal)
	return o
}

func (o *IpOpt) Set(val string) error {
	ip := net.ParseIP(val)
	if ip == nil {
		return fmt.Errorf("%s is not an ip address", val)
	}
	*o.IP = ip
	return nil
}

func (o *IpOpt) String() string {
	return o.IP.String()
}

Remove duplicate call to net.ParseIP and a little cleanup


package main

import (
	"github.com/yuin/gopher-lua"
	"sync"
)

// The LState pool pattern, as recommended by the author of gopher-lua:
// https://github.com/yuin/gopher-lua#the-lstate-pool-pattern

type lStatePool struct {
	m     sync.Mutex
	saved []*lua.LState
}

func (pl *lStatePool) Get() *lua.LState {
	pl.m.Lock()
	defer pl.m.Unlock()
	n := len(pl.saved)
	if n == 0 {
		return pl.New()
	}
	x := pl.saved[n-1]
	pl.saved = pl.saved[0 : n-1]
	return x
}

func (pl *lStatePool) New() *lua.LState {
	L := lua.NewState()
	// setting the L up here.
	// load scripts, set global variables, share channels, etc...
	return L
}

func (pl *lStatePool) Put(L *lua.LState) {
	pl.m.Lock()
	defer pl.m.Unlock()
	pl.saved = append(pl.saved, L)
}

func (pl *lStatePool) Shutdown() {
	for _, L := range pl.saved {
		L.Close()
	}
}

package main

import (
	"github.com/yuin/gopher-lua"
	"sync"
)

// The LState pool pattern, as recommended by the author of gopher-lua:
// https://github.com/yuin/gopher-lua#the-lstate-pool-pattern

type lStatePool struct {
	m     sync.Mutex
	saved []*lua.LState
}

func (pl *lStatePool) Get() *lua.LState {
	pl.m.Lock()
	defer pl.m.Unlock()
	n := len(pl.saved)
	if n == 0 {
		return pl.New()
	}
	x := pl.saved[n-1]
	pl.saved = pl.saved[0 : n-1]
	return x
}

func (pl *lStatePool) New() *lua.LState {
	L := lua.NewState()
	// setting the L up here.
	// load scripts, set global variables, share channels, etc...
	return L
}

func (pl *lStatePool) Put(L *lua.LState) {
	pl.m.Lock()
	defer pl.m.Unlock()
	pl.saved = append(pl.saved, L)
}

func (pl *lStatePool) Shutdown() {
	// The following line causes a race condition with the
	// graceful shutdown package at server shutdown:
	//for _, L := range pl.saved {
	//	L.Close()
	//}
}

Fix race condition at server shutdown


package schedule

import (
	"testing"
)

func TestGetRandomNumber(t *testing.T) {
	var tests = []struct {
		min int
		max int
	}{
		{0, 0},
		{0, 1},
		{1, 1},
		{0, 10},
		{10, 20},
	}
	for _, test := range tests {
		actual := getRandomNumber(test.min, test.max)
		if test.min > actual || actual > test.max {
			fmt := "getRandomNumber(%d, %d) == %d; not min <= actual <= max"
			t.Errorf(fmt, test.min, test.max, actual)
		}
	}
}

// TODO test random commit message and random time

Add todo for next tests


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

package log

import (
	"flag"

	"github.com/cockroachdb/cockroach/util/log/logflags"
)

func init() {
	logflags.InitFlags(&logging.mu, &logging.toStderr, &logging.alsoToStderr,
		logDir, &logging.color, &logging.verbosity, &logging.vmodule, &logging.traceLocation)
	// We define this flag here because stderrThreshold has the non-exported type
	// "severity".
	flag.Var(&logging.stderrThreshold, "log-threshold", "logs at or above this threshold go to stderr")
}

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

package log

import (
	"flag"

	"github.com/cockroachdb/cockroach/util/log/logflags"
)

func init() {
	logflags.InitFlags(&logging.mu, &logging.toStderr, &logging.alsoToStderr,
		logDir, &logging.color, &logging.verbosity, &logging.vmodule, &logging.traceLocation)
	// We define this flag here because stderrThreshold has the type Severity
	// which we can't pass to logflags without creating an import cycle.
	flag.Var(&logging.stderrThreshold, "log-threshold", "logs at or above this threshold go to stderr")
}

Fix comment about the location of log-threshold flag.


package ergo

type Handler interface {
	ServeHTTP(*Response, *Request)
}

type HandlerFunc func(*Response, *Request)

func (f HandlerFunc) ServeHTTP(w *Response, r *Request) {
	f(w, r)
}

// Operation

type Operation struct {
	method      string
	name        string
	description string
	handler     Handler
	schemes     []string
}

func NewOperation(handler Handler) *Operation {
	return &Operation{
		handler: handler,
	}
}

// Schemes is not additive, meaning that it'll reset the schemes
// already defined with what it's been given if they are valid.
func (o *Operation) Schemes(s ...string) *Operation {
	schemes(o, s)
	return o
}

func (o *Operation) GetSchemes() []string {
	return o.schemes
}

func (o *Operation) setSchemes(schemes []string) {
	o.schemes = schemes
}

package ergo

type Handler interface {
	ServeHTTP(*Response, *Request)
}

type HandlerFunc func(*Response, *Request)

func (f HandlerFunc) ServeHTTP(w *Response, r *Request) {
	f(w, r)
}

// Operation

type Operation struct {
	method      string
	name        string
	description string
	handler     Handler
	schemes     []string
	consumes    []string
}

func NewOperation(handler Handler) *Operation {
	return &Operation{
		handler: handler,
	}
}

// Schemes is not additive, meaning that it'll reset the schemes
// already defined with what it's been given if they are valid.
func (o *Operation) Schemes(s ...string) *Operation {
	schemes(o, s)
	return o
}

func (o *Operation) Consumes(mimes ...string) *Operation {
	consumes(o, mimes)
	return o
}

func (o *Operation) GetSchemes() []string {
	return o.schemes
}

func (o *Operation) GetConsumes() []string {
	return o.consumes
}

func (o *Operation) setSchemes(schemes []string) {
	o.schemes = schemes
}

func (o *Operation) setConsumes(mimes []string) {
	o.consumes = mimes
}

Define consumes functions for Operation


// Implements a Logstash client via TCP or UDP.

package logostash

import (
	"bytes"
	"encoding/json"
	"io"
	"net"
)

type Client struct {
	Conn *net.Conn
}

func NewClient(network, address string) (*Client, error) {
	conn, err := net.Dial(network, address)
	if err != nil {
		return nil, err
	}
	return &Client{&conn}, nil
}

// JSON encodes the input struct and sends it to Logstash.
func (c *Client) SendJson(j interface{}) error {
	buf := &bytes.Buffer{}
	encoder := json.NewEncoder(buf)
	if err := encoder.Encode(j); err != nil {
		return err
	}
	if _, err := io.Copy(*c.Conn, buf); err != nil {
		return err
	}
	return nil
}

// Implements a Logstash client via TCP or UDP.

package logostash

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net"
)

var (
	MissingConnection = errors.New("Connection is missing")
)

type Client struct {
	Conn *net.Conn
}

func NewClient(network, address string) (*Client, error) {
	conn, err := net.Dial(network, address)
	if err != nil {
		return nil, err
	}
	return &Client{&conn}, nil
}

// JSON encodes the input struct and sends it to Logstash.
func (c *Client) SendJson(j interface{}) error {
	if c.Conn == nil {
		return MissingConnection
	}
	buf := &bytes.Buffer{}
	encoder := json.NewEncoder(buf)
	if err := encoder.Encode(j); err != nil {
		return err
	}
	if _, err := io.Copy(*c.Conn, buf); err != nil {
		return err
	}
	return nil
}

Add error for missing connection


package main

import (
	"fmt"
	"os"

	"strings"

	"github.com/hackebrot/go-librariesio/librariesio"
)

func loadFromEnv(keys ...string) (map[string]string, error) {
	env := make(map[string]string)

	for _, key := range keys {
		v := os.Getenv(key)
		if v == "" {
			return nil, fmt.Errorf("environment variable %q is required", key)
		}
		env[key] = v
	}

	return env, nil
}

func main() {
	env, err := loadFromEnv("LIBRARIESIO_API_KEY")

	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
	fmt.Fprintf(os.Stdout, "%v\n", env)

	c := librariesio.NewClient(strings.TrimSpace(env["LIBRARIESIO_API_KEY"]))
	project, _, err := c.GetProject("pypi", "cookiecutter")

	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(1)
	}
	fmt.Fprintf(os.Stdout, "%v\n", project)
}

package main

import (
	"fmt"
	"os"

	"strings"

	"github.com/hackebrot/go-librariesio/librariesio"
)

func loadFromEnv(keys ...string) (map[string]string, error) {
	env := make(map[string]string)

	for _, key := range keys {
		v := os.Getenv(key)
		if v == "" {
			return nil, fmt.Errorf("environment variable %q is required", key)
		}
		env[key] = v
	}

	return env, nil
}

func main() {
	env, err := loadFromEnv("LIBRARIESIO_API_KEY")

	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	c := librariesio.NewClient(strings.TrimSpace(env["LIBRARIESIO_API_KEY"]))
	project, _, err := c.GetProject("pypi", "cookiecutter")

	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(1)
	}
	fmt.Fprintf(os.Stdout, "%+v\n", project)
}

Update cmd to also print struct field names


package loader

type ModuleKind string

const (
	ModuleKindIssueTracking ModuleKind = "issue_tracking"
	ModuleKindCodeReview    ModuleKind = "code_review"
	ModuleKindReleaseNotes  ModuleKind = "release_notes"
)

type ConfigContainer interface {
	PromptUserForConfig() error
}

type Unmarshaller interface {
	Unmarshal(unmarshal func(interface{}) error) error
}

type Marshaller interface {
	Marshal() (interface{}, error)
}

type Validator interface {
	Validate(sectionPath string) error
}

type ConfigSpec interface {
	ConfigKey() string
	GlobalConfig() ConfigContainer
	LocalConfig() ConfigContainer
}

type ModuleConfigSpec interface {
	ConfigSpec
	ModuleKind() ModuleKind
}

package loader

type ModuleKind string

const (
	ModuleKindIssueTracking ModuleKind = "issue_tracking"
	ModuleKindCodeReview    ModuleKind = "code_review"
	ModuleKindReleaseNotes  ModuleKind = "release_notes"
)

// ConfigSpec represents a complete configuration specification.
// It says how to generate, marshal, unmarshal and validate both local
// and global configuration sections for the given configuration key.
type ConfigSpec interface {

	// ConfigKey returns the globally unique string representing this config spec.
	ConfigKey() string

	// GlobalConfig returns the spec for the global configuration file.
	// The global config is always handled before the local one,
	// so the local spec can access data from the global one without any worries.
	GlobalConfig() ConfigContainer

	// LocalConfig returns the spec for the local configuration file.
	LocalConfig() ConfigContainer
}

// ModuleConfigSpec represents a module config spec, which is a config spec
// that also specified a module kind.
type ModuleConfigSpec interface {
	ConfigSpec

	// ModuleKind returns the module kind for the associated module.
	ModuleKind() ModuleKind
}

// ConfigContainer represents the global or local configuration section
// for the given configuration specification. It specified how to
// generate, marshal, unmarshal and validate the configuration section
// for the key specified by the config spec.
type ConfigContainer interface {

	// PromptUserForConfig is triggered when the config section
	// is not valid or it is not possible to unmarshal it.
	PromptUserForConfig() error
}

// A ConfigContainer can implement Marshaller to overwrite the default
// marshalling mechanism. By default the ConfigContainer is taken as is
// and marshalled (passed to the encoder).
type Marshaller interface {
	Marshal() (interface{}, error)
}

// A ConfigContainer can implement Unmarshaller to overwrite the default
// unmarshalling mechanism. By default the ConfigContainer is just filled
// with the raw data from the associated config section.
type Unmarshaller interface {

	// Unmarshal is passed a function that is to be used to fill
	// an object with the data from the associated config section.
	Unmarshal(unmarshal func(interface{}) error) error
}

// A ConfigContainer can implement Validator to overwrite the default
// validating mechanism. By default the ConfigContainer needs to have
// all exported fields filled to be considered valid.
type Validator interface {
	Validate(sectionPath string) error
}

Add comments to the interfaces


package main

import (
	"fmt"
	sci "github.com/samuell/scipipe"
)

func main() {
	// Init barReplacer task
	barReplacer := sci.Sh("sed 's/foo/bar/g' {i:foo2} > {o:bar}")
	// Init function for generating output file pattern
	barReplacer.OutPathFuncs["bar"] = func() string {
		return barReplacer.GetInPath("foo2") + ".bar"
	}

	// Set up tasks for execution
	barReplacer.Init()

	// Connect network
	for _, name := range []string{"foo1", "foo2", "foo3"} {
		barReplacer.InPorts["foo2"] <- sci.NewFileTarget(name + ".txt")
	}
	close(barReplacer.InPorts["foo2"])
	for f := range barReplacer.OutPorts["bar"] {
		fmt.Println("Processed file", f.GetPath(), "...")
	}
}

package main

import (
	"fmt"
	sci "github.com/samuell/scipipe"
)

func main() {
	// Init barReplacer task
	barReplacer := sci.Sh("sed 's/foo/bar/g' {i:foo2} > {o:bar}")
	// Init function for generating output file pattern
	barReplacer.OutPathFuncs["bar"] = func() string {
		return barReplacer.GetInPath("foo2") + ".bar"
	}

	// Set up tasks for execution
	barReplacer.Init()

	// Manually send file targets on the inport of barReplacer
	for _, name := range []string{"foo1", "foo2", "foo3"} {
		barReplacer.InPorts["foo2"] <- sci.NewFileTarget(name + ".txt")
	}
	// We have to manually close the inport as well here, to
	// signal that we are done sending targets (the tasks outport will
	// then automatically be closed as well)
	close(barReplacer.InPorts["foo2"])

	for f := range barReplacer.OutPorts["bar"] {
		fmt.Println("Finished processing file", f.GetPath(), "...")
	}
}

Improve comments in example 2


package dockercommand

import (
	"testing"

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

func TestShortDockerPs(t *testing.T) {
	docker, err := NewDockerForTest()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	containers, err := docker.Ps(&PsOptions{})
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	assert.NotEmpty(t, containers)
	assert.Len(t, containers, 2)
	assert.Equal(t, containers[0].ID, "8dfafdbc3a40")
	assert.Equal(t, containers[1].ID, "0236fd017853")
}

func TestLongDockerPs(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	docker, err := NewDocker("")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	_, err = docker.Run(&RunOptions{
		Image: "ubuntu",
		Cmd:   []string{"ls", "/"},
	})
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	containers, err := docker.Ps(&PsOptions{})
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	assert.NotEmpty(t, containers)
}

package dockercommand

import (
	"testing"

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

func TestShortDockerPs(t *testing.T) {
	docker, err := NewDockerForTest()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	containers, err := docker.Ps(&PsOptions{All: true})
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	assert.NotEmpty(t, containers)
	assert.Len(t, containers, 2)
	assert.Equal(t, containers[0].ID, "8dfafdbc3a40")
	assert.Equal(t, containers[1].ID, "0236fd017853")
}

func TestLongDockerPs(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	docker, err := NewDocker("")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	_, err = docker.Run(&RunOptions{
		Image: "ubuntu",
		Cmd:   []string{"ls", "/"},
	})
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	containers, err := docker.Ps(&PsOptions{})
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	assert.NotEmpty(t, containers)
}

Update ps test: add All option


package dns

import (
	"encoding/binary"
	"testing"
)

func TestPack(t *testing.T) {
	m := &Message{
		QName:  "www.sekimura.org.",
		Qtype:  QtypeA,
		Qclass: QclassIN,
	}
	b, err := Pack(m)
	if err != nil {
		t.Error(err)
	}
	if b[12] != 0x3 || string(b[13:16]) != "www" {
		t.Error("the first label did not match")
	}
	if b[16] != 0x8 || string(b[17:25]) != "sekimura" {
		t.Error("the second label did not match")
	}
	if b[25] != 0x3 || string(b[26:29]) != "org" {
		t.Error("the third label did not match")
	}
	if b[29] != 0x0 {
		t.Error("missing the termination")
	}
	if QtypeA != binary.BigEndian.Uint16(b[30:32]) {
		t.Errorf("Qtype did not match")
	}
	if QclassIN != binary.BigEndian.Uint16(b[32:34]) {
		t.Error("Qclass did not match")
	}
}

package dns

import (
	"encoding/binary"
	"testing"
)

func TestPack(t *testing.T) {
	m := &Message{
		Question: make([]Q, 1),
	}
	m.Question[0] = Q{
		Name:  "www.sekimura.org.",
		Type:  QtypeA,
		Class: QclassIN,
	}
	b, err := Pack(m)
	if err != nil {
		t.Error(err)
	}
	if b[12] != 0x3 || string(b[13:16]) != "www" {
		t.Error("the first label did not match")
	}
	if b[16] != 0x8 || string(b[17:25]) != "sekimura" {
		t.Error("the second label did not match")
	}
	if b[25] != 0x3 || string(b[26:29]) != "org" {
		t.Error("the third label did not match")
	}
	if b[29] != 0x0 {
		t.Error("missing the termination")
	}
	if QtypeA != binary.BigEndian.Uint16(b[30:32]) {
		t.Errorf("Qtype did not match")
	}
	if QclassIN != binary.BigEndian.Uint16(b[32:34]) {
		t.Error("Qclass did not match")
	}
}

Fix a pack test with the new Question field


package somaproto

type ProtoRequestServer struct {
	Server ProtoServer       `json:"server,omitempty"`
	Filter ProtoServerFilter `json:"filter,omitempty"`
	Purge  bool              `json:"purge,omitempty"`
}

type ProtoResultServer struct {
	Code    uint16        `json:"code,omitempty"`
	Status  string        `json:"status,omitempty"`
	Text    []string      `json:"text,omitempty"`
	Servers []ProtoServer `json:"servers,omitempty"`
}

type ProtoServer struct {
	AssetId    uint64              `json:"assetid,omitempty"`
	Datacenter string              `json:"datacenter,omitempty"`
	Location   string              `json:"location,omitempty"`
	Name       string              `json:"name,omitempty"`
	Online     bool                `json:"online,omitempty"`
	Details    *ProtoServerDetails `json:"details,omitempty"`
}

type ProtoServerDetails struct {
	CreatedAt string   `json:"createdat,omitempty"`
	CreatedBy string   `json:"createdby,omitempty"`
	Nodes     []string `json:"nodes,omitempty"`
}

type ProtoServerFilter struct {
	Online     bool   `json:"online,omitempty"`
	Deleted    bool   `json:"deleted,omitempty"`
	Datacenter string `json:"datacenter,omitempty"`
	Name       string `json:"name,omitempty"`
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix

package somaproto

import "github.com/satori/go.uuid"

type ProtoRequestServer struct {
	Server ProtoServer       `json:"server,omitempty"`
	Filter ProtoServerFilter `json:"filter,omitempty"`
	Purge  bool              `json:"purge,omitempty"`
}

type ProtoResultServer struct {
	Code    uint16        `json:"code,omitempty"`
	Status  string        `json:"status,omitempty"`
	Text    []string      `json:"text,omitempty"`
	Servers []ProtoServer `json:"servers,omitempty"`
}

type ProtoServer struct {
	Id         uuid.UUID           `json:"id,omitempty"`
	AssetId    uint64              `json:"assetid,omitempty"`
	Datacenter string              `json:"datacenter,omitempty"`
	Location   string              `json:"location,omitempty"`
	Name       string              `json:"name,omitempty"`
	Online     bool                `json:"online,omitempty"`
	Details    *ProtoServerDetails `json:"details,omitempty"`
}

type ProtoServerDetails struct {
	CreatedAt string   `json:"createdat,omitempty"`
	CreatedBy string   `json:"createdby,omitempty"`
	Nodes     []string `json:"nodes,omitempty"`
}

type ProtoServerFilter struct {
	Online     bool   `json:"online,omitempty"`
	Deleted    bool   `json:"deleted,omitempty"`
	Datacenter string `json:"datacenter,omitempty"`
	Name       string `json:"name,omitempty"`
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix

Add Id field to ProtoServer