package main

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

	"gopkg.in/wolfeidau/go-buildkite.v1"
	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	apiToken = kingpin.Flag("token", "API token").Required().String()
	org      = kingpin.Flag("org", "Orginization slug").Required().String()
	debug    = kingpin.Flag("debug", "Enable debugging").Bool()
)

func main() {
	kingpin.Parse()

	config, err := buildkite.NewTokenConfig(*apiToken, *debug)

	if err != nil {
		log.Fatalf("client config failed: %s", err)
	}

	client := buildkite.NewClient(config.Client())

	projects, _, err := client.Projects.List(*org, nil)

	if err != nil {
		log.Fatalf("list projects failed: %s", err)
	}

	data, err := json.MarshalIndent(projects, "", "\t")

	if err != nil {
		log.Fatalf("json encode failed: %s", err)
	}

	fmt.Fprintf(os.Stdout, "%s", string(data))
}

package main

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

	"github.com/wolfeidau/go-buildkite/buildkite"

	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	apiToken = kingpin.Flag("token", "API token").Required().String()
	org      = kingpin.Flag("org", "Orginization slug").Required().String()
	debug    = kingpin.Flag("debug", "Enable debugging").Bool()
)

func main() {
	kingpin.Parse()

	config, err := buildkite.NewTokenConfig(*apiToken, *debug)

	if err != nil {
		log.Fatalf("client config failed: %s", err)
	}

	client := buildkite.NewClient(config.Client())

	projects, _, err := client.Projects.List(*org, nil)

	if err != nil {
		log.Fatalf("list projects failed: %s", err)
	}

	data, err := json.MarshalIndent(projects, "", "\t")

	if err != nil {
		log.Fatalf("json encode failed: %s", err)
	}

	fmt.Fprintf(os.Stdout, "%s", string(data))
}

Undo using gopkg.in for examples.


package state

// State represents the state of a hosts
type State int

const (
	None State = iota
	Running
	Paused
	Saved
	Stopped
	Stopping
	Starting
	Error
)

var states = []string{
	"",
	"Running",
	"Paused",
	"Saved",
	"Stopped",
	"Stopping",
	"Starting",
	"Error",
}

func (s State) String() string {
	if int(s) < len(states) {
		return states[s]
	}
	return ""
}

package state

// State represents the state of a host
type State int

const (
	None State = iota
	Running
	Paused
	Saved
	Stopped
	Stopping
	Starting
	Error
)

var states = []string{
	"",
	"Running",
	"Paused",
	"Saved",
	"Stopped",
	"Stopping",
	"Starting",
	"Error",
}

// Given a State type, returns its string representation
func (s State) String() string {
	if int(s) >= 0 && int(s) < len(states) {
		return states[s]
	} else {
		return ""
	}
}

Fix doc typo and add additional if condition


package utils

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

// GpgDetachedSign signs file with detached signature in ASCII format
func GpgDetachedSign(source string, destination string) error {
	fmt.Printf("v = %#v\n", strings.Join([]string{"gpg", "-o", destination, "--armor", "--detach-sign", source}, " "))
	cmd := exec.Command("gpg", "-o", destination, "--armor", "--yes", "--detach-sign", source)
	return cmd.Run()
}

// GpgClearSign clear-signs the file
func GpgClearSign(source string, destination string) error {
	cmd := exec.Command("gpg", "-o", destination, "--yes", "--clearsign", source)
	return cmd.Run()
}

package utils

import (
	"os/exec"
)

// Signer interface describes facility implementing signing of files
type Signer interface {
	SetKey(keyRef string)
	DetachedSign(source string, destination string) error
	ClearSign(source string, destination string) error
}

// Test interface
var (
	_ Signer = &GpgSigner{}
)

// GpgSigner is implementation of Signer interface using gpg
type GpgSigner struct {
	keyRef string
}

// SetKey sets key ID to use when signing files
func (g *GpgSigner) SetKey(keyRef string) {
	g.keyRef = keyRef
}

// DetachedSign signs file with detached signature in ASCII format
func (g *GpgSigner) DetachedSign(source string, destination string) error {
	args := []string{"-o", destination, "--armor", "--yes"}
	if g.keyRef != "" {
		args = append(args, "-u", g.keyRef)
	}
	args = append(args, "--detach-sign", source)
	cmd := exec.Command("gpg", args...)
	return cmd.Run()
}

// ClearSign clear-signs the file
func (g *GpgSigner) ClearSign(source string, destination string) error {
	args := []string{"-o", destination, "--yes"}
	if g.keyRef != "" {
		args = append(args, "-u", g.keyRef)
	}
	args = append(args, "--clearsign", source)
	cmd := exec.Command("gpg", args...)
	return cmd.Run()
}

Rework Gpg signing to work through interface.


package main

import (
	"github.com/WhiteHatCP/seclab-listener/backend"
	"github.com/WhiteHatCP/seclab-listener/server"
	"log"
	"net"
	"os"
	"syscall"
)

func main() {
	syscall.Umask(0007)

	socket := "seclab.sock"
	ln, err := net.Listen("unix", socket)
	syscall.Chmod(socket, 0770)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	backend := backend.New("status.txt", "open.txt", "closed.txt")
	s := server.New([]byte(os.Args[1]), 10, backend)
	s.Serve(ln)
}

package main

import (
	"github.com/WhiteHatCP/seclab-listener/backend"
	"github.com/WhiteHatCP/seclab-listener/server"
	"log"
	"net"
	"os"
	"syscall"
)

func main() {
	syscall.Umask(0007)

	socket := "seclab.sock"
	ln, err := net.Listen("unix", socket)
	syscall.Chmod(socket, 0770)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	// Make sure the socket closes
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for sig := range c {
			log.Printf("Captured: %v", sig)
			ln.Close()
		}
	}()

	backend := backend.New("status.txt", "open.txt", "closed.txt")
	s := server.New([]byte(os.Args[1]), 10, backend)
	s.Serve(ln)
}

Make sure the socket closes


package octokit

const (
	gitHubAPIURL     = "https://api.github.com"
	userAgent        = "Octokit Go " + version
	version          = "0.3.0"
	defaultMediaType = "application/vnd.github.v3+json; charset=utf-8"
)

package octokit

const (
	gitHubAPIURL     = "https://api.github.com"
	userAgent        = "Octokit Go " + version
	version          = "0.3.0"
	defaultMediaType = "application/vnd.github.v3+json;charset=utf-8"
)

Trim space for multiple media type entries


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
}

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

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
}

Define schemes functions for Operation


// Copyright 2018 The Hugo 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 hugo

// CurrentVersion represents the current build version.
// This should be the only one.
var CurrentVersion = Version{
	Major:      0,
	Minor:      105,
	PatchLevel: 0,
	Suffix:     "-DEV",
}

// Copyright 2018 The Hugo 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 hugo

// CurrentVersion represents the current build version.
// This should be the only one.
var CurrentVersion = Version{
	Major:      0,
	Minor:      105,
	PatchLevel: 0,
	Suffix:     "",
}

Bump versions for release of 0.105.0


package client

import (
	"github.com/Symantec/Dominator/lib/hash"
	"github.com/Symantec/Dominator/lib/srpc"
	"github.com/Symantec/Dominator/proto/sub"
)

func fetch(client *srpc.Client, serverAddress string,
	hashes []hash.Hash) error {
	request := sub.FetchRequest{serverAddress, hashes}
	var reply sub.FetchResponse
	return client.RequestReply("Subd.Fetch", request, &reply)
}

package client

import (
	"github.com/Symantec/Dominator/lib/hash"
	"github.com/Symantec/Dominator/lib/srpc"
	"github.com/Symantec/Dominator/proto/sub"
)

func fetch(client *srpc.Client, serverAddress string,
	hashes []hash.Hash) error {
	request := sub.FetchRequest{ServerAddress: serverAddress, Hashes: hashes}
	var reply sub.FetchResponse
	return client.RequestReply("Subd.Fetch", request, &reply)
}

Use named initialisers in sub/client.Fetch().


package netconf

type NetworkConfig struct {
	PreCmds    []string                   `yaml:"pre_cmds,omitempty"`
	Dns        DnsConfig                  `yaml:"dns,omitempty"`
	Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"`
	PostCmds   []string                   `yaml:"post_cmds,omitempty"`
}

type InterfaceConfig struct {
	Match       string            `yaml:"match,omitempty"`
	DHCP        bool              `yaml:"dhcp,omitempty"`
	DHCPArgs    string            `yaml:"dhcp_args,omitempty"`
	Address     string            `yaml:"address,omitempty"`
	Addresses   []string          `yaml:"addresses,omitempty"`
	IPV4LL      bool              `yaml:"ipv4ll,omitempty"`
	Gateway     string            `yaml:"gateway,omitempty"`
	GatewayIpv6 string            `yaml:"gateway_ipv6,omitempty"`
	MTU         int               `yaml:"mtu,omitempty"`
	Bridge      string            `yaml:"bridge,omitempty"`
	Bond        string            `yaml:"bond,omitempty"`
	BondOpts    map[string]string `yaml:"bond_opts,omitempty"`
	PostUp      []string          `yaml:"post_up,omitempty"`
	PreUp       []string          `yaml:"pre_up,omitempty"`
	Vlans       string            `yaml:"vlans,omitempty"`
}

type DnsConfig struct {
	Nameservers []string `yaml:"nameservers,flow,omitempty"`
	Search      []string `yaml:"search,flow,omitempty"`
}

package netconf

type NetworkConfig struct {
	PreCmds    []string                   `yaml:"pre_cmds,omitempty"`
	Dns        DnsConfig                  `yaml:"dns,omitempty"`
	Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"`
	PostCmds   []string                   `yaml:"post_cmds,omitempty"`
	HttpProxy  string                     `yaml:"http_proxy,omitempty"`
	HttpsProxy string                     `yaml:"https_proxy,omitempty"`
	NoProxy    string                     `yaml:"no_proxy,omitempty"`
}

type InterfaceConfig struct {
	Match       string            `yaml:"match,omitempty"`
	DHCP        bool              `yaml:"dhcp,omitempty"`
	DHCPArgs    string            `yaml:"dhcp_args,omitempty"`
	Address     string            `yaml:"address,omitempty"`
	Addresses   []string          `yaml:"addresses,omitempty"`
	IPV4LL      bool              `yaml:"ipv4ll,omitempty"`
	Gateway     string            `yaml:"gateway,omitempty"`
	GatewayIpv6 string            `yaml:"gateway_ipv6,omitempty"`
	MTU         int               `yaml:"mtu,omitempty"`
	Bridge      string            `yaml:"bridge,omitempty"`
	Bond        string            `yaml:"bond,omitempty"`
	BondOpts    map[string]string `yaml:"bond_opts,omitempty"`
	PostUp      []string          `yaml:"post_up,omitempty"`
	PreUp       []string          `yaml:"pre_up,omitempty"`
	Vlans       string            `yaml:"vlans,omitempty"`
}

type DnsConfig struct {
	Nameservers []string `yaml:"nameservers,flow,omitempty"`
	Search      []string `yaml:"search,flow,omitempty"`
}

Add proxy settings to NetworkConfig


package main // import "eriol.xyz/piken"

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

func download(url, output string) error {

	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	out, err := os.Create(output)
	if err != nil {
		return err
	}
	defer out.Close()

	// io.copyBuffer, the actual implementation of io.Copy, reads maximum 32 KB
	// from input, writes to output and then repeats. No need to worry about
	// the size of file to download.
	_, err = io.Copy(out, r.Body)
	if err != nil {
		return err
	}

	return nil

}

package main // import "eriol.xyz/piken"

import (
	"io"
	"net/http"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/mitchellh/go-homedir"
)

func download(url, output string) error {

	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	out, err := os.Create(output)
	if err != nil {
		return err
	}
	defer out.Close()

	// io.copyBuffer, the actual implementation of io.Copy, reads maximum 32 KB
	// from input, writes to output and then repeats. No need to worry about
	// the size of file to download.
	_, err = io.Copy(out, r.Body)
	if err != nil {
		return err
	}

	return nil

}

// Get user home directory or exit with a fatal error.
func getHome() string {

	homeDir, err := homedir.Dir()
	if err != nil {
		logrus.Fatal(err)
	}

	return homeDir
}

Add a function to get user $HOME dir (cross platform)


// $G $D/$F.go && $L $F.$A && (! ./$A.out || echo BUG: should not succeed)

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

package main
type I interface { };
func foo1(i int) int { return i }
func foo2(i int32) int32 { return i }
func main() {
  var i I;
  i = 1;
  var v1 int = i;
  if foo1(v1) != 1 { panicln(1) }
  var v2 int32 = i.(int).(int32);
  if foo1(v2) != 1 { panicln(2) }
  var v3 int32 = i; // This implicit type conversion should fail at runtime.
  if foo1(v3) != 1 { panicln(3) }
}

// $G $D/$F.go && $L $F.$A && (! ./$A.out || echo BUG: should not succeed)

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

package main
type I interface { };
func foo1(i int) int { return i }
func foo2(i int32) int32 { return i }
func main() {
  var i I;
  i = 1;
  var v1 int = i;
  if foo1(v1) != 1 { panicln(1) }
  var v2 int32 = i.(int).(int32);
  if foo2(v2) != 1 { panicln(2) }
  var v3 int32 = i; // This implicit type conversion should fail at runtime.
  if foo2(v3) != 1 { panicln(3) }
}

Call the right function for int32 values.


package golog

import . "github.com/mndrix/golog/term"

import "testing"

func TestFacts (t *testing.T) {
    db := NewDatabase().
            Asserta(NewTerm("father", NewTerm("michael"))).
            Asserta(NewTerm("father", NewTerm("marc")))
    t.Logf("%s\n", db.String())

    // these should be provably true
    if !IsTrue(db, NewTerm("father", NewTerm("michael"))) {
        t.Errorf("Couldn't prove father(michael)")
    }
    if !IsTrue(db, NewTerm("father", NewTerm("marc"))) {
        t.Errorf("Couldn't prove father(marc)")
    }

    // these should not be provable
    if IsTrue(db, NewTerm("father", NewTerm("sue"))) {
        t.Errorf("Proved father(sue)")
    }
    if IsTrue(db, NewTerm("father", NewTerm("michael"), NewTerm("marc"))) {
        t.Errorf("Proved father(michael, marc)")
    }
    if IsTrue(db, NewTerm("mother", NewTerm("michael"))) {
        t.Errorf("Proved mother(michael)")
    }
}

package golog

import "github.com/mndrix/golog/read"

import "testing"

func TestFacts (t *testing.T) {
    rt := read.Term_
    db := NewDatabase().
            Asserta(rt(`father(michael).`)).
            Asserta(rt(`father(marc).`))
    t.Logf("%s\n", db.String())

    // these should be provably true
    if !IsTrue(db, rt(`father(michael).`)) {
        t.Errorf("Couldn't prove father(michael)")
    }
    if !IsTrue(db, rt(`father(marc).`)) {
        t.Errorf("Couldn't prove father(marc)")
    }

    // these should not be provable
    if IsTrue(db, rt(`father(sue).`)) {
        t.Errorf("Proved father(sue)")
    }
    if IsTrue(db, rt(`father(michael,marc).`)) {
        t.Errorf("Proved father(michael, marc)")
    }
    if IsTrue(db, rt(`mother(michael).`)) {
        t.Errorf("Proved mother(michael)")
    }
}

Simplify prove tests with read.Term_


package cloudsql

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
)

const (
	maxUsernameLength       = 16 // Limit from http://dev.mysql.com/doc/refman/5.7/en/user-names.html
	generatedPasswordLength = 32
)

func GenerateUsername(instanceID, bindingID string) (string, error) {
	if len(instanceID)+len(bindingID) == 0 {
		return "", fmt.Errorf("empty instanceID and bindingID")
	}

	username := instanceID + bindingID
	if len(username) > maxUsernameLength {
		username = username[:maxUsernameLength]
	}

	return username, nil
}

func GeneratePassword() (string, error) {
	rb := make([]byte, generatedPasswordLength)
	_, err := rand.Read(rb)

	if err != nil {
		return "", err
	}

	rs := base64.URLEncoding.EncodeToString(rb)

	return rs, nil
}

package cloudsql

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
)

const (
	maxUsernameLength       = 16 // Limit from http://dev.mysql.com/doc/refman/5.7/en/user-names.html
	generatedPasswordLength = 32
)

func GenerateUsername(instanceID, bindingID string) (string, error) {
	if len(instanceID)+len(bindingID) == 0 {
		return "", fmt.Errorf("empty instanceID and bindingID")
	}

	username := bindingID + instanceID
	if len(username) > maxUsernameLength {
		username = username[:maxUsernameLength]
	}

	return username, nil
}

func GeneratePassword() (string, error) {
	rb := make([]byte, generatedPasswordLength)
	_, err := rand.Read(rb)

	if err != nil {
		return "", err
	}

	rs := base64.URLEncoding.EncodeToString(rb)

	return rs, nil
}

Switch the order of the bindingID/instanceID


package db

import (
	"database/sql"
	sq "github.com/lann/squirrel"
	"time"
)

var LedgerRecordSelect sq.SelectBuilder = sq.
	Select("hl.*").
	From("history_ledgers hl")

type LedgerRecord struct {
	HistoryRecord
	Sequence           int32          `db:"sequence"`
	ImporterVersion    int32          `db:"importer_version"`
	LedgerHash         string         `db:"ledger_hash"`
	PreviousLedgerHash sql.NullString `db:"previous_ledger_hash"`
	TransactionCount   int32          `db:"transaction_count"`
	OperationCount     int32          `db:"operation_count"`
	ClosedAt           time.Time      `db:"closed_at"`
	CreatedAt          time.Time      `db:"created_at"`
	UpdatedAt          time.Time      `db:"updated_at"`
}

package db

import (
	"database/sql"
	sq "github.com/lann/squirrel"
	"time"
)

var LedgerRecordSelect sq.SelectBuilder = sq.Select(
	"hl.id",
	"hl.sequence",
	"hl.importer_version",
	"hl.ledger_hash",
	"hl.previous_ledger_hash",
	"hl.transaction_count",
	"hl.operation_count",
	"hl.closed_at",
	"hl.created_at",
	"hl.updated_at",
).From("history_ledgers hl")

type LedgerRecord struct {
	HistoryRecord
	Sequence           int32          `db:"sequence"`
	ImporterVersion    int32          `db:"importer_version"`
	LedgerHash         string         `db:"ledger_hash"`
	PreviousLedgerHash sql.NullString `db:"previous_ledger_hash"`
	TransactionCount   int32          `db:"transaction_count"`
	OperationCount     int32          `db:"operation_count"`
	ClosedAt           time.Time      `db:"closed_at"`
	CreatedAt          time.Time      `db:"created_at"`
	UpdatedAt          time.Time      `db:"updated_at"`
}

Select history_ledger columns directly, to prep for more fields


package main

import (
	"flag"
	"github.com/goerlang/node"
	"log"
)

var enableNode bool
var nodeName string
var nodeCookie string

func init() {
	flag.BoolVar(&enableNode, "node", false, "start erlang node")
	flag.StringVar(&nodeName, "node-name", "", "name of erlang node")
	flag.StringVar(&nodeCookie, "node-cookie", "", "cookie of erlang node")
}

func nodeEnabled() bool {
	return enableNode
}

func runNode() (enode *node.Node) {
	enode = node.NewNode(nodeName, nodeCookie)
	err := enode.Publish(5858)
	if err != nil {
		log.Printf("Cannot publish: %s", err)
		enode = nil
	}
	eSrv := new(eclusSrv)
	enode.Spawn(eSrv)
	return
}

package main

import (
	"flag"
	"github.com/goerlang/node"
	"log"
)

var enableNode bool
var nodeName string
var nodeCookie string
var nodePort int

func init() {
	flag.BoolVar(&enableNode, "node", false, "start erlang node")
	flag.StringVar(&nodeName, "node-name", "", "name of erlang node")
	flag.StringVar(&nodeCookie, "node-cookie", "", "cookie of erlang node")
	flag.IntVar(&nodePort, "node-port", 5858, "port of erlang node")
}

func nodeEnabled() bool {
	return enableNode
}

func runNode() (enode *node.Node) {
	enode = node.NewNode(nodeName, nodeCookie)
	err := enode.Publish(nodePort)
	if err != nil {
		log.Printf("Cannot publish: %s", err)
		enode = nil
	}
	eSrv := new(eclusSrv)
	enode.Spawn(eSrv)
	return
}

Add flag `-node-port` to specify TCP-port for distribution protocol


/*
Copyright 2021 The Tekton Authors

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

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

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

package v1alpha1

import (
	"context"
)

func (tc *TektonConfig) SetDefaults(ctx context.Context) {
	if tc.Spec.Profile == "" {
		tc.Spec.Profile = ProfileBasic
	}

	tc.Spec.Pipeline.PipelineProperties.setDefaults()

	setAddonDefaults(&tc.Spec.Addon.Params)
}

/*
Copyright 2021 The Tekton Authors

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

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

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

package v1alpha1

import (
	"context"
)

func (tc *TektonConfig) SetDefaults(ctx context.Context) {
	if tc.Spec.Profile == "" {
		tc.Spec.Profile = ProfileBasic
	}

	tc.Spec.Pipeline.PipelineProperties.setDefaults()

	setAddonDefaults(&tc.Spec.Addon.Params)

	// before adding webhook we had default value for pruner's keep as 1
	// but we expect user to define all values now otherwise webhook reject
	// request so if a user has installed prev version and has not enabled
	// pruner then `keep` will have a value 1 and after upgrading
	// to newer version webhook will fail if keep has a value and
	// other fields are not defined
	// this handles that case by removing the default for keep if
	// other pruner fields are not defined
	if len(tc.Spec.Pruner.Resources) == 0 {
		tc.Spec.Pruner.Keep = nil
		tc.Spec.Pruner.Schedule = ""
	} else if tc.Spec.Pruner.Schedule == "" {
		tc.Spec.Pruner.Keep = nil
		tc.Spec.Pruner.Resources = []string{}
	}
}

Add param to enable/disable servicemonitor


package diego_errors

func SanitizeErrorMessage(message string) string {
	switch message {
	case
		INSUFFICIENT_RESOURCES_MESSAGE,
		MISSING_APP_BITS_DOWNLOAD_URI_MESSAGE,
		MISSING_APP_ID_MESSAGE,
		MISSING_TASK_ID_MESSAGE,
		NO_COMPILER_DEFINED_MESSAGE:
		return message
	default:
		return "staging failed"
	}
}

package diego_errors

func SanitizeErrorMessage(message string) string {
	switch message {
	case
		INSUFFICIENT_RESOURCES_MESSAGE,
		MISSING_APP_BITS_DOWNLOAD_URI_MESSAGE,
		MISSING_APP_ID_MESSAGE,
		MISSING_TASK_ID_MESSAGE,
		NO_COMPILER_DEFINED_MESSAGE,
		CELL_MISMATCH_MESSAGE:
		return message
	default:
		return "staging failed"
	}
}

Allow CELL_MISMATCH to flow back to the stager


package swarm

import (
	"fmt"

	"golang.org/x/net/context"

	"github.com/docker/docker/cli"
	"github.com/docker/docker/cli/command"
	"github.com/spf13/cobra"
)

type leaveOptions struct {
	force bool
}

func newLeaveCommand(dockerCli *command.DockerCli) *cobra.Command {
	opts := leaveOptions{}

	cmd := &cobra.Command{
		Use:   "leave [OPTIONS]",
		Short: "Leave a swarm",
		Args:  cli.NoArgs,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runLeave(dockerCli, opts)
		},
	}

	flags := cmd.Flags()
	flags.BoolVar(&opts.force, "force", false, "Force leave ignoring warnings.")
	return cmd
}

func runLeave(dockerCli *command.DockerCli, opts leaveOptions) error {
	client := dockerCli.Client()
	ctx := context.Background()

	if err := client.SwarmLeave(ctx, opts.force); err != nil {
		return err
	}

	fmt.Fprintln(dockerCli.Out(), "Node left the swarm.")
	return nil
}

package swarm

import (
	"fmt"

	"golang.org/x/net/context"

	"github.com/docker/docker/cli"
	"github.com/docker/docker/cli/command"
	"github.com/spf13/cobra"
)

type leaveOptions struct {
	force bool
}

func newLeaveCommand(dockerCli *command.DockerCli) *cobra.Command {
	opts := leaveOptions{}

	cmd := &cobra.Command{
		Use:   "leave [OPTIONS]",
		Short: "Leave the swarm (workers only)",
		Args:  cli.NoArgs,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runLeave(dockerCli, opts)
		},
	}

	flags := cmd.Flags()
	flags.BoolVar(&opts.force, "force", false, "Force this node to leave the swarm, ignoring warnings")
	return cmd
}

func runLeave(dockerCli *command.DockerCli, opts leaveOptions) error {
	client := dockerCli.Client()
	ctx := context.Background()

	if err := client.SwarmLeave(ctx, opts.force); err != nil {
		return err
	}

	fmt.Fprintln(dockerCli.Out(), "Node left the swarm.")
	return nil
}

Clarify usage of --force when used on a swarm manager


package rev

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

func TestContentTypeByFilename(t *testing.T) {
	testCases := map[string]string{
		"xyz.jpg":       "image/jpeg",
		"helloworld.c":  "text/x-c; charset=utf-8",
		"helloworld.":   "application/octet-stream",
		"helloworld":    "application/octet-stream",
		"hello.world.c": "text/x-c; charset=utf-8",
	}
	ConfPaths = []string{path.Join(
		findSrcPath(REVEL_IMPORT_PATH),
		filepath.FromSlash(REVEL_IMPORT_PATH),
		"conf"),
	}
	loadMimeConfig()
	for filename, expected := range testCases {
		actual := ContentTypeByFilename(filename)
		if actual != expected {
			t.Errorf("%s: %s, Expected %s", filename, actual, expected)
		}
	}
}

package rev

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

func TestContentTypeByFilename(t *testing.T) {
	testCases := map[string]string{
		"xyz.jpg":       "image/jpeg",
		"helloworld.c":  "text/x-c; charset=utf-8",
		"helloworld.":   "application/octet-stream",
		"helloworld":    "application/octet-stream",
		"hello.world.c": "text/x-c; charset=utf-8",
	}
	srcPath, _ := findSrcPaths(REVEL_IMPORT_PATH)
	ConfPaths = []string{path.Join(
		srcPath,
		filepath.FromSlash(REVEL_IMPORT_PATH),
		"conf"),
	}
	loadMimeConfig()
	for filename, expected := range testCases {
		actual := ContentTypeByFilename(filename)
		if actual != expected {
			t.Errorf("%s: %s, Expected %s", filename, actual, expected)
		}
	}
}

Fix test to use new findSrcPaths


package model

import (
	"errors"

	"gopkg.in/mgo.v2/bson"
)

// A user of the system
type User struct {
	ID       bson.ObjectId `json:"-"         bson:"_id,omitempty"`
	Username string        `json:"user-name" bson:"user-name"`
}

// GetID to satisfy jsonapi.MarshalIdentifier interface
func (u User) GetID() string {
	return u.ID.Hex()
}

// SetID to satisfy jsonapi.UnmarshalIdentifier interface
func (u *User) SetID(id string) error {

	if bson.IsObjectIdHex(id) {
		u.ID = bson.ObjectIdHex(id)
		return nil
	}

	return errors.New("<id>" + id + "</id> is not a valid user id")
}

package model

import "gopkg.in/mgo.v2/bson"

// A user of the system
type User struct {
	ID       bson.ObjectId `json:"-"         bson:"_id,omitempty"`
	Username string        `json:"user-name" bson:"user-name"`
}

// GetID to satisfy jsonapi.MarshalIdentifier interface
func (u User) GetID() string {
	return u.ID.Hex()
}

// SetID to satisfy jsonapi.UnmarshalIdentifier interface
func (u *User) SetID(id string) error {

	if bson.IsObjectIdHex(id) {
		u.ID = bson.ObjectIdHex(id)
		return nil
	}

	return nil
	// return errors.New("<id>" + id + "</id> is not a valid user id")
}

Remove id check to debug travis CI


package middleware

import (
	"net/http"

	nextSkyerr "github.com/skygeario/skygear-server/pkg/core/skyerr"
	"github.com/skygeario/skygear-server/pkg/server/skyerr"
)

// RecoverHandler provides an interface to handle recovered panic error
type RecoverHandler func(http.ResponseWriter, *http.Request, skyerr.Error)

// RecoverMiddleware recover from panic
type RecoverMiddleware struct {
	RecoverHandler RecoverHandler
}

func (m RecoverMiddleware) Handle(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if rec := recover(); r != nil {
				err := nextSkyerr.ErrorFromRecoveringPanic(rec)
				if m.RecoverHandler != nil {
					m.RecoverHandler(w, r, err)
				}
			}
		}()

		next.ServeHTTP(w, r)
	})
}

package middleware

import (
	"net/http"

	nextSkyerr "github.com/skygeario/skygear-server/pkg/core/skyerr"
	"github.com/skygeario/skygear-server/pkg/server/skyerr"
)

// RecoverHandler provides an interface to handle recovered panic error
type RecoverHandler func(http.ResponseWriter, *http.Request, skyerr.Error)

// RecoverMiddleware recover from panic
type RecoverMiddleware struct {
	RecoverHandler RecoverHandler
}

func (m RecoverMiddleware) Handle(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if rec := recover(); rec != nil {
				err := nextSkyerr.ErrorFromRecoveringPanic(rec)
				if m.RecoverHandler != nil {
					m.RecoverHandler(w, r, err)
				}
			}
		}()

		next.ServeHTTP(w, r)
	})
}

Fix wrong variable name in RecoverMiddleware


package nsqhandler

import (
	"sync"
	"time"

	"github.com/apex/log"
)

var start = time.Now()

type PublishFunc func(topic string, body []byte) error

type MarshalFunc func(x interface{}) ([]byte, error)

type Handler struct {
	mu          sync.Mutex
	marshalFunc MarshalFunc
	publishFunc PublishFunc
	topic       string
}

func New(marshalFunc MarshalFunc, publishFunc PublishFunc, topic string) *Handler {
	return &Handler{
		marshalFunc: marshalFunc,
		publishFunc: publishFunc,
		topic:       topic,
	}
}

func (h *Handler) HandleLog(e *log.Entry) error {
	h.mu.Lock()
	defer h.mu.Unlock()

	payload, err := h.marshalFunc(e)
	if err != nil {
		return err
	}
	h.publishFunc(h.topic, payload)

	return nil
}

package nsqhandler

import (
	"sync"
	"time"

	"github.com/apex/log"
)

var start = time.Now()

type PublishFunc func(topic string, body []byte) error

type MarshalFunc func(x interface{}) ([]byte, error)

type Handler struct {
	mu          sync.Mutex
	marshalFunc MarshalFunc
	publishFunc PublishFunc
	topic       string
}

func New(marshalFunc MarshalFunc, publishFunc PublishFunc, topic string) *Handler {
	return &Handler{
		marshalFunc: marshalFunc,
		publishFunc: publishFunc,
		topic:       topic,
	}
}

func (h *Handler) HandleLog(e *log.Entry) error {
	h.mu.Lock()
	defer h.mu.Unlock()

	payload, err := h.marshalFunc(e)
	if err != nil {
		return err
	}
	return h.publishFunc(h.topic, payload)
}

Return error in HandleLog from h.publishFunc


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

package backups

import (
	"github.com/juju/errors"

	"github.com/juju/juju/apiserver/params"
)

func (b *API) Info(args params.BackupsInfoArgs) (params.BackupsMetadataResult, error) {
	var result params.BackupsMetadataResult

	meta, _, err := b.backups.Get(args.ID)
	if err != nil {
		return result, errors.Trace(err)
	}

	result.UpdateFromMetadata(meta)

	return result, nil
}

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

package backups

import (
	"github.com/juju/errors"

	"github.com/juju/juju/apiserver/params"
)

// Info provides the implementation of the API method.
func (b *API) Info(args params.BackupsInfoArgs) (params.BackupsMetadataResult, error) {
	var result params.BackupsMetadataResult

	meta, _, err := b.backups.Get(args.ID)
	if err != nil {
		return result, errors.Trace(err)
	}

	result.UpdateFromMetadata(meta)

	return result, nil
}

Add a missing doc comment.


package data

// Definition stores information about a system, used for importing data.
type Definition struct {
	Title    string
	Type     string
	Env      string
	Location string
	User     string
	Password string
	URL      string
	Notes    string
	Tags     []string
}

// YamlData stores information about all systems, used for importing data.
type YamlData struct {
	Defs []Definition
}

// Config stores data about a system, used for exporting data.
type Config struct {
	ID          string `json:"id,"`
	Title       string `json:"title"`
	Location    string `json:"location"`
	Environment string `json:"environment"`
	User        string `json:"user"`
	Password    string `json:"password,omitempty"`
	Host        string `json:"host,omitempty"`
	IsValid     bool   `json:"valid"`
}

package data

// Definition stores information about a system, used for importing data.
type Definition struct {
	Title    string
	Type     string
	Env      string
	Location string
	User     string
	Password string
	URL      string
	Notes    string
	Tags     []string
}

// YamlData stores information about all systems, used for importing data.
type YamlData struct {
	Defs []Definition
}

// Config stores data about a system, used for exporting data.
type Config struct {
	ID          string `json:"id,"`
	Title       string `json:"title"`
	Location    string `json:"location"`
	Environment string `json:"environment"`
	User        string `json:"user"`
	Password    string `json:"password,omitempty"`
	Host        string `json:"host,omitempty"`
	IsValid     bool   `json:"-"`
}

Hide the „IsValid“ property in JSON


package xbmc

import (
	"github.com/streamboat/xbmc_jsonrpc"

	. "github.com/pdf/xbmc-callback-daemon/log"
)

// Execute takes an XBMC JSON-RPC Connection and a callback, and performs the
// RPC request contained in the callback
func Execute(x *xbmc_jsonrpc.Connection, callback map[string]interface{}) {
	Logger.Debug(`Sending request to XBMC: %v`, callback)

	req := xbmc_jsonrpc.Request{}
	req.Method = callback[`method`].(string)
	if callback[`params`] != nil {
		params := callback[`params`].(map[string]interface{})
		req.Params = &params
	}
	_ = x.Send(req, false)
}

package xbmc

import (
	"github.com/StreamBoat/xbmc_jsonrpc"

	. "github.com/pdf/xbmc-callback-daemon/log"
)

// Execute takes an XBMC JSON-RPC Connection and a callback, and performs the
// RPC request contained in the callback
func Execute(x *xbmc_jsonrpc.Connection, callback map[string]interface{}) {
	Logger.Debug(`Sending request to XBMC: %v`, callback)

	req := xbmc_jsonrpc.Request{}
	req.Method = callback[`method`].(string)
	if callback[`params`] != nil {
		params := callback[`params`].(map[string]interface{})
		req.Params = &params
	}
	_ = x.Send(req, false)
}

Fix import case for StreamBoat/xbmc_jsonrpc


package virtualboxclient

import (
	"github.com/appropriate/go-virtualboxclient/vboxwebsrv"
)

type Medium struct {
	managedObjectId string
}

func (svc *VirtualBoxClient) CreateHardDisk(format, location string) (*Medium, error) {
	svc.Logon()

	request := vboxwebsrv.IVirtualBoxcreateHardDisk{This: svc.managedObjectId, Format: format, Location: location}

	response, err := svc.client.IVirtualBoxcreateHardDisk(&request)
	if err != nil {
		return nil, err // TODO: Wrap the error
	}

	return &Medium{managedObjectId: response.Returnval}, nil
}

package virtualboxclient

import (
	"github.com/appropriate/go-virtualboxclient/vboxwebsrv"
)

type Medium struct {
	client          *vboxwebsrv.VboxPortType
	managedObjectId string
}

func (svc *VirtualBoxClient) CreateHardDisk(format, location string) (*Medium, error) {
	svc.Logon()

	request := vboxwebsrv.IVirtualBoxcreateHardDisk{This: svc.managedObjectId, Format: format, Location: location}

	response, err := svc.client.IVirtualBoxcreateHardDisk(&request)
	if err != nil {
		return nil, err // TODO: Wrap the error
	}

	return &Medium{client: svc.client, managedObjectId: response.Returnval}, nil
}

func (m *Medium) CreateBaseStorage(logicalSize int64, variant []*vboxwebsrv.MediumVariant) error {
	request := vboxwebsrv.IMediumcreateBaseStorage{This: m.managedObjectId, LogicalSize: logicalSize, Variant: variant}

	_, err := m.client.IMediumcreateBaseStorage(&request)
	if err != nil {
		return err // TODO: Wrap the error
	}

	// TODO: See if we need to do anything with the response
	return nil
}

func (m *Medium) DeleteStorage() error {
	request := vboxwebsrv.IMediumdeleteStorage{This: m.managedObjectId}

	_, err := m.client.IMediumdeleteStorage(&request)
	if err != nil {
		return err // TODO: Wrap the error
	}

	// TODO: See if we need to do anything with the response
	return nil
}

Add CreateBaseStorage and DeleteStorage to Medium


// Copyright 2015, Klaus Post, see LICENSE for details.

package mgopw

import (
	"testing"
	"time"

	"github.com/klauspost/password/drivers"
	"gopkg.in/mgo.v2"
)

// Test a Mongo database
func TestMongo(t *testing.T) {
	session, err := mgo.DialWithTimeout("127.0.0.1:27017", time.Second)
	if err != nil {
		t.Skip("No database: ", err)
	}
	coll := session.DB("testdb").C("password-test")
	_ = coll.DropCollection()

	db := New(session, "testdb", "password-test")
	err = drivers.TestImport(db)
	if err != nil {
		t.Fatal(err)
	}

	// Be sure data is flushed, probably not needed, but we like to be sure
	err = session.Fsync(false)
	if err != nil {
		t.Log("Fsync returned", err, "(ignoring)")
	}

	err = drivers.TestData(db)
	if err != nil {
		t.Fatal(err)
	}

	err = coll.DropCollection()
	if err != nil {
		t.Log("Drop returned", err, "(ignoring)")
	}
	session.Close()
}

// Copyright 2015, Klaus Post, see LICENSE for details.

package mgopw

import (
	"testing"
	"time"

	"github.com/klauspost/password/drivers"
	"gopkg.in/mgo.v2"
)

// Test a Mongo database
func TestMongo(t *testing.T) {
	session, err := mgo.DialWithTimeout("127.0.0.1:27017", time.Second)
	if err != nil {
		t.Skip("No database: ", err)
	}
	coll := session.DB("testdb").C("password-test")
	_ = coll.DropCollection()

	// Set timeout, otherwise travis sometimes gets timeout.
	session.SetSocketTimeout(time.Minute)
	session.SetSyncTimeout(time.Minute)

	db := New(session, "testdb", "password-test")
	err = drivers.TestImport(db)
	if err != nil {
		t.Fatal(err)
	}

	// Be sure data is flushed, probably not needed, but we like to be sure
	err = session.Fsync(false)
	if err != nil {
		t.Log("Fsync returned", err, "(ignoring)")
	}

	err = drivers.TestData(db)
	if err != nil {
		t.Fatal(err)
	}

	err = coll.DropCollection()
	if err != nil {
		t.Log("Drop returned", err, "(ignoring)")
	}
	session.Close()
}

Extend timeouts on Mongo sessions to avoid random CI failures.


package main

import (
	"github.com/marcusolsson/tui-go"
)

func main() {
	var currentView int

	views := []tui.Widget{
		tui.NewVBox(tui.NewLabel("Press right arrow to continue ...")),
		tui.NewVBox(tui.NewLabel("Almost there, one more time!")),
		tui.NewVBox(tui.NewLabel("Congratulations, you've finished the example!")),
	}

	root := tui.NewVBox(views[0])

	ui := tui.New(root)
	ui.SetKeybinding(tui.KeyEsc, func() { ui.Quit() })
	ui.SetKeybinding(tui.KeyArrowLeft, func() {
		currentView = clamp(currentView-1, 0, len(views)-1)
		ui.SetWidget(views[currentView])
	})
	ui.SetKeybinding(tui.KeyArrowRight, func() {
		currentView = clamp(currentView+1, 0, len(views)-1)
		ui.SetWidget(views[currentView])
	})

	if err := ui.Run(); err != nil {
		panic(err)
	}
}

func clamp(n, min, max int) int {
	if n < min {
		return min
	}
	if n > max {
		return max
	}
	return n
}

package main

import (
	"github.com/marcusolsson/tui-go"
)

func main() {
	var currentView int

	views := []tui.Widget{
		tui.NewVBox(tui.NewLabel("Press right arrow to continue ...")),
		tui.NewVBox(tui.NewLabel("Almost there, one more time!")),
		tui.NewVBox(tui.NewLabel("Congratulations, you've finished the example!")),
	}

	root := tui.NewVBox(views[0])

	ui := tui.New(root)
	ui.SetKeybinding("Esc", func() { ui.Quit() })
	ui.SetKeybinding("Left", func() {
		currentView = clamp(currentView-1, 0, len(views)-1)
		ui.SetWidget(views[currentView])
	})
	ui.SetKeybinding("Right", func() {
		currentView = clamp(currentView+1, 0, len(views)-1)
		ui.SetWidget(views[currentView])
	})

	if err := ui.Run(); err != nil {
		panic(err)
	}
}

func clamp(n, min, max int) int {
	if n < min {
		return min
	}
	if n > max {
		return max
	}
	return n
}

Update to new keybinding API


package api

import (
	api "github.com/diyan/assimilator/api/endpoints"

	"github.com/labstack/echo"
)

// RegisterAPIRoutes adds API routes to the Echo's route group
func RegisterAPIRoutes(g *echo.Group) {
	// Organizations
	g.GET("/organizations/", api.OrganizationIndexGetEndpoint)
	g.GET("/organizations/:organization_slug/", api.OrganizationDetailsGetEndpoint)

	// Projects
	g.GET("/projects/:organization_slug/:project_slug/environments/", api.ProjectEnvironmentsGetEndpoint)
	g.GET("/projects/:organization_slug/:project_slug/issues/", api.ProjectGroupIndexGetEndpoint)
	g.GET("/projects/:organization_slug/:project_slug/groups/", api.ProjectGroupIndexGetEndpoint)
	g.GET("/projects/:organization_slug/:project_slug/searches/", api.ProjectSearchesGetEndpoint)

	g.GET("/projects/:organization_slug/:project_slug/members/", api.ProjectMemberIndexGetEndpoint)
	g.GET("/projects/:organization_slug/:project_slug/tags/", api.ProjectTagsGetEndpoint)
	// Internal
	g.GET("/internal/health/", api.SystemHealthGetEndpoint)
}

package api

import (
	api "github.com/diyan/assimilator/api/endpoints"
	mw "github.com/diyan/assimilator/api/middleware"
	"github.com/labstack/echo"
)

// RegisterAPIRoutes adds API routes to the Echo's route group
func RegisterAPIRoutes(g *echo.Group) {
	// Organizations
	g.GET("/organizations/", api.OrganizationIndexGetEndpoint)
	g.GET("/organizations/:organization_slug/", api.OrganizationDetailsGetEndpoint)

	// Projects
	p := g.Group("/projects/:organization_slug/:project_slug")
	//p.Use(mw.RequireUser)
	p.Use(mw.RequireOrganization)
	p.Use(mw.RequireProject)
	p.GET("/environments/", api.ProjectEnvironmentsGetEndpoint)
	p.GET("/issues/", api.ProjectGroupIndexGetEndpoint)
	p.GET("/groups/", api.ProjectGroupIndexGetEndpoint)
	p.GET("/searches/", api.ProjectSearchesGetEndpoint)
	p.GET("/members/", api.ProjectMemberIndexGetEndpoint)
	p.GET("/tags/", api.ProjectTagsGetEndpoint)

	// Internal
	g.GET("/internal/health/", api.SystemHealthGetEndpoint)
}

Remove duplicated code from RegisterAPIRoutes


package app

import (
	"github.com/go-kit/kit/log"
	"github.com/goph/emperror"
)

// Service implements the RPC server
type Service struct {
	logger       log.Logger
	errorHandler emperror.Handler
}

// NewService creates a new service object
func NewService(logger log.Logger, errorHandler emperror.Handler) *Service {
	return &Service{logger, errorHandler}
}

package app

import (
	"github.com/go-kit/kit/log"
	"github.com/goph/emperror"
)

// Service implements the RPC server.
type Service struct {
	Logger       log.Logger
	ErrorHandler emperror.Handler
}

// NewService creates a new service object.
func NewService() *Service {
	return &Service{
		Logger:       log.NewNopLogger(),
		ErrorHandler: emperror.NewNullHandler(),
	}
}

Make logger and error handler optional


package caddycmd

import (
	"log"

	"bitbucket.org/lightcodelabs/caddy2"
)

// Main executes the main function of the caddy command.
func Main() {
	err := caddy2.StartAdmin("127.0.0.1:1234")
	if err != nil {
		log.Fatal(err)
	}
	defer caddy2.StopAdmin()

	select {}
}

package caddycmd

import (
	"log"

	"bitbucket.org/lightcodelabs/caddy2"
)

// Main executes the main function of the caddy command.
func Main() {
	addr := ":1234" // TODO: for dev only
	err := caddy2.StartAdmin(addr)
	if err != nil {
		log.Fatal(err)
	}
	defer caddy2.StopAdmin()

	log.Println("Caddy 2 admin endpoint listening on", addr)

	select {}
}

Change admin listener to :1234 for now; output message when listening


package dmm

// Base may not be needed, but the idea is that there are some functions that
// could be abstracted out to the general DMM.
type Base interface {
	DCVolts() (v float64, err error)
	ACVolts() (v float64, err error)
}

package dmm

// MeasurementFunction provides the defined values for the Measurement Function defined in
// Section 4.2.1 of IVI-4.2: IviDmm Class Specification.
type MeasurementFunction int

// The MeasurementFunction defined values are the available measurement functions.
const (
	DCVolts MeasurementFunction = iota
	ACVolts
	DCCurrent
	ACCurrent
	TwoWireResistance
	FourWireResistance
	ACPlusDCVolts
	ACPlusDCCurrent
	Frequency
	Period
	Temperature
)

var measurementFunctions = map[MeasurementFunction]string{
	DCVolts:            "DC Volts",
	ACVolts:            "AC Volts",
	DCCurrent:          "DC Current",
	ACCurrent:          "AC Current",
	TwoWireResistance:  "2-wire Resistance",
	FourWireResistance: "4-wire Resistance",
	ACPlusDCVolts:      "AC Plus DC Volts",
	ACPlusDCCurrent:    "AC Plus DC Current",
	Frequency:          "Frequency",
	Period:             "Period",
	Temperature:        "Temperature",
}

func (f MeasurementFunction) String() string {
	return measurementFunctions[f]
}

Add MeasurementFunction DMM defined values


package cmd

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"github.com/spf13/cobra"
)

func init() {
	RootCmd.AddCommand(searchCommand)
}

var searchCommand = &cobra.Command{
	Use:   "search TERM",
	Short: "Search for packages on Docker Hub",
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) < 1 {
			return cmd.Help()
		}
		if len(args) > 1 {
			return fmt.Errorf("Only one search term is supported")
		}

		cli, err := client.NewEnvClient()
		if err != nil {
			return err
		}

		term := "whalebrew/" + args[0]
		options := types.ImageSearchOptions{Limit: 100}
		results, err := cli.ImageSearch(context.Background(), term, options)
		if err != nil {
			return err
		}

		for _, res := range results {
			fmt.Println(res.Name)
		}

		return nil
	},
}

package cmd

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
	"github.com/spf13/cobra"
	"sort"
)

func init() {
	RootCmd.AddCommand(searchCommand)
}

var searchCommand = &cobra.Command{
	Use:   "search [TERM]",
	Short: "Search for packages on Docker Hub",
	Long:  "Search for Whalebrew packages on Docker Hub. If no search term is provided, all packages are listed.",
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) > 1 {
			return fmt.Errorf("Only one search term is supported")
		}

		cli, err := client.NewEnvClient()
		if err != nil {
			return err
		}

		term := "whalebrew/"
		if len(args) == 1 {
			term = term + args[0]
		}

		options := types.ImageSearchOptions{Limit: 100}
		results, err := cli.ImageSearch(context.Background(), term, options)
		if err != nil {
			return err
		}

		names := make([]string, len(results))
		for i, result := range results {
			names[i] = result.Name
		}
		sort.Strings(names)

		for _, name := range names {
			fmt.Println(name)
		}

		return nil
	},
}

Support for listing all packages


// +build !windows

package input

import (
	"os"
	"syscall"

	"github.com/elastic/libbeat/logp"
)

func IsSameFile(path string, info os.FileInfo, state *FileState) bool {
	fstat := info.Sys().(*syscall.Stat_t)

	return (fstat.Ino == state.Inode && fstat.Dev == state.Device)
}

// Checks if the two files are the same.
func (f1 *File) IsSameFile(f2 *File) bool {
	f1Stat := f1.FileInfo.Sys().(*syscall.Stat_t)
	f2Stat := f2.FileInfo.Sys().(*syscall.Stat_t)

	return compareFileStats(f1Stat, f2Stat)
}

// Compare file stats. Inode id and device are compared
func compareFileStats(s1 *syscall.Stat_t, s2 *syscall.Stat_t) bool {
	return (s1.Dev == s2.Dev && s1.Ino == s2.Ino)
}

// SafeFileRotate safely rotates an existing file under path and replaces it with the tempfile
func SafeFileRotate(path, tempfile string) error {
	if e := os.Rename(tempfile, path); e != nil {
		logp.Info("registry rotate: rename of %s to %s - %s", tempfile, path, e)
		return e
	}
	return nil
}

// +build !windows

package input

import (
	"os"
	"syscall"

	"github.com/elastic/libbeat/logp"
)

func IsSameFile(path string, info os.FileInfo, state *FileState) bool {
	fstat := info.Sys().(*syscall.Stat_t)

	return (fstat.Ino == state.Inode && fstat.Dev == state.Device)
}

// Checks if the two files are the same.
func (f1 *File) IsSameFile(f2 *File) bool {
	return os.SameFile(f1.FileInfo, f2.FileInfo)
}

// Compare file stats. Inode id and device are compared
func compareFileStats(s1 *syscall.Stat_t, s2 *syscall.Stat_t) bool {
	return (s1.Dev == s2.Dev && s1.Ino == s2.Ino)
}

// SafeFileRotate safely rotates an existing file under path and replaces it with the tempfile
func SafeFileRotate(path, tempfile string) error {
	if e := os.Rename(tempfile, path); e != nil {
		logp.Info("registry rotate: rename of %s to %s - %s", tempfile, path, e)
		return e
	}
	return nil
}

Use os.SameFile for file comparison


package consumergroup

import "testing"

func TestConfigValidate(t *testing.T) {
	conf := NewConfig()
	conf.ZkList = []string{}
	conf.TopicList = []string{}
	if err := conf.validate(); err == nil {
		t.Fatal("config invalidate is expected")
	}
	conf.ZkList = []string{"127.0.0.1:2181", "127.0.0.1:2181"}
	if err := conf.validate(); err == nil {
		t.Fatal("config invalidate is expected")
	}
	conf.TopicList = []string{"a", "a", "b", "c", "a"}
	if err := conf.validate(); err == nil {
		t.Fatal("config validate is expected")
	}
	conf.GroupID = "go-test-group"
	if err := conf.validate(); err == nil {
		t.Fatal("config invalidate is expected")
	}
	if len(conf.TopicList) != 3 {
		t.Fatal("config validate should remove duplicate topics")
	}
	if len(conf.ZkList) != 1 {
		t.Fatal("config validate should remove duplicate zk addresses")
	}
	if err := conf.validate(); err != nil {
		t.Fatalf("validate is expected, but got error %s", err)
	}
}

package consumergroup

import (
	"testing"
)

func TestConfigValidate(t *testing.T) {
	conf := NewConfig()
	conf.ZkList = []string{}
	conf.TopicList = []string{}
	if err := conf.validate(); err == nil {
		t.Fatal("config invalidate is expected")
	}
	conf.ZkList = []string{"127.0.0.1:2181", "127.0.0.1:2181"}
	if err := conf.validate(); err == nil {
		t.Fatal("config invalidate is expected")
	}
	conf.TopicList = []string{"a", "a", "b", "c", "a"}
	if err := conf.validate(); err == nil {
		t.Fatal("config validate is expected")
	}
	conf.GroupID = "go-test-group"
	if err := conf.validate(); err != nil {
		t.Fatalf("validate is expected, but got error %s", err)
	}
	if len(conf.TopicList) != 3 {
		t.Fatal("config validate should remove duplicate topics")
	}
	if len(conf.ZkList) != 1 {
		t.Fatal("config validate should remove duplicate zk addresses")
	}
}

Fix config unit test failed


package core

// Writer describes an object that tuples can be written to
// as the output for a Box. Note that this interface was chosen
// because it also allows a Box to write multiple (or none)
// output tuples. It is expected that the ctx pointer passed in
// points to the same Context that was used by the Box that
// called Write.
type Writer interface {
	Write(ctx *Context, t *Tuple) error
}

// WriteCloser add a capability of closing to Writer.
type WriteCloser interface {
	Writer

	// Close closes the writer. An appropriate Context should be given,
	// which is usually provided by Topology. Close doesn't have to be
	// idempotent.
	Close(ctx *Context) error
}

type writerFunc func(ctx *Context, t *Tuple) error

// WriterFunc creates a Writer from a function.
func WriterFunc(f func(ctx *Context, t *Tuple) error) Writer {
	return writerFunc(f)
}

func (w writerFunc) Write(ctx *Context, t *Tuple) error {
	return w(ctx, t)
}

Add WriterFunc to convert a function to core.Writer


package main

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

func main() {
	word := os.Args[1]
	if len(os.Args) != 2 {
		fmt.Println("Exactly one argument is required")
		os.Exit(1)
	}
	s := strings.Split(word, "")
	generatePermutations(len(word)-1, s)
}

func generatePermutations(n int, a []string) {
	if n == 0 {
		fmt.Println(strings.Join(a, ""))
	} else {
		for i := 0; i <= n; i++ {
			generatePermutations(n-1, a)
			if n%2 == 0 {
				a[i], a[n] = a[n], a[i]
			} else {
				a[0], a[n] = a[n], a[0]
			}
		}
	}
}

package main

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

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Exactly one argument is required")
		os.Exit(1)
	}
	word := os.Args[1]
	generatePermutations(len(word)-1, strings.Split(word, ""))
}

func generatePermutations(n int, a []string) {
	if n == 0 {
		fmt.Println(strings.Join(a, ""))
	} else {
		for i := 0; i <= n; i++ {
			generatePermutations(n-1, a)
			if n % 2 == 0 {
				a[i], a[n] = a[n], a[i]
			} else {
				a[0], a[n] = a[n], a[0]
			}
		}
	}
}

Check that there are command line args before accessing


package prgs

// Prg is a Program, with all its data (no behavior)
type prg struct {
	name string
}

// Prg defines what kind of service a program has to provide
type Prg interface {
	// Name is the name of a program to install, acts as an id
	Name() string
}

// PGetter gets programs (from an internal config)
type PGetter interface {
	Get() []Prg
}

type defaultGetter struct{}

var dg defaultGetter
var getter PGetter

func init() {
	dg = defaultGetter{}
	getter = dg
}
func (df defaultGetter) Get() []Prg {
	return []Prg{}
}

// Getter returns a object able to get a list of Prgs
func Getter() PGetter {
	return getter
}

func (p *prg) Name() string {
	return p.name
}

package prgs

import "github.com/VonC/senvgo/envs"
import "github.com/VonC/senvgo/paths"

// Prg is a Program, with all its data (no behavior)
type prg struct {
	name string
}

// Prg defines what kind of service a program has to provide
type Prg interface {
	// Name is the name of a program to install, acts as an id
	Name() string
}

// PGetter gets programs (from an internal config)
type PGetter interface {
	Get() []Prg
}

type defaultGetter struct{}

var dg defaultGetter
var getter PGetter
var _prgs []Prg

func init() {
	dg = defaultGetter{}
	getter = dg
}
func (df defaultGetter) Get() []Prg {
	if _prgs != nil && len(_prgs) > 0 {
		return _prgs
	}
	var p *paths.Path
	p = envs.Prgsenv()
	p.Add("")
	return []Prg{}
}

// Getter returns a object able to get a list of Prgs
func Getter() PGetter {
	return getter
}

func (p *prg) Name() string {
	return p.name
}

Add Prgs Get() starts using envs.Prgsenv()


package github

type User struct {
	Id    int    `json:"id"`
	Login string `json:"login"`
}

package github

type User struct {
	ID    int    `json:"id"`
	Login string `json:"login"`
}

Rename Id field to ID


package image

import (
	"github.com/Symantec/Dominator/lib/filesystem"
	"github.com/Symantec/Dominator/lib/filter"
	"github.com/Symantec/Dominator/lib/triggers"
)

type Image struct {
	Filter     *filter.Filter
	FileSystem *filesystem.FileSystem
	Triggers   *triggers.Triggers
}

package image

import (
	"github.com/Symantec/Dominator/lib/filesystem"
	"github.com/Symantec/Dominator/lib/filter"
	"github.com/Symantec/Dominator/lib/hash"
	"github.com/Symantec/Dominator/lib/triggers"
)

type Annotation struct {
	Object *hash.Hash // These are mutually exclusive.
	URL    string
}

type Image struct {
	Filter       *filter.Filter
	FileSystem   *filesystem.FileSystem
	Triggers     *triggers.Triggers
	ReleaseNotes *Annotation
	BuildLog     *Annotation
}

Add ReleaseNotes and BuildLog fields to image.Image.


package web

import (
	"github.com/control-center/serviced/dao"
	rest "github.com/zenoss/go-json-rest"
)

type EmergencyShutdownRequest struct {
	Operation int // 0 is emergency shutdown, 1 is clear emergency shutdown status
	TenantID  string
}

func restEmergencyShutdown(w *rest.ResponseWriter, r *rest.Request, ctx *requestContext) {
	req := EmergencyShutdownRequest{}
	err := r.DecodeJsonPayload(&req)
	if err != nil {
		plog.WithError(err).Error("Could not decode json payload for emergency shutdown request")
		restBadRequest(w, err)
		return
	}

	daoReq := dao.ScheduleServiceRequest{
		ServiceID:   req.TenantID,
		AutoLaunch:  true,
		Synchronous: false,
	}

	n, err := ctx.getFacade().EmergencyStopService(ctx.getDatastoreContext(), daoReq)
	if err != nil {
		plog.WithError(err).Error("Facade could not process Emergency Shutdown Request")
		restBadRequest(w, err)
		return
	}
	plog.Infof("Scheduled %d services", n)
	restSuccess(w)
}

package web

import (
	"github.com/control-center/serviced/dao"
	rest "github.com/zenoss/go-json-rest"
)

type EmergencyShutdownRequest struct {
	Operation int // 0 is emergency shutdown, 1 is clear emergency shutdown status
	TenantID  string
}

func restEmergencyShutdown(w *rest.ResponseWriter, r *rest.Request, ctx *requestContext) {
	req := EmergencyShutdownRequest{}
	err := r.DecodeJsonPayload(&req)
	if err != nil {
		plog.WithError(err).Error("Could not decode json payload for emergency shutdown request")
		restBadRequest(w, err)
		return
	}

	daoReq := dao.ScheduleServiceRequest{
		ServiceID:   req.TenantID,
		AutoLaunch:  true,
		Synchronous: false,
	}

	go ctx.getFacade().EmergencyStopService(ctx.getDatastoreContext(), daoReq)
	restSuccess(w)
}

Update to emergency shutdown endpoint for tests


package main

import (
	"testing"

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

func TestUnderscoreCaseName(t *testing.T) {
	assert.Equal(t, "notify_event", underscoreCaseName("NotifyEvent"))
	assert.Equal(t, "repository", underscoreCaseName("Repository"))
	assert.Equal(t, "http_server", underscoreCaseName("HTTPServer"))
	assert.Equal(t, "awesome_http_server", underscoreCaseName("AwesomeHTTPServer"))
	assert.Equal(t, "csv", underscoreCaseName("CSV"))
	assert.Equal(t, "position0_size", underscoreCaseName("Position0Size"))
}

func TestFilenameBare(t *testing.T) {
	assert.Equal(t, "name.go", filename("name", Config{fIP: false, fTO: false}))
}

func TestFilenameMockOnly(t *testing.T) {
	assert.Equal(t, "mock_name.go", filename("name", Config{fIP: true, fTO: false}))
}

func TestFilenameMockTest(t *testing.T) {
	assert.Equal(t, "mock_name_test.go", filename("name", Config{fIP: true, fTO: true}))
}

func TestFilenameTest(t *testing.T) {
	assert.Equal(t, "name.go", filename("name", Config{fIP: false, fTO: true}))
}

Add tests around filename function. Leaving bug.


package main

import (
	"time"
)

type Bus struct {
	queue chan *Message
}

type Subscriber interface {
	onMessage(message *Message) error
}

var MessageBus = &Bus{
	queue: make(chan *Message),
}

func (b Bus) Publish(message *Message) {
	b.queue <- message
}

func (b Bus) Subscribe(subscriber Subscriber) {
	go func() {
		for {
			message := <-b.queue

			// To comply with API rate limit requirement
			done := make(chan interface{}, 1)
			go func() {
				done <- time.After(1 * time.Second)
			}()

			err := subscriber.onMessage(message)
			message.Result <- err

			<-done
		}
	}()
}

package main

import (
	"time"
)

type Bus struct {
	queue chan *Message
}

type Subscriber interface {
	onMessage(message *Message) error
}

var MessageBus = &Bus{
	queue: make(chan *Message),
}

func (b Bus) Publish(message *Message) {
	b.queue <- message
}

func (b Bus) Subscribe(subscriber Subscriber) {
	go func() {
		for {
			message := <-b.queue

			// To comply with API rate limit requirement
			// https://api.slack.com/docs/rate-limits
			done := make(chan interface{}, 1)
			go func() {
				done <- time.After(1 * time.Second)
			}()

			err := subscriber.onMessage(message)
			message.Result <- err

			<-done
		}
	}()
}

Add URL of API limit doc


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

// Package number formats numbers according to the customs of different locales.
//
// The number formats of this package allow for greater formatting flexibility
// than passing values to message.Printf calls as is. It currently supports the
// builtin Go types and anything that implements the Convert interface
// (currently internal).
//
//    p := message.NewPrinter(language.English)
//
//    p.Printf("%v bottles of beer on the wall.", number.Decimal(1234))
//    // Prints: 1,234 bottles of beer on the wall.
//
//    p.Printf("%v of gophers lose too much fur", number.Percent(0.12))
//    // Prints: 12% of gophers lose too much fur.
//
//    p := message.NewPrinter(language.Dutch)
//
//    p.Printf("Er zijn %v fietsen per huishouden.", number.Decimal(1.2))
//    // Prints: Er zijn 1,2 fietsen per huishouden.
//
//
// The width and scale specified in the formatting directives override the
// configuration of the formatter.
package number

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

// Package number formats numbers according to the customs of different locales.
//
// The number formats of this package allow for greater formatting flexibility
// than passing values to message.Printf calls as is. It currently supports the
// builtin Go types and anything that implements the Convert interface
// (currently internal).
//
//    p := message.NewPrinter(language.English)
//
//    p.Printf("%v bottles of beer on the wall.", number.Decimal(1234))
//    // Prints: 1,234 bottles of beer on the wall.
//
//    p.Printf("%v of gophers lose too much fur", number.Percent(0.12))
//    // Prints: 12% of gophers lose too much fur.
//
//    p := message.NewPrinter(language.Dutch)
//
//    p.Printf("There are %v bikes per household.", number.Decimal(1.2))
//    // Prints: Er zijn 1,2 fietsen per huishouden.
//
//
// The width and scale specified in the formatting directives override the
// configuration of the formatter.
package number

Revert "number: match input example to be Dutch as in the output"


package main

import (
	"flag"
	"log"
	"net"
	"os"

	"github.com/sirupsen/logrus"
)

func main() {
	configFileName := flag.String("config", "", "config file")
	flag.Parse()

	cfg, err := getConfig(*configFileName)
	if err != nil {
		log.Fatalln("Failed to get config:", err)
	}

	sshServerConfig := cfg.createSSHServerConfig()

	listener, err := net.Listen("tcp", cfg.ListenAddress)
	if err != nil {
		log.Fatalln("Failed to listen for connections:", err)
	}
	defer listener.Close()

	logrus.SetOutput(os.Stdout)

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("Failed to accept connection:", err)
			continue
		}
		logrus.WithFields(logrus.Fields{"remote_address": conn.RemoteAddr().String()}).Infoln("Connection accepted")
		go handleConnection(conn, sshServerConfig)
	}
}

package main

import (
	"flag"
	"log"
	"net"
	"os"

	"github.com/sirupsen/logrus"
)

func main() {
	configFileName := flag.String("config", "", "config file")
	jsonLogging := flag.Bool("json_logging", false, "enable JSON logging")
	flag.Parse()

	cfg, err := getConfig(*configFileName)
	if err != nil {
		log.Fatalln("Failed to get config:", err)
	}

	sshServerConfig := cfg.createSSHServerConfig()

	listener, err := net.Listen("tcp", cfg.ListenAddress)
	if err != nil {
		log.Fatalln("Failed to listen for connections:", err)
	}
	defer listener.Close()

	logrus.SetOutput(os.Stdout)
	if *jsonLogging {
		logrus.SetFormatter(&logrus.JSONFormatter{})
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("Failed to accept connection:", err)
			continue
		}
		logrus.WithFields(logrus.Fields{"remote_address": conn.RemoteAddr().String()}).Infoln("Connection accepted")
		go handleConnection(conn, sshServerConfig)
	}
}

Add the -json_logging flag to enable logging in JSON


package puddle

import (
	"bufio"
	"fmt"
	"github.com/nlopes/slack"
	"os"
)

// RunCLI Starts the command line input shell
func RunCLI() {
	fmt.Println("Starting Puddle CLI Input...\n")
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Print("Puddle> ")
	for scanner.Scan() {
		line := scanner.Text()
		msg := slack.Msg{
			Text: line,
		}
		ProcessMessage(msg)
		fmt.Print("Puddle> ")
	}
}

// RunCLI Prints to CLI
func PrintCLI(text string) {
	fmt.Print("Puddle> ")
}

Fix up comments & delete redundant function


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

package plugin

import (
	"encoding/json"

	"github.com/juju/errors"
)

// LaunchDetails represents information about a process launched by a plugin.
type LaunchDetails struct {
	// ID is a unique string identifying the process to the plugin.
	ID string `json:"id"`
	// Status is the plugin-defined status of the process after launch.
	Status
}

func UnmarshalDetails(b []byte) (LaunchDetails, error) {
	var details LaunchDetails
	if err := json.Unmarshal(b, &details); err != nil {
		return details, errors.Annotate(err, "error parsing data for procdetails")
	}
	if err := details.Validate(); err != nil {
		return details, errors.Annotate(err, "invalid procdetails")
	}
	return details, nil

}

// Validate returns nil if this value is valid, and an error that satisfies
// IsValid if it is not.
func (p LaunchDetails) Validate() error {
	if p.ID == "" {
		e := errors.NewErr("ID cannot be empty")
		return validationErr{&e}
	}
	return p.Status.Validate()
}

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

package plugin

import (
	"encoding/json"

	"github.com/juju/errors"
)

// LaunchDetails represents information about a process launched by a plugin.
type LaunchDetails struct {
	// ID is a unique string identifying the process to the plugin.
	ID string `json:"id"`
	// Status is the plugin-defined status of the process after launch.
	Status
}

// UnmarshalDetails de-serialized the provided data into a LaunchDetails.
func UnmarshalDetails(b []byte) (LaunchDetails, error) {
	var details LaunchDetails
	if err := json.Unmarshal(b, &details); err != nil {
		return details, errors.Annotate(err, "error parsing data for procdetails")
	}
	if err := details.Validate(); err != nil {
		return details, errors.Annotate(err, "invalid procdetails")
	}
	return details, nil

}

// Validate returns nil if this value is valid, and an error that satisfies
// IsValid if it is not.
func (p LaunchDetails) Validate() error {
	if p.ID == "" {
		e := errors.NewErr("ID cannot be empty")
		return validationErr{&e}
	}
	return p.Status.Validate()
}

Add a missing doc comment.


package proof

import (
	"bytes"
	"ioutil"
	"testing"
)

func TestCRC(t *testing.T) {
	data := []byte("Hello, World!")
	cases := []struct {
		csum uint32
		err  error
	}{
		{0xec4ac3d0, nil},
		{0xdeadbeef, EHASHFAIL},
	}

	for _, c := range cases {
		buf := bytes.Buffer(data)
		h := crc32.NewIEEE()
		r = NewReader32(buf, h, csum)

		_, err := ioutil.ReadAll(r)
		if err != c.err {
			t.Fatalf("expected error %v, got %v", c.err, err)
		}
	}
}

package proof

import (
	"bytes"
	"hash/crc32"
	"io/ioutil"
	"testing"
)

func TestCRC(t *testing.T) {
	data := []byte("Hello, World!")
	cases := []struct {
		csum uint32
		err  error
	}{
		{0xec4ac3d0, nil},
		{0xdeadbeef, EHASHFAIL},
	}

	for _, c := range cases {
		buf := bytes.NewBuffer(data)
		h := crc32.NewIEEE()
		r := NewReader32(buf, h, c.csum)

		_, err := ioutil.ReadAll(r)
		if err != c.err {
			t.Fatalf("expected error: %v, got: %v", c.err, err)
		}
	}
}

Fix bugs in test case


// +build linux darwin openbsd freebsd netbsd

package main

const EXITERS = "EOF (Ctrl-D), or SIGINT (Ctrl-C)"

// +build !windows
// +build !plan9

package main

const EXITERS = "EOF (Ctrl-D), or SIGINT (Ctrl-C)"

Exclude the different OSes instead of trying to list all the 'normal' ones


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

package ebiten

import "github.com/hajimehoshi/ebiten/v2/internal/driver"

// A CursorModeType represents
// a render and coordinate mode of a mouse cursor.
type CursorModeType int

// Cursor Modes
const (
	CursorModeVisible  = CursorModeType(driver.CursorModeVisible)
	CursorModeHidden   = CursorModeType(driver.CursorModeHidden)
	CursorModeCaptured = CursorModeType(driver.CursorModeCaptured)
)

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

package ebiten

import "github.com/hajimehoshi/ebiten/v2/internal/driver"

// CursorModeType represents
// a render and coordinate mode of a mouse cursor.
type CursorModeType int

const (
	CursorModeVisible  CursorModeType = CursorModeType(driver.CursorModeVisible)
	CursorModeHidden   CursorModeType = CursorModeType(driver.CursorModeHidden)
	CursorModeCaptured CursorModeType = CursorModeType(driver.CursorModeCaptured)
)

Add an explicit type to CursorModeType consts for pkg.go.dev


package reporters

import (
	"os/exec"

	"github.com/approvals/go-approval-tests/utils"
)

// NewFrontLoadedReporter creates the default front loaded reporter.
func NewFrontLoadedReporter() Reporter {
	return NewFirstWorkingReporter(
		NewContinuousIntegrationReporter(),
	)
}

// NewDiffReporter creates the default diff reporter.
func NewDiffReporter() Reporter {
	return NewFirstWorkingReporter(
		NewBeyondCompareReporter(),
		NewIntelliJReporter(),
		NewFileMergeReporter(),
		NewVSCodeReporter(),
		NewGoLandReporter(),
		NewPrintSupportedDiffProgramsReporter(),
		NewQuietReporter(),
	)
}

func launchProgram(programName, approved string, args ...string) bool {
	if !utils.DoesFileExist(programName) {
		return false
	}

	utils.EnsureExists(approved)

	cmd := exec.Command(programName, args...)
	cmd.Start()
	return true
}

package reporters

import (
	"os/exec"

	"github.com/approvals/go-approval-tests/utils"
)

// NewFrontLoadedReporter creates the default front loaded reporter.
func NewFrontLoadedReporter() Reporter {
	return NewFirstWorkingReporter(
		NewContinuousIntegrationReporter(),
	)
}

// NewDiffReporter creates the default diff reporter.
func NewDiffReporter() Reporter {
	return NewFirstWorkingReporter(
		NewBeyondCompareReporter(),
		NewIntelliJReporter(),
		NewFileMergeReporter(),
		NewVSCodeReporter(),
		NewGoLandReporter(),
		NewRealDiffReporter(),
		NewPrintSupportedDiffProgramsReporter(),
		NewQuietReporter(),
	)
}

func launchProgram(programName, approved string, args ...string) bool {
	if !utils.DoesFileExist(programName) {
		return false
	}

	utils.EnsureExists(approved)

	cmd := exec.Command(programName, args...)
	cmd.Start()
	return true
}

Add real diff reporter to list of defaults


package ir

import (
	"testing"

	"github.com/tisp-lang/tisp/src/lib/core"
)

func TestNewSwitch(t *testing.T) {
	NewSwitch(0, []Case{NewCase(core.Nil, 1)})
}

func TestNewSwitchNoPattern(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Fail()
		}
	}()

	NewSwitch(0, []Case{})
}

func TestSwitchCompileToDict(t *testing.T) {
	NewSwitch(0, []Case{NewCase(core.Nil, 1)}).compileToDict()
}

package ir

import (
	"testing"

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

func TestNewSwitch(t *testing.T) {
	NewSwitch(0, []Case{NewCase(core.Nil, 1)})
}

func TestNewSwitchNoPattern(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Fail()
		}
	}()

	NewSwitch(0, []Case{})
}

func TestSwitchCompileToDict(t *testing.T) {
	NewSwitch(0, []Case{NewCase(core.Nil, 1)}).compileToDict()
}

func TestSwitchInFunction(t *testing.T) {
	f := CompileFunction(
		core.NewSignature([]string{"x"}, nil, "", nil, nil, ""),
		nil,
		NewSwitch(0, []Case{
			NewCase(core.NewString("foo"), core.NewNumber(42)),
			NewCase(core.True, core.NewNumber(2049)),
		}))

	assert.Equal(t, 42.0, float64(core.PApp(f, core.NewString("foo")).Eval().(core.NumberType)))
	assert.Equal(t, 2049.0, float64(core.PApp(f, core.True).Eval().(core.NumberType)))
}

Test switch expression in a function


package logger

import (
	"fmt"
	"testing"
)

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

	tests := []struct {
		lvl      LogLevel
		expected string
	}{
		{Debug, "Debug"},
		{Thumb, "Thumb"},
		{Info, "Info"},
		{Warn, "Warn"},
		{Error, "Error"},
		{Fatal, "Fatal"},
	}

	for _, test := range tests {
		got := test.lvl.String()
		if got != test.expected {
			t.Fatalf("Expected Loglevel %d to return %s, but got %s", int(test.lvl),
				test.expected, got)
		}
	}
}

func TestNewLogLevel(t *testing.T) {
	oldLogLevelNames := logLevelNames
	oldLogLevelIndices := logLevelIndices

	for i := 1; i <= 248; i++ {
		expected := fmt.Sprintf("myLogLevel%d", i)
		myLogLevel := NewLogLevel(expected)

		if got := myLogLevel.String(); got != expected {
			t.Fatalf("Expected Loglevel %d to return %s, but got %s", int(myLogLevel),
				expected, got)
		}
	}

	logLevelNames = oldLogLevelNames
	logLevelIndices = oldLogLevelIndices
}

package logger

import (
	"fmt"
	"testing"
)

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

	tests := []struct {
		lvl      LogLevel
		expected string
	}{
		{Debug, "Debug"},
		{Thumb, "Thumb"},
		{Info, "Info"},
		{Warn, "Warn"},
		{Error, "Error"},
		{Fatal, "Fatal"},
	}

	for _, test := range tests {
		got, gotBytes := test.lvl.String(), test.lvl.Bytes()

		if got != string(gotBytes) {
			t.Errorf("LogLevel.Bytes() and String() don't return the same value, got %q"+
				" and %q, want %q", got, string(gotBytes), test.expected)
		} else if got != test.expected {
			t.Errorf("Expected LogLevel.String() to return %q, got %q",
				test.expected, got)
		}
	}
}

func TestNewLogLevel(t *testing.T) {
	oldLogLevelNames := logLevelNames
	oldLogLevelIndices := logLevelIndices

	for i := 1; i <= 248; i++ {
		expected := fmt.Sprintf("myLogLevel%d", i)
		myLogLevel := NewLogLevel(expected)

		if got := myLogLevel.String(); got != expected {
			t.Fatalf("Expected Loglevel %d to return %s, but got %s", int(myLogLevel),
				expected, got)
		}
	}

	logLevelNames = oldLogLevelNames
	logLevelIndices = oldLogLevelIndices
}

Test both LogLevel.String and .Bytes


package server

import (
	"log"
	"net/http"
	"net/url"

	"github.com/bmorton/deployster/fleet"
)

type UnitsResource struct {
	Fleet fleet.Client
}

type UnitsResponse struct {
	Units []VersionedUnit `json:"units"`
}

func (ur *UnitsResource) Index(u *url.URL, h http.Header, req interface{}) (int, http.Header, *UnitsResponse, error) {
	statusCode := http.StatusOK
	response := &UnitsResponse{}

	units, err := ur.Fleet.Units()
	if err != nil {
		log.Printf("%#v\n", err)
		return http.StatusInternalServerError, nil, nil, err
	}
	response.Units = FindServiceUnits(u.Query().Get("name"), units)

	return statusCode, nil, response, nil
}

package server

import (
	"log"
	"net/http"
	"net/url"

	"github.com/bmorton/deployster/fleet"
)

// UnitsResource is the HTTP resource responsible for getting basic information
// on all units that exist for a given service.
type UnitsResource struct {
	Fleet fleet.Client
}

// UnitsResponse is the wrapper struct for the JSON payload returned by the
// Index action.
type UnitsResponse struct {
	Units []VersionedUnit `json:"units"`
}

// Index is the GET endpoint for listing all units that exist for a given
// service.
//
// This function assumes that it is nested inside `/services/{name}`
// and that Tigertonic is extracting the service name and providing it via query
// params.
func (ur *UnitsResource) Index(u *url.URL, h http.Header, req interface{}) (int, http.Header, *UnitsResponse, error) {
	statusCode := http.StatusOK
	response := &UnitsResponse{}

	units, err := ur.Fleet.Units()
	if err != nil {
		log.Printf("%#v\n", err)
		return http.StatusInternalServerError, nil, nil, err
	}
	response.Units = FindServiceUnits(u.Query().Get("name"), units)

	return statusCode, nil, response, nil
}

Add documentation for UnitsResource in the server package.


// Package main provide one-line integration with letsencrypt.org
package main

import (
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
)

func main() {
	app := iris.New()

	app.Get("/", func(ctx context.Context) {
		ctx.Writef("Hello from SECURE SERVER!")
	})

	app.Get("/test2", func(ctx context.Context) {
		ctx.Writef("Welcome to secure server from /test2!")
	})

	app.Get("/redirect", func(ctx context.Context) {
		ctx.Redirect("/test2")
	})

	// NOTE: This may not work on local addresses like this,
	// use it on a real domain, because
	// it uses the 	"golang.org/x/crypto/acme/autocert" package.
	app.Run(iris.AutoTLS("localhost:443"))
}

// Package main provide one-line integration with letsencrypt.org
package main

import (
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
)

func main() {
	app := iris.New()

	app.Get("/", func(ctx context.Context) {
		ctx.Writef("Hello from SECURE SERVER!")
	})

	app.Get("/test2", func(ctx context.Context) {
		ctx.Writef("Welcome to secure server from /test2!")
	})

	app.Get("/redirect", func(ctx context.Context) {
		ctx.Redirect("/test2")
	})

	// NOTE: This will not work on domains like this,
	// use real whitelisted domain(or domains split by whitespaces)
	// and a non-public e-mail instead.
	app.Run(iris.AutoTLS(":443", "example.com", "mail@example.com"))
}

Update `iris.AutoTLS` example, read description.


// Command test_serviced is an implementation of the test_service service.
package main

import (
	"fmt"
	"log"

	"veyron.io/veyron/veyron/lib/signals"
	_ "veyron.io/veyron/veyron/profiles"
	"veyron.io/veyron/veyron2/rt"
)

func main() {
	// Create the runtime
	r := rt.Init()
	defer r.Cleanup()

	s, endpoint, err := StartServer(r)
	if err != nil {
		log.Fatal("", err)
	}
	defer s.Stop()

	fmt.Printf("Listening at: %v\n", endpoint)
	<-signals.ShutdownOnSignals()
}

// Command test_serviced is an implementation of the test_service service.
package main

import (
	"fmt"
	"log"

	"veyron.io/veyron/veyron/lib/signals"
	_ "veyron.io/veyron/veyron/profiles"
	"veyron.io/veyron/veyron2/rt"
)

func main() {
	// Create the runtime
	r := rt.Init()
	defer r.Cleanup()

	s, endpoint, err := StartServer(r)
	if err != nil {
		log.Fatal("", err)
	}
	defer s.Stop()

	fmt.Printf("Listening at: %v\n", endpoint)
	<-signals.ShutdownOnSignals(r)
}

Add runtime arg to ShutdownOnSignals.


package server

import (
	"fmt"
	"github.com/Frostman/aptomi/pkg/slinga"
	"net/http"
)

func endpointsHandler(w http.ResponseWriter, r *http.Request) {
	// Load the previous usage state
	state := slinga.LoadServiceUsageState()

	endpoints := state.Endpoints()

	writeJSON(w, endpoints)
}

func Serve(host string, port int) {
	// redirect from "/" to "/ui/"
	http.Handle("/", http.RedirectHandler("/ui/", http.StatusPermanentRedirect))

	// serve all files from "webui" folder and require auth for everything except login.html
	http.Handle("/ui/", staticFilesHandler("/ui/", http.Dir("./webui/")))

	// serve all API endpoints at /api/ path and require auth
	http.Handle("/api/endpoints", requireAuth(endpointsHandler))

	// serve login/logout api without auth
	http.HandleFunc("/api/login", loginHandler)
	http.HandleFunc("/api/logout", logoutHandler)

	listenAddr := fmt.Sprintf("%s:%d", host, port)
	fmt.Println("Serving at", listenAddr)
	// todo better handle error returned from ListenAndServe (path to Fatal??)
	panic(http.ListenAndServe(listenAddr, nil))
}

package server

import (
	"fmt"
	"github.com/Frostman/aptomi/pkg/slinga"
	"net/http"
)

func endpointsHandler(w http.ResponseWriter, r *http.Request) {
	// Load the previous usage state
	state := slinga.LoadServiceUsageState()

	endpoints := state.Endpoints()

	writeJSON(w, endpoints)
}

// Serve starts http server on specified address that serves Aptomi API and WebUI
func Serve(host string, port int) {
	// redirect from "/" to "/ui/"
	http.Handle("/", http.RedirectHandler("/ui/", http.StatusPermanentRedirect))

	// serve all files from "webui" folder and require auth for everything except login.html
	http.Handle("/ui/", staticFilesHandler("/ui/", http.Dir("./webui/")))

	// serve all API endpoints at /api/ path and require auth
	http.Handle("/api/endpoints", requireAuth(endpointsHandler))

	// serve login/logout api without auth
	http.HandleFunc("/api/login", loginHandler)
	http.HandleFunc("/api/logout", logoutHandler)

	listenAddr := fmt.Sprintf("%s:%d", host, port)
	fmt.Println("Serving at", listenAddr)
	// todo better handle error returned from ListenAndServe (path to Fatal??)
	panic(http.ListenAndServe(listenAddr, nil))
}

Fix warning from go lint


// Copyright 2018 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.

package manager

import (
	"context"
	"fmt"

	"google.golang.org/grpc"

	"openpitrix.io/openpitrix/pkg/logger"
)

func NewClient(ctx context.Context, host string, port int) (*grpc.ClientConn, error) {
	endpoint := fmt.Sprintf("%s:%d", host, port)
	conn, err := grpc.Dial(endpoint, grpc.WithInsecure())
	if err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			if cerr := conn.Close(); cerr != nil {
				logger.Error("Failed to close conn to %s: %v", endpoint, cerr)
			}
			return
		}
		go func() {
			<-ctx.Done()
			if cerr := conn.Close(); cerr != nil {
				logger.Error("Failed to close conn to %s: %v", endpoint, cerr)
			}
		}()
	}()
	return conn, err
}

// Copyright 2018 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.

package manager

import (
	"context"
	"fmt"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/keepalive"

	"openpitrix.io/openpitrix/pkg/logger"
)

func NewClient(ctx context.Context, host string, port int) (*grpc.ClientConn, error) {
	endpoint := fmt.Sprintf("%s:%d", host, port)
	conn, err := grpc.DialContext(ctx, endpoint,
		grpc.WithInsecure(), grpc.WithKeepaliveParams(keepalive.ClientParameters{
			Time:                10 * time.Second,
			Timeout:             5 * time.Second,
			PermitWithoutStream: true,
		}))
	if err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			if cerr := conn.Close(); cerr != nil {
				logger.Error("Failed to close conn to %s: %v", endpoint, cerr)
			}
			return
		}
		go func() {
			<-ctx.Done()
			if cerr := conn.Close(); cerr != nil {
				logger.Error("Failed to close conn to %s: %v", endpoint, cerr)
			}
		}()
	}()
	return conn, err
}

Optimize gRPC connection keepalive between services


package run

import (
	"gopkg.in/workanator/go-floc.v2"
)

const locRepeat = "Repeat"

/*
Repeat repeats running jobs for N times. Jobs start sequentially.

Summary:
	- Run jobs in goroutines : NO
	- Wait all jobs finish   : YES
	- Run order              : SEQUENCE

Diagram:
                          NO
    +-----------[JOB]<---------+
    |                          |
    V                          | YES
  ----(ITERATED COUNT TIMES?)--+---->
*/
func Repeat(count int, job floc.Job) floc.Job {
	return func(ctx floc.Context, ctrl floc.Control) error {
		for n := 1; n <= count; n++ {
			// Do not start the job if the execution is finished
			if ctrl.IsFinished() {
				return nil
			}

			// Do the job
			err := job(ctx, ctrl)
			if handledErr := handleResult(ctrl, err, locRepeat); handledErr != nil {
				return handledErr
			}
		}

		return nil
	}
}

package run

import (
	"gopkg.in/workanator/go-floc.v2"
)

const locRepeat = "Repeat"

/*
Repeat repeats running the job for N times.

Summary:
	- Run jobs in goroutines : NO
	- Wait all jobs finish   : YES
	- Run order              : SEQUENCE

Diagram:
                          NO
    +-----------[JOB]<---------+
    |                          |
    V                          | YES
  ----(ITERATED COUNT TIMES?)--+---->
*/
func Repeat(times int, job floc.Job) floc.Job {
	return func(ctx floc.Context, ctrl floc.Control) error {
		for n := 1; n <= times; n++ {
			// Do not start the job if the execution is finished
			if ctrl.IsFinished() {
				return nil
			}

			// Do the job
			err := job(ctx, ctrl)
			if handledErr := handleResult(ctrl, err, locRepeat); handledErr != nil {
				return handledErr
			}
		}

		return nil
	}
}

Change parameter name and fix comment


package commons

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

func init() {
	rand.Seed(time.Now().UnixNano())
}

func GetUID() string {
	s := 6
	return randomString(s)
}

func randomString(l int) string {
	r := strconv.Itoa(rand.Intn(10000))

	bytes := make([]byte, l)
	for i := 0; i < l; i++ {
		bytes[i] = byte(randInt(64, 90))
	}
	return string(bytes) + r
}

func randInt(min int, max int) int {
	return min + rand.Intn(max-min)
}

package commons

import (
	"math/rand"
	"strconv"
	"time"
	"net/http"
	"log"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

func GetUID() string {
	s := 6
	return randomString(s)
}

func randomString(l int) string {
	r := strconv.Itoa(rand.Intn(10000))

	bytes := make([]byte, l)
	for i := 0; i < l; i++ {
		bytes[i] = byte(randInt(64, 90))
	}
	return string(bytes) + r
}

func randInt(min int, max int) int {
	return min + rand.Intn(max-min)
}

func WriteResponseWithError(w http.ResponseWriter, errorCode int) {
	w.WriteHeader(errorCode)
}

func Check(e error) {
	if e != nil {
		log.Fatal(e)
		panic(e)
	}
}

Make WriteResponseWithError and Check(err) common


/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package main

// ClusterAutoscalerVersion contains version of CA.
const ClusterAutoscalerVersion = "0.7.0-beta2"

/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package main

// ClusterAutoscalerVersion contains version of CA.
const ClusterAutoscalerVersion = "1.0.0"

Mark Cluster Autoscaler as GA (1.0.0)


package action

import (
	"flag"
)

type catalogServices struct {
	*config
}

func CatalogServicesAction() Action {
	return &catalogServices{
		config: &gConfig,
	}
}

func (c *catalogServices) CommandFlags() *flag.FlagSet {
	return newFlagSet()
}

//	addDatacenterOption(cmd)
//	addTemplateOption(cmd)
//	addConsistencyOptions(cmd)

func (c *catalogServices) Run(args []string) error {
	client, err := c.newCatalog()
	if err != nil {
		return err
	}

	queryOpts := c.queryOptions()
	config, _, err := client.Services(queryOpts)
	if err != nil {
		return err
	}

	return c.Output(config)
}

package action

import (
	"flag"
)

type catalogServices struct {
	*config
}

func CatalogServicesAction() Action {
	return &catalogServices{
		config: &gConfig,
	}
}

func (c *catalogServices) CommandFlags() *flag.FlagSet {
	f := newFlagSet()

	c.addDatacenterFlag(f)
	c.addOutputFlags(f, false)
	c.addConsistencyFlags(f)

	return f
}

func (c *catalogServices) Run(args []string) error {
	client, err := c.newCatalog()
	if err != nil {
		return err
	}

	queryOpts := c.queryOptions()
	config, _, err := client.Services(queryOpts)
	if err != nil {
		return err
	}

	return c.Output(config)
}

Fix catalog services command line flags


package main

import "github.com/hasit/gohr"

func main() {
	gohr.DrawHr("-0-")
	gohr.DrawHr("-", "#")
	gohr.DrawHr(".", "\\", "/")
}

package main

import (
	"os"

	"github.com/hasit/gohr"
)

func main() {
	args := os.Args[1:]
	gohr.Draw(args...)
}

Complete tool to match LuRsT/hr


package core

import "github.com/tisp-lang/tisp/src/lib/systemt"

type functionType struct {
	signature Signature
	function  func(...*Thunk) Value
}

func (f functionType) call(args Arguments) Value {
	ts, err := f.signature.Bind(args)

	if err != nil {
		return err
	}

	return f.function(ts...)
}

// NewLazyFunction creates a function whose arguments are evaluated lazily.
func NewLazyFunction(s Signature, f func(...*Thunk) Value) *Thunk {
	return Normal(functionType{
		signature: s,
		function:  f,
	})
}

// NewStrictFunction creates a function whose arguments are evaluated strictly.
func NewStrictFunction(s Signature, f func(...*Thunk) Value) *Thunk {
	return NewLazyFunction(s, func(ts ...*Thunk) Value {
		for _, t := range ts {
			systemt.Daemonize(func() { t.Eval() })
		}

		return f(ts...)
	})
}

func (f functionType) string() Value {
	return StringType("<function>")
}

package core

import "github.com/tisp-lang/tisp/src/lib/systemt"

type functionType struct {
	signature Signature
	function  func(...*Thunk) Value
}

func (f functionType) call(args Arguments) Value {
	ts, err := f.signature.Bind(args)

	if err != nil {
		return err
	}

	return f.function(ts...)
}

// NewLazyFunction creates a function whose arguments are evaluated lazily.
func NewLazyFunction(s Signature, f func(...*Thunk) Value) *Thunk {
	return Normal(functionType{
		signature: s,
		function:  f,
	})
}

// NewStrictFunction creates a function whose arguments are evaluated strictly.
func NewStrictFunction(s Signature, f func(...*Thunk) Value) *Thunk {
	return NewLazyFunction(s, func(ts ...*Thunk) Value {
		for _, t := range ts {
			tt := t
			systemt.Daemonize(func() { tt.Eval() })
		}

		return f(ts...)
	})
}

func (f functionType) string() Value {
	return StringType("<function>")
}

Fix wrong use of loop variables


package terminal

import (
	"bytes"
	"io"
	"strconv"

	"github.com/mattn/go-runewidth"
)

type Terminal struct {
	w   io.Writer
	buf *bytes.Buffer
	msg string
}

func New(w io.Writer) *Terminal {
	return &Terminal{
		w:   w,
		buf: bytes.NewBuffer(make([]byte, 0, 32)),
	}
}

func (t *Terminal) Refresh(prompt string, s []rune, pos int) {
	t.buf.WriteString("\r\033[J")
	t.buf.WriteString(prompt)
	t.buf.WriteString(string(s))
	if t.msg != "" {
		t.buf.WriteString("\n")
		t.buf.WriteString(t.msg)
		t.buf.WriteString("\033[A")
	}
	t.buf.WriteString("\033[")
	t.buf.WriteString(strconv.Itoa(runewidth.StringWidth(prompt) + runesWidth(s[:pos]) + 1))
	t.buf.WriteString("G")
	t.buf.WriteTo(t.w)
}

func runesWidth(s []rune) (width int) {
	for _, r := range s {
		width += runewidth.RuneWidth(r)
	}
	return width
}

func (t *Terminal) SetLastLine(msg string) {
	t.msg = msg
}

package terminal

import (
	"bufio"
	"io"
	"strconv"

	"github.com/mattn/go-runewidth"
)

type Terminal struct {
	w   *bufio.Writer
	msg string
}

func New(w io.Writer) *Terminal {
	return &Terminal{
		w: bufio.NewWriterSize(w, 32),
	}
}

func (t *Terminal) Refresh(prompt string, s []rune, pos int) {
	t.w.WriteString("\r\033[J")
	t.w.WriteString(prompt)
	t.w.WriteString(string(s))
	if t.msg != "" {
		t.w.WriteString("\n")
		t.w.WriteString(t.msg)
		t.w.WriteString("\033[A")
	}
	t.w.WriteString("\033[")
	t.w.WriteString(strconv.Itoa(runewidth.StringWidth(prompt) + runesWidth(s[:pos]) + 1))
	t.w.WriteString("G")
	t.w.Flush()
}

func runesWidth(s []rune) (width int) {
	for _, r := range s {
		width += runewidth.RuneWidth(r)
	}
	return width
}

func (t *Terminal) SetLastLine(msg string) {
	t.msg = msg
}

Use bufio.Writer instead of io.Writer & bytes.Buffer


// Package launcher configures Lantern to run on system start
package launcher

import (
	"github.com/kardianos/osext"
	"github.com/luisiturrios/gowin"

	"github.com/getlantern/golog"
)

const (
	runDir = `Software\Microsoft\Windows\CurrentVersion\Run`
)

var (
	log = golog.LoggerFor("launcher")
)

func CreateLaunchFile(autoLaunch bool) {
	var err error

	if autoLaunch {
		lanternPath, err := osext.Executable()
		if err != nil {
			log.Errorf("Could not get Lantern directory path: %q", err)
			return
		}
		err = gowin.WriteStringReg("HKCU", runDir, "Lantern", fmt.Sprintf(`"%s" -startup`, lanternPath))
		if err != nil {
			log.Errorf("Error inserting Lantern auto-start registry key: %q", err)
		}
	} else {
		// Just remove proxy settings and quit.
		err = gowin.WriteStringReg("HKCU", runDir, "Lantern", fmt.Sprintf(`"%s" -clear-proxy-settings`, lanternPath))
		if err != nil {
			log.Errorf("Error removing Lantern auto-start registry key: %q", err)
		}
	}
}

// Package launcher configures Lantern to run on system start
package launcher

import (
	"fmt"
	"github.com/kardianos/osext"
	"github.com/luisiturrios/gowin"

	"github.com/getlantern/golog"
)

const (
	runDir = `Software\Microsoft\Windows\CurrentVersion\Run`
)

var (
	log = golog.LoggerFor("launcher")
)

func CreateLaunchFile(autoLaunch bool) {
	var startupCommand string

	lanternPath, err := osext.Executable()
	if err != nil {
		log.Errorf("Could not get Lantern directory path: %q", err)
		return
	}

	if autoLaunch {
		// Start Lantern normally.
		startupCommand = fmt.Sprintf(`"%s" -startup`, lanternPath)
	} else {
		// Just clear stored proxy settings and quit.
		startupCommand = fmt.Sprintf(`"%s" -clear-proxy-settings`, lanternPath)
	}

	err = gowin.WriteStringReg("HKCU", runDir, "Lantern", startupCommand)
	if err != nil {
		log.Errorf("Error setting Lantern auto-start registry key: %q", err)
	}
}

Use either -startup or -clear-proxy-settings on the Lantern HKCU/.../CurrentVersion/Run registry key.


package main

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

type config struct {
	controllerKey string
	ourPort       string
	logOut        io.Writer
}

func loadConfigFromEnv() (*config, error) {
	c := &config{}
	c.controllerKey = os.Getenv("CONTROLLER_KEY")
	if c.controllerKey == "" {
		return nil, fmt.Errorf("CONTROLLER_KEY is required")
	}
	port := os.Getenv("PORT")
	if port == "" {
		port = "4456"
	}
	c.ourPort = port

	if logPath := os.Getenv("LOGFILE"); logPath != "" {
		if f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err == nil {
			c.logOut = f
		}
	}
	if c.logOut == nil {
		c.logOut = os.Stderr
	}
	return c, nil
}

package main

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

type config struct {
	controllerKey string
	ourPort       string
	logOut        io.Writer
}

func init() {
	log.SetFlags(log.Lshortfile | log.Lmicroseconds)
}

func loadConfigFromEnv() (*config, error) {
	c := &config{}
	c.controllerKey = os.Getenv("CONTROLLER_KEY")
	if c.controllerKey == "" {
		return nil, fmt.Errorf("CONTROLLER_KEY is required")
	}
	port := os.Getenv("PORT")
	if port == "" {
		port = "4456"
	}
	c.ourPort = port

	if logPath := os.Getenv("LOGFILE"); logPath != "" {
		if f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err == nil {
			c.logOut = f
		}
	}
	if c.logOut == nil {
		c.logOut = os.Stderr
	}
	return c, nil
}

Add file/line to log messages


/*
word-server creates an HTTP server which exports endpoints for querying a word2vec model.
*/
package main

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

	"github.com/sajari/word2vec"
)

var listen, modelPath string

func init() {
	flag.StringVar(&listen, "listen", "localhost:1234", "bind `address` for HTTP server")
	flag.StringVar(&modelPath, "model", "", "path to binary model data")
}

func main() {
	flag.Parse()

	if modelPath == "" {
		fmt.Println("must specify -p; see -h for more details")
		os.Exit(1)
	}

	log.Println("Loading model...")
	f, err := os.Open(modelPath)
	if err != nil {
		fmt.Printf("error opening binary model data file: %v\n", err)
		os.Exit(1)
	}
	defer f.Close()

	m, err := word2vec.FromReader(f)
	if err != nil {
		fmt.Printf("error reading binary model data: %v\n", err)
		os.Exit(1)
	}

	ms := word2vec.NewServer(m)

	log.Printf("Server listening on %v", listen)
	log.Println("Hit Ctrl-C to quit.")

	log.Fatal(http.ListenAndServe(listen, ms))
}

/*
word-server creates an HTTP server which exports endpoints for querying a word2vec model.
*/
package main

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

	"github.com/sajari/word2vec"
)

var listen, modelPath string

func init() {
	flag.StringVar(&listen, "listen", "localhost:1234", "bind `address` for HTTP server")
	flag.StringVar(&modelPath, "model", "", "path to binary model data")
}

func main() {
	flag.Parse()

	if modelPath == "" {
		fmt.Println("must specify -model; see -h for more details")
		os.Exit(1)
	}

	log.Println("Loading model...")
	f, err := os.Open(modelPath)
	if err != nil {
		fmt.Printf("error opening binary model data file: %v\n", err)
		os.Exit(1)
	}
	defer f.Close()

	m, err := word2vec.FromReader(f)
	if err != nil {
		fmt.Printf("error reading binary model data: %v\n", err)
		os.Exit(1)
	}

	ms := word2vec.NewServer(m)

	log.Printf("Server listening on %v", listen)
	log.Println("Hit Ctrl-C to quit.")

	log.Fatal(http.ListenAndServe(listen, ms))
}

Update help message to use -model.