<commit_before>package gofakeit

import (
	"fmt"
	"testing"
)

func ExampleFruit() {
	Seed(11)
	fmt.Println(Fruit())
	// Output: Date
}

func BenchmarkFruit(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Fruit()
	}
}

func ExampleVegetable() {
	Seed(11)
	fmt.Println(Vegetable())
	// Output: Amaranth Leaves
}

func BenchmarkVegetable(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Vegetable()
	}
}

func ExampleBreakfast() {
	Seed(11)
	fmt.Println(Breakfast())
	// Output: Blueberry banana happy face pancakes
}

func BenchmarkBreakfast(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Breakfast()
	}
}

func ExampleLunch() {
	Seed(11)
	fmt.Println(Lunch())
	// Output: No bake hersheys bar pie
}

func BenchmarkLunch(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Lunch()
	}
}

func ExampleDinner() {
	Seed(11)
	fmt.Println(Dinner())
	// Output: Wild addicting dip
}

func BenchmarkDinner(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Dinner()
	}
}

func ExampleSnack() {
	Seed(11)
	fmt.Println(Snack())
	// Output: Hoisin marinated wing pieces
}

func BenchmarkSnack(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Snack()
	}
}

func ExampleDessert() {
	Seed(11)
	fmt.Println(Dessert())
	// Output: French napoleons
}

func BenchmarkDessert(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Dessert()
	}
}
<commit_msg>food examples and benchmarks<commit_after>package gofakeit

import (
	"fmt"
	"testing"
)

func ExampleFruit() {
	Seed(11)
	fmt.Println(Fruit())
	// Output: Date
}

func ExampleFaker_Fruit() {
	f := New(11)
	fmt.Println(f.Fruit())
	// Output: Date
}

func BenchmarkFruit(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Fruit()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Fruit()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Fruit()
		}
	})
}

func ExampleVegetable() {
	Seed(11)
	fmt.Println(Vegetable())
	// Output: Amaranth Leaves
}

func ExampleFaker_Vegetable() {
	f := New(11)
	fmt.Println(f.Vegetable())
	// Output: Amaranth Leaves
}

func BenchmarkVegetable(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Vegetable()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Vegetable()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Vegetable()
		}
	})
}

func ExampleBreakfast() {
	Seed(11)
	fmt.Println(Breakfast())
	// Output: Blueberry banana happy face pancakes
}

func ExampleFaker_Breakfast() {
	f := New(11)
	fmt.Println(f.Breakfast())
	// Output: Blueberry banana happy face pancakes
}

func BenchmarkBreakfast(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Breakfast()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Breakfast()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Breakfast()
		}
	})
}

func ExampleLunch() {
	Seed(11)
	fmt.Println(Lunch())
	// Output: No bake hersheys bar pie
}

func ExampleFaker_Lunch() {
	f := New(11)
	fmt.Println(f.Lunch())
	// Output: No bake hersheys bar pie
}

func BenchmarkLunch(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Lunch()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Lunch()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Lunch()
		}
	})
}

func ExampleDinner() {
	Seed(11)
	fmt.Println(Dinner())
	// Output: Wild addicting dip
}

func ExampleFaker_Dinner() {
	f := New(11)
	fmt.Println(f.Dinner())
	// Output: Wild addicting dip
}

func BenchmarkDinner(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Dinner()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Dinner()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Dinner()
		}
	})
}

func ExampleSnack() {
	Seed(11)
	fmt.Println(Snack())
	// Output: Hoisin marinated wing pieces
}

func ExampleFaker_Snack() {
	f := New(11)
	fmt.Println(f.Snack())
	// Output: Hoisin marinated wing pieces
}

func BenchmarkSnack(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Snack()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Snack()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Snack()
		}
	})
}

func ExampleDessert() {
	Seed(11)
	fmt.Println(Dessert())
	// Output: French napoleons
}

func ExampleFaker_Dessert() {
	f := New(11)
	fmt.Println(f.Dessert())
	// Output: French napoleons
}

func BenchmarkDessert(b *testing.B) {
	b.Run("package", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			Dessert()
		}
	})

	b.Run("Faker math", func(b *testing.B) {
		f := New(0)

		for i := 0; i < b.N; i++ {
			f.Dessert()
		}
	})

	b.Run("Faker crypto", func(b *testing.B) {
		f := NewCrypto()

		for i := 0; i < b.N; i++ {
			f.Dessert()
		}
	})
}
<|endoftext|>


<commit_before>package bio

import (
	"bytes"
	"encoding/gob"

	"gopkg.in/itchio/rsync-go.v0"
)

type LogEntry struct {
	Message string
}

type Target struct {
	RepoSpec string
}

type SourceFile struct {
	Path string
	Size uint64
}

type EndOfSources struct{}

type FilePatched struct {
	Path    string
	ApplyTo string
}

type FileAdded struct {
	Path string
}

type FileRemoved struct {
	Path string
}

func init() {
	Register()
}

func Register() {
	gob.Register(LogEntry{})

	gob.Register(Target{})

	gob.Register(SourceFile{})
	gob.Register(EndOfSources{})

	gob.Register(rsync.BlockHash{})
	gob.Register(rsync.Operation{})

	gob.Register(FilePatched{})
	gob.Register(FileAdded{})
	gob.Register(FileRemoved{})
	gob.Register(rsync.BlockHash{})
}

func Marshal(value interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	genc := gob.NewEncoder(buf)

	err := genc.Encode(&value)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

func Unmarshal(buf []byte) (interface{}, error) {
	gdec := gob.NewDecoder(bytes.NewReader(buf))

	var value interface{}
	err := gdec.Decode(&value)
	if err != nil {
		return nil, err
	}

	return value, nil
}
<commit_msg>Add bio.MD5Hash message type<commit_after>package bio

import (
	"bytes"
	"encoding/gob"

	"gopkg.in/itchio/rsync-go.v0"
)

type LogEntry struct {
	Message string
}

type Target struct {
	RepoSpec string
}

type SourceFile struct {
	Path string
	Size uint64
}

type MD5Hash struct {
	Hash []byte
}

type EndOfSources struct{}

type FilePatched struct {
	Path    string
	ApplyTo string
}

type FileAdded struct {
	Path string
}

type FileRemoved struct {
	Path string
}

func init() {
	Register()
}

func Register() {
	gob.Register(LogEntry{})

	gob.Register(Target{})

	gob.Register(SourceFile{})
	gob.Register(MD5Hash{})
	gob.Register(EndOfSources{})

	gob.Register(rsync.BlockHash{})
	gob.Register(rsync.Operation{})

	gob.Register(FilePatched{})
	gob.Register(FileAdded{})
	gob.Register(FileRemoved{})
	gob.Register(rsync.BlockHash{})
}

func Marshal(value interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	genc := gob.NewEncoder(buf)

	err := genc.Encode(&value)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

func Unmarshal(buf []byte) (interface{}, error) {
	gdec := gob.NewDecoder(bytes.NewReader(buf))

	var value interface{}
	err := gdec.Decode(&value)
	if err != nil {
		return nil, err
	}

	return value, nil
}
<|endoftext|>


<commit_before>// Copyright ©2014 The gonum 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 optimize

import (
	"math"

	"github.com/gonum/floats"
)

// Bisection is a LinesearchMethod that uses a bisection to find a point that
// satisfies the strong Wolfe conditions with the given gradient constant and
// function constant of zero. If GradConst is zero, it will be set to a reasonable
// value. Bisection will panic if GradConst is not between zero and one.
type Bisection struct {
	GradConst float64

	minStep  float64
	maxStep  float64
	currStep float64

	initF float64
	minF  float64
	maxF  float64

	initGrad float64
	minGrad  float64
	maxGrad  float64
}

func (b *Bisection) Init(initLoc LinesearchLocation, initStepSize float64, f *FunctionInfo) EvaluationType {
	if initLoc.Derivative >= 0 {
		panic("bisection: init G non-negative")
	}
	if initStepSize <= 0 {
		panic("bisection: bad step size")
	}

	if b.GradConst == 0 {
		b.GradConst = 0.9
	}
	if b.GradConst <= 0 || b.GradConst >= 1 {
		panic("bisection: GradConst not between 0 and 1")
	}

	b.minStep = 0
	b.maxStep = math.Inf(1)
	b.currStep = initStepSize

	b.initF = initLoc.F
	b.minF = initLoc.F
	b.maxF = math.NaN()

	b.initGrad = initLoc.Derivative
	b.minGrad = initLoc.Derivative
	b.maxGrad = math.NaN()

	return FunctionAndGradientEval
}

const (
	funcSmallEqual = 1e-14
	gradSmallEqual = 1e-10
)

func (b *Bisection) Finished(l LinesearchLocation) bool {
	if floats.EqualWithinRel(l.F, b.initF, funcSmallEqual) && math.Abs(l.Derivative) < gradSmallEqual && math.Abs(b.initGrad) < gradSmallEqual {
		// The two numbers are so close that we should just check on the gradient
		// TODO: Should iterate be updated? Maybe find a function where it needs it.
		return math.Abs(l.Derivative) < b.GradConst*math.Abs(b.initGrad)
	}

	return StrongWolfeConditionsMet(l.F, l.Derivative, b.initF, b.initGrad, b.currStep, 0, b.GradConst)
}

func (b *Bisection) Iterate(l LinesearchLocation) (float64, EvaluationType, error) {
	f := l.F
	g := l.Derivative
	// Deciding on the next step size
	if math.IsInf(b.maxStep, 1) {
		// Have not yet bounded the minimum
		switch {
		case g > 0:
			// Found a change in derivative sign, so this is the new maximum
			b.maxStep = b.currStep
			b.maxF = f
			b.maxGrad = g
			return b.checkStepEqual((b.minStep+b.maxStep)/2, FunctionAndGradientEval)
		case f <= b.minF:
			// Still haven't found an upper bound, but there is not an increase in
			// function value and the gradient is still negative, so go more in
			// that direction.
			b.minStep = b.currStep
			b.minF = f
			b.minGrad = g
			return b.checkStepEqual(b.currStep*2, FunctionAndGradientEval)
		default:
			// Increase in function value, but the gradient is still negative.
			// Means we must have skipped over a local minimum, so set this point
			// as the new maximum
			b.maxStep = b.currStep
			b.maxF = f
			b.maxGrad = g
			return b.checkStepEqual((b.minStep+b.maxStep)/2, FunctionAndGradientEval)
		}
	}
	// We have already bounded the minimum, so we're just working to find one
	// close enough to the minimum to meet the strong wolfe conditions
	if g < 0 {
		if f <= b.minF {
			b.minStep = b.currStep
			b.minF = f
			b.minGrad = g
		} else {
			// Negative gradient, but increase in function value, so must have
			// skipped over a local minimum. Set this as the new maximum location
			b.maxStep = b.currStep
			b.maxF = f
			b.maxGrad = g
		}
	} else {
		// Gradient is positive, so minimum must be between the max point and
		// the minimum point
		b.maxStep = b.currStep
		b.maxF = f
		b.maxGrad = g
	}
	return b.checkStepEqual((b.minStep+b.maxStep)/2, FunctionAndGradientEval)
}

// checkStepEqual checks if the new step is equal to the old step.
// this can happen if min and max are the same, or if the step size is infinity,
// both of which indicate the minimization must stop. If the steps are different,
// it sets the new step size and returns the step and evaluation type. If the steps
// are the same, it returns an error.
func (b *Bisection) checkStepEqual(newStep float64, e EvaluationType) (float64, EvaluationType, error) {
	if b.currStep == newStep {
		return b.currStep, NoEvaluation, ErrLinesearchFailure
	}
	b.currStep = newStep
	return newStep, e, nil
}
<commit_msg>Remove extra check for conclusion of Bisection.<commit_after>// Copyright ©2014 The gonum 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 optimize

import "math"

// Bisection is a LinesearchMethod that uses a bisection to find a point that
// satisfies the strong Wolfe conditions with the given gradient constant and
// function constant of zero. If GradConst is zero, it will be set to a reasonable
// value. Bisection will panic if GradConst is not between zero and one.
type Bisection struct {
	GradConst float64

	minStep  float64
	maxStep  float64
	currStep float64

	initF float64
	minF  float64
	maxF  float64

	initGrad float64
	minGrad  float64
	maxGrad  float64
}

func (b *Bisection) Init(initLoc LinesearchLocation, initStepSize float64, f *FunctionInfo) EvaluationType {
	if initLoc.Derivative >= 0 {
		panic("bisection: init G non-negative")
	}
	if initStepSize <= 0 {
		panic("bisection: bad step size")
	}

	if b.GradConst == 0 {
		b.GradConst = 0.9
	}
	if b.GradConst <= 0 || b.GradConst >= 1 {
		panic("bisection: GradConst not between 0 and 1")
	}

	b.minStep = 0
	b.maxStep = math.Inf(1)
	b.currStep = initStepSize

	b.initF = initLoc.F
	b.minF = initLoc.F
	b.maxF = math.NaN()

	b.initGrad = initLoc.Derivative
	b.minGrad = initLoc.Derivative
	b.maxGrad = math.NaN()

	return FunctionAndGradientEval
}

func (b *Bisection) Finished(l LinesearchLocation) bool {
	return StrongWolfeConditionsMet(l.F, l.Derivative, b.initF, b.initGrad, b.currStep, 0, b.GradConst)
}

func (b *Bisection) Iterate(l LinesearchLocation) (float64, EvaluationType, error) {
	f := l.F
	g := l.Derivative
	// Deciding on the next step size
	if math.IsInf(b.maxStep, 1) {
		// Have not yet bounded the minimum
		switch {
		case g > 0:
			// Found a change in derivative sign, so this is the new maximum
			b.maxStep = b.currStep
			b.maxF = f
			b.maxGrad = g
			return b.checkStepEqual((b.minStep+b.maxStep)/2, FunctionAndGradientEval)
		case f <= b.minF:
			// Still haven't found an upper bound, but there is not an increase in
			// function value and the gradient is still negative, so go more in
			// that direction.
			b.minStep = b.currStep
			b.minF = f
			b.minGrad = g
			return b.checkStepEqual(b.currStep*2, FunctionAndGradientEval)
		default:
			// Increase in function value, but the gradient is still negative.
			// Means we must have skipped over a local minimum, so set this point
			// as the new maximum
			b.maxStep = b.currStep
			b.maxF = f
			b.maxGrad = g
			return b.checkStepEqual((b.minStep+b.maxStep)/2, FunctionAndGradientEval)
		}
	}
	// We have already bounded the minimum, so we're just working to find one
	// close enough to the minimum to meet the strong wolfe conditions
	if g < 0 {
		if f <= b.minF {
			b.minStep = b.currStep
			b.minF = f
			b.minGrad = g
		} else {
			// Negative gradient, but increase in function value, so must have
			// skipped over a local minimum. Set this as the new maximum location
			b.maxStep = b.currStep
			b.maxF = f
			b.maxGrad = g
		}
	} else {
		// Gradient is positive, so minimum must be between the max point and
		// the minimum point
		b.maxStep = b.currStep
		b.maxF = f
		b.maxGrad = g
	}
	return b.checkStepEqual((b.minStep+b.maxStep)/2, FunctionAndGradientEval)
}

// checkStepEqual checks if the new step is equal to the old step.
// this can happen if min and max are the same, or if the step size is infinity,
// both of which indicate the minimization must stop. If the steps are different,
// it sets the new step size and returns the step and evaluation type. If the steps
// are the same, it returns an error.
func (b *Bisection) checkStepEqual(newStep float64, e EvaluationType) (float64, EvaluationType, error) {
	if b.currStep == newStep {
		return b.currStep, NoEvaluation, ErrLinesearchFailure
	}
	b.currStep = newStep
	return newStep, e, nil
}
<|endoftext|>


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

package cli

import (
	"bytes"
	"errors"
	"fmt"
	"strconv"

	"github.com/cockroachdb/cockroach/config"
	"github.com/cockroachdb/cockroach/keys"
	"github.com/cockroachdb/cockroach/roachpb"
	"github.com/cockroachdb/cockroach/storage"
	"github.com/cockroachdb/cockroach/storage/engine"
	"github.com/cockroachdb/cockroach/util/stop"
	"github.com/cockroachdb/cockroach/util/timeutil"
	"github.com/coreos/etcd/raft/raftpb"
	"github.com/gogo/protobuf/proto"
	"github.com/kr/pretty"
	"github.com/spf13/cobra"
)

var debugKeysCmd = &cobra.Command{
	Use:   "keys [directory]",
	Short: "dump all the keys in a store",
	Long: `
Pretty-prints all keys in a store.
`,
	RunE: runDebugKeys,
}

func parseRangeID(arg string) (roachpb.RangeID, error) {
	rangeIDInt, err := strconv.ParseInt(arg, 10, 64)
	if err != nil {
		return 0, err
	}
	return roachpb.RangeID(rangeIDInt), nil
}

func openStore(cmd *cobra.Command, dir string, stopper *stop.Stopper) (engine.Engine, error) {
	initCacheSize()

	db := engine.NewRocksDB(roachpb.Attributes{}, dir,
		cliContext.CacheSize, cliContext.MemtableBudget, 0, stopper)
	if err := db.Open(); err != nil {
		return nil, err
	}
	return db, nil
}

func printKey(kv engine.MVCCKeyValue) (bool, error) {
	fmt.Printf("%q\n", kv.Key)

	return false, nil
}

func printKeyValue(kv engine.MVCCKeyValue) (bool, error) {
	if kv.Key.Timestamp != roachpb.ZeroTimestamp {
		fmt.Printf("%s %q: ", kv.Key.Timestamp, kv.Key.Key)
	} else {
		fmt.Printf("%q: ", kv.Key.Key)
	}
	for _, decoder := range []func(kv engine.MVCCKeyValue) (string, error){tryRaftLogEntry, tryRangeDescriptor, tryMeta, trySequence, tryTxn} {
		out, err := decoder(kv)
		if err != nil {
			continue
		}
		fmt.Println(out)
		return false, nil
	}
	// No better idea, just print raw bytes and hope that folks use `less -S`.
	fmt.Printf("%q\n\n", kv.Value)
	return false, nil
}

func runDebugKeys(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 1 {
		return errors.New("one argument is required")
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	d := cliContext.debug

	from := engine.NilKey
	to := engine.MVCCKeyMax
	if d.raw {
		if len(d.startKey) > 0 {
			from = engine.MakeMVCCMetadataKey(roachpb.Key(d.startKey))
		}
		if len(d.endKey) > 0 {
			to = engine.MakeMVCCMetadataKey(roachpb.Key(d.endKey))
		}
	} else {
		if len(d.startKey) > 0 {
			startKey, err := keys.UglyPrint(d.startKey)
			if err != nil {
				return err
			}
			from = engine.MakeMVCCMetadataKey(startKey)
		}
		if len(d.endKey) > 0 {
			endKey, err := keys.UglyPrint(d.endKey)
			if err != nil {
				return err
			}
			to = engine.MakeMVCCMetadataKey(endKey)
		}
	}

	printer := printKey
	if d.values {
		printer = printKeyValue
	}

	if err := db.Iterate(from, to, printer); err != nil {
		return err
	}

	return nil
}

var debugRangeDescriptorsCmd = &cobra.Command{
	Use:   "range-descriptors [directory]",
	Short: "print all range descriptors in a store",
	Long: `
Prints all range descriptors in a store with a history of changes.
`,
	RunE: runDebugRangeDescriptors,
}

func descStr(desc roachpb.RangeDescriptor) string {
	return fmt.Sprintf("[%s, %s)\n\tRaw:%s\n",
		desc.StartKey, desc.EndKey, &desc)
}

func tryMeta(kv engine.MVCCKeyValue) (string, error) {
	if !bytes.HasPrefix(kv.Key.Key, keys.Meta1Prefix) && !bytes.HasPrefix(kv.Key.Key, keys.Meta2Prefix) {
		return "", errors.New("not a meta key")
	}
	value := roachpb.Value{
		Timestamp: kv.Key.Timestamp,
		RawBytes:  kv.Value,
	}
	var desc roachpb.RangeDescriptor
	if err := value.GetProto(&desc); err != nil {
		return "", err
	}
	return descStr(desc), nil
}

func maybeUnmarshalInline(v []byte, dest proto.Message) error {
	var meta engine.MVCCMetadata
	if err := meta.Unmarshal(v); err != nil {
		return err
	}
	value := roachpb.Value{
		RawBytes: meta.RawBytes,
	}
	return value.GetProto(dest)
}

func tryTxn(kv engine.MVCCKeyValue) (string, error) {
	var txn roachpb.Transaction
	if err := maybeUnmarshalInline(kv.Value, &txn); err != nil {
		return "", err
	}
	return txn.String() + "\n", nil
}

func trySequence(kv engine.MVCCKeyValue) (string, error) {
	if kv.Key.Timestamp != roachpb.ZeroTimestamp {
		return "", errors.New("not a sequence cache key")
	}
	_, _, _, err := keys.DecodeSequenceCacheKey(kv.Key.Key, nil)
	if err != nil {
		return "", err
	}
	var dest roachpb.SequenceCacheEntry
	if err := maybeUnmarshalInline(kv.Value, &dest); err != nil {
		return "", err
	}
	return fmt.Sprintf("ts=%s, key=%q\n", dest.Timestamp, dest.Key), nil
}

func tryRangeDescriptor(kv engine.MVCCKeyValue) (string, error) {
	_, suffix, _, err := keys.DecodeRangeKey(kv.Key.Key)
	if err != nil {
		return "", err
	}
	if !bytes.Equal(suffix, keys.LocalRangeDescriptorSuffix) {
		return "", fmt.Errorf("wrong suffix: %s", suffix)
	}
	value := roachpb.Value{
		RawBytes: kv.Value,
	}
	var desc roachpb.RangeDescriptor
	if err := value.GetProto(&desc); err != nil {
		return "", err
	}
	return descStr(desc), nil
}

func printRangeDescriptor(kv engine.MVCCKeyValue) (bool, error) {
	if out, err := tryRangeDescriptor(kv); err != nil {
		fmt.Printf("%s %q: invalid value: %v", kv.Key.Timestamp, kv.Key.Key, err)
	} else {
		fmt.Println(out)
	}
	return true, nil
}

func runDebugRangeDescriptors(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 1 {
		return errors.New("one argument is required")
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	start := engine.MakeMVCCMetadataKey(keys.LocalRangePrefix)
	end := engine.MakeMVCCMetadataKey(keys.LocalRangeMax)

	if err := db.Iterate(start, end, printRangeDescriptor); err != nil {
		return err
	}
	return nil
}

var debugRaftLogCmd = &cobra.Command{
	Use:   "raft-log [directory] [range id]",
	Short: "print the raft log for a range",
	Long: `
Prints all log entries in a store for the given range.
`,
	RunE: runDebugRaftLog,
}

func tryRaftLogEntry(kv engine.MVCCKeyValue) (string, error) {
	var ent raftpb.Entry
	if err := maybeUnmarshalInline(kv.Value, &ent); err != nil {
		return "", err
	}
	if ent.Type == raftpb.EntryNormal {
		if len(ent.Data) > 0 {
			_, cmdData := storage.DecodeRaftCommand(ent.Data)
			var cmd roachpb.RaftCommand
			if err := cmd.Unmarshal(cmdData); err != nil {
				return "", err
			}
			ent.Data = nil
			return fmt.Sprintf("%s by %v\n%s\n%s\n", &ent, cmd.OriginReplica, &cmd.Cmd, &cmd), nil
		}
		return fmt.Sprintf("%s: EMPTY\n", &ent), nil
	} else if ent.Type == raftpb.EntryConfChange {
		var cc raftpb.ConfChange
		if err := cc.Unmarshal(ent.Data); err != nil {
			return "", err
		}
		var ctx storage.ConfChangeContext
		if err := ctx.Unmarshal(cc.Context); err != nil {
			return "", err
		}
		var cmd roachpb.RaftCommand
		if err := cmd.Unmarshal(ctx.Payload); err != nil {
			return "", err
		}
		ent.Data = nil
		return fmt.Sprintf("%s\n%s\n", &ent, &cmd), nil
	}
	return "", fmt.Errorf("Unknown log entry type: %s\n", &ent)
}

func printRaftLogEntry(kv engine.MVCCKeyValue) (bool, error) {
	if out, err := tryRaftLogEntry(kv); err != nil {
		fmt.Printf("%q: %v\n\n", kv.Key.Key, err)
	} else {
		fmt.Println(out)
	}
	return false, nil
}

func runDebugRaftLog(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 2 {
		return errors.New("required arguments: dir range_id")
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	rangeID, err := parseRangeID(args[1])
	if err != nil {
		return err
	}

	start := engine.MakeMVCCMetadataKey(keys.RaftLogPrefix(rangeID))
	end := engine.MakeMVCCMetadataKey(keys.RaftLogPrefix(rangeID).PrefixEnd())

	if err := db.Iterate(start, end, printRaftLogEntry); err != nil {
		return err
	}
	return nil
}

var debugGCCmd = &cobra.Command{
	Use:   "estimate-gc [directory] [range id]",
	Short: "find out what a GC run would do",
	Long: `
Sets up (but does not run) a GC collection cycle, giving insight into how much
work would be done (assuming all intent resolution and pushes succeed).

Without a RangeID specified on the command line, runs the analysis for all
ranges individually.

Uses a hard-coded GC policy with a 24 hour TTL for old versions.
`,
	RunE: runDebugGCCmd,
}

func runDebugGCCmd(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 1 {
		return errors.New("required arguments: dir")
	}

	var rangeID roachpb.RangeID
	if len(args) == 2 {
		var err error
		if rangeID, err = parseRangeID(args[1]); err != nil {
			return err
		}
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	start := keys.RangeDescriptorKey(roachpb.RKeyMin)
	end := keys.RangeDescriptorKey(roachpb.RKeyMax)

	var descs []roachpb.RangeDescriptor

	if _, err := engine.MVCCIterate(db, start, end, roachpb.MaxTimestamp,
		false /* !consistent */, nil, /* txn */
		false /* !reverse */, func(kv roachpb.KeyValue) (bool, error) {
			var desc roachpb.RangeDescriptor
			_, suffix, _, err := keys.DecodeRangeKey(kv.Key)
			if err != nil {
				return false, err
			}
			if !bytes.Equal(suffix, keys.LocalRangeDescriptorSuffix) {
				return false, nil
			}
			if err := kv.Value.GetProto(&desc); err != nil {
				return false, err
			}
			if desc.RangeID == rangeID || rangeID == 0 {
				descs = append(descs, desc)
			}
			return desc.RangeID == rangeID, nil
		}); err != nil {
		return err
	}

	if len(descs) == 0 {
		return fmt.Errorf("no range matching the criteria found")
	}

	for _, desc := range descs {
		snap := db.NewSnapshot()
		defer snap.Close()
		_, info, err := storage.RunGC(&desc, snap, roachpb.Timestamp{WallTime: timeutil.Now().UnixNano()},
			config.GCPolicy{TTLSeconds: 24 * 60 * 60 /* 1 day */}, func(_ roachpb.Timestamp, _ *roachpb.Transaction, _ roachpb.PushTxnType) {
			}, func(_ []roachpb.Intent, _, _ bool) error { return nil })
		if err != nil {
			return err
		}
		fmt.Printf("RangeID: %d [%s, %s):\n", desc.RangeID, desc.StartKey, desc.EndKey)
		_, _ = pretty.Println(info)
	}
	return nil
}

func init() {
	debugCmd.AddCommand(debugCmds...)
}

var debugCmds = []*cobra.Command{
	debugKeysCmd,
	debugRangeDescriptorsCmd,
	debugRaftLogCmd,
	debugGCCmd,
	kvCmd,
	rangeCmd,
}

var debugCmd = &cobra.Command{
	Use:   "debug [command]",
	Short: "debugging commands",
	Long: `Various commands for debugging.

These commands are useful for extracting data from the data files of a
process that has failed and cannot restart.
`,
	Run: func(cmd *cobra.Command, args []string) {
		mustUsage(cmd)
	},
}
<commit_msg>Fix `cli/debug range-descriptors`<commit_after>// Copyright 2016 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License. See the AUTHORS file
// for names of contributors.
//
// Author: Ben Darnell

package cli

import (
	"bytes"
	"errors"
	"fmt"
	"strconv"

	"github.com/cockroachdb/cockroach/config"
	"github.com/cockroachdb/cockroach/keys"
	"github.com/cockroachdb/cockroach/roachpb"
	"github.com/cockroachdb/cockroach/storage"
	"github.com/cockroachdb/cockroach/storage/engine"
	"github.com/cockroachdb/cockroach/util/stop"
	"github.com/cockroachdb/cockroach/util/timeutil"
	"github.com/coreos/etcd/raft/raftpb"
	"github.com/gogo/protobuf/proto"
	"github.com/kr/pretty"
	"github.com/spf13/cobra"
)

var debugKeysCmd = &cobra.Command{
	Use:   "keys [directory]",
	Short: "dump all the keys in a store",
	Long: `
Pretty-prints all keys in a store.
`,
	RunE: runDebugKeys,
}

func parseRangeID(arg string) (roachpb.RangeID, error) {
	rangeIDInt, err := strconv.ParseInt(arg, 10, 64)
	if err != nil {
		return 0, err
	}
	return roachpb.RangeID(rangeIDInt), nil
}

func openStore(cmd *cobra.Command, dir string, stopper *stop.Stopper) (engine.Engine, error) {
	initCacheSize()

	db := engine.NewRocksDB(roachpb.Attributes{}, dir,
		cliContext.CacheSize, cliContext.MemtableBudget, 0, stopper)
	if err := db.Open(); err != nil {
		return nil, err
	}
	return db, nil
}

func printKey(kv engine.MVCCKeyValue) (bool, error) {
	fmt.Printf("%q\n", kv.Key)

	return false, nil
}

func printKeyValue(kv engine.MVCCKeyValue) (bool, error) {
	if kv.Key.Timestamp != roachpb.ZeroTimestamp {
		fmt.Printf("%s %q: ", kv.Key.Timestamp, kv.Key.Key)
	} else {
		fmt.Printf("%q: ", kv.Key.Key)
	}
	for _, decoder := range []func(kv engine.MVCCKeyValue) (string, error){tryRaftLogEntry, tryRangeDescriptor, tryMeta, trySequence, tryTxn} {
		out, err := decoder(kv)
		if err != nil {
			continue
		}
		fmt.Println(out)
		return false, nil
	}
	// No better idea, just print raw bytes and hope that folks use `less -S`.
	fmt.Printf("%q\n\n", kv.Value)
	return false, nil
}

func runDebugKeys(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 1 {
		return errors.New("one argument is required")
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	d := cliContext.debug

	from := engine.NilKey
	to := engine.MVCCKeyMax
	if d.raw {
		if len(d.startKey) > 0 {
			from = engine.MakeMVCCMetadataKey(roachpb.Key(d.startKey))
		}
		if len(d.endKey) > 0 {
			to = engine.MakeMVCCMetadataKey(roachpb.Key(d.endKey))
		}
	} else {
		if len(d.startKey) > 0 {
			startKey, err := keys.UglyPrint(d.startKey)
			if err != nil {
				return err
			}
			from = engine.MakeMVCCMetadataKey(startKey)
		}
		if len(d.endKey) > 0 {
			endKey, err := keys.UglyPrint(d.endKey)
			if err != nil {
				return err
			}
			to = engine.MakeMVCCMetadataKey(endKey)
		}
	}

	printer := printKey
	if d.values {
		printer = printKeyValue
	}

	if err := db.Iterate(from, to, printer); err != nil {
		return err
	}

	return nil
}

var debugRangeDescriptorsCmd = &cobra.Command{
	Use:   "range-descriptors [directory]",
	Short: "print all range descriptors in a store",
	Long: `
Prints all range descriptors in a store with a history of changes.
`,
	RunE: runDebugRangeDescriptors,
}

func descStr(desc roachpb.RangeDescriptor) string {
	return fmt.Sprintf("[%s, %s)\n\tRaw:%s\n",
		desc.StartKey, desc.EndKey, &desc)
}

func tryMeta(kv engine.MVCCKeyValue) (string, error) {
	if !bytes.HasPrefix(kv.Key.Key, keys.Meta1Prefix) && !bytes.HasPrefix(kv.Key.Key, keys.Meta2Prefix) {
		return "", errors.New("not a meta key")
	}
	value := roachpb.Value{
		Timestamp: kv.Key.Timestamp,
		RawBytes:  kv.Value,
	}
	var desc roachpb.RangeDescriptor
	if err := value.GetProto(&desc); err != nil {
		return "", err
	}
	return descStr(desc), nil
}

func maybeUnmarshalInline(v []byte, dest proto.Message) error {
	var meta engine.MVCCMetadata
	if err := meta.Unmarshal(v); err != nil {
		return err
	}
	value := roachpb.Value{
		RawBytes: meta.RawBytes,
	}
	return value.GetProto(dest)
}

func tryTxn(kv engine.MVCCKeyValue) (string, error) {
	var txn roachpb.Transaction
	if err := maybeUnmarshalInline(kv.Value, &txn); err != nil {
		return "", err
	}
	return txn.String() + "\n", nil
}

func trySequence(kv engine.MVCCKeyValue) (string, error) {
	if kv.Key.Timestamp != roachpb.ZeroTimestamp {
		return "", errors.New("not a sequence cache key")
	}
	_, _, _, err := keys.DecodeSequenceCacheKey(kv.Key.Key, nil)
	if err != nil {
		return "", err
	}
	var dest roachpb.SequenceCacheEntry
	if err := maybeUnmarshalInline(kv.Value, &dest); err != nil {
		return "", err
	}
	return fmt.Sprintf("ts=%s, key=%q\n", dest.Timestamp, dest.Key), nil
}

func tryRangeDescriptor(kv engine.MVCCKeyValue) (string, error) {
	_, suffix, _, err := keys.DecodeRangeKey(kv.Key.Key)
	if err != nil {
		return "", err
	}
	if !bytes.Equal(suffix, keys.LocalRangeDescriptorSuffix) {
		return "", fmt.Errorf("wrong suffix: %s", suffix)
	}
	value := roachpb.Value{
		RawBytes: kv.Value,
	}
	var desc roachpb.RangeDescriptor
	if err := value.GetProto(&desc); err != nil {
		return "", err
	}
	return descStr(desc), nil
}

func printRangeDescriptor(kv engine.MVCCKeyValue) (bool, error) {
	if out, err := tryRangeDescriptor(kv); err != nil {
		fmt.Printf("%s %q: invalid value: %v", kv.Key.Timestamp, kv.Key.Key, err)
	} else {
		fmt.Println(out)
	}
	return false, nil
}

func runDebugRangeDescriptors(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 1 {
		return errors.New("one argument is required")
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	start := engine.MakeMVCCMetadataKey(keys.LocalRangePrefix)
	end := engine.MakeMVCCMetadataKey(keys.LocalRangeMax)

	if err := db.Iterate(start, end, printRangeDescriptor); err != nil {
		return err
	}
	return nil
}

var debugRaftLogCmd = &cobra.Command{
	Use:   "raft-log [directory] [range id]",
	Short: "print the raft log for a range",
	Long: `
Prints all log entries in a store for the given range.
`,
	RunE: runDebugRaftLog,
}

func tryRaftLogEntry(kv engine.MVCCKeyValue) (string, error) {
	var ent raftpb.Entry
	if err := maybeUnmarshalInline(kv.Value, &ent); err != nil {
		return "", err
	}
	if ent.Type == raftpb.EntryNormal {
		if len(ent.Data) > 0 {
			_, cmdData := storage.DecodeRaftCommand(ent.Data)
			var cmd roachpb.RaftCommand
			if err := cmd.Unmarshal(cmdData); err != nil {
				return "", err
			}
			ent.Data = nil
			return fmt.Sprintf("%s by %v\n%s\n%s\n", &ent, cmd.OriginReplica, &cmd.Cmd, &cmd), nil
		}
		return fmt.Sprintf("%s: EMPTY\n", &ent), nil
	} else if ent.Type == raftpb.EntryConfChange {
		var cc raftpb.ConfChange
		if err := cc.Unmarshal(ent.Data); err != nil {
			return "", err
		}
		var ctx storage.ConfChangeContext
		if err := ctx.Unmarshal(cc.Context); err != nil {
			return "", err
		}
		var cmd roachpb.RaftCommand
		if err := cmd.Unmarshal(ctx.Payload); err != nil {
			return "", err
		}
		ent.Data = nil
		return fmt.Sprintf("%s\n%s\n", &ent, &cmd), nil
	}
	return "", fmt.Errorf("Unknown log entry type: %s\n", &ent)
}

func printRaftLogEntry(kv engine.MVCCKeyValue) (bool, error) {
	if out, err := tryRaftLogEntry(kv); err != nil {
		fmt.Printf("%q: %v\n\n", kv.Key.Key, err)
	} else {
		fmt.Println(out)
	}
	return false, nil
}

func runDebugRaftLog(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 2 {
		return errors.New("required arguments: dir range_id")
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	rangeID, err := parseRangeID(args[1])
	if err != nil {
		return err
	}

	start := engine.MakeMVCCMetadataKey(keys.RaftLogPrefix(rangeID))
	end := engine.MakeMVCCMetadataKey(keys.RaftLogPrefix(rangeID).PrefixEnd())

	if err := db.Iterate(start, end, printRaftLogEntry); err != nil {
		return err
	}
	return nil
}

var debugGCCmd = &cobra.Command{
	Use:   "estimate-gc [directory] [range id]",
	Short: "find out what a GC run would do",
	Long: `
Sets up (but does not run) a GC collection cycle, giving insight into how much
work would be done (assuming all intent resolution and pushes succeed).

Without a RangeID specified on the command line, runs the analysis for all
ranges individually.

Uses a hard-coded GC policy with a 24 hour TTL for old versions.
`,
	RunE: runDebugGCCmd,
}

func runDebugGCCmd(cmd *cobra.Command, args []string) error {
	stopper := stop.NewStopper()
	defer stopper.Stop()

	if len(args) != 1 {
		return errors.New("required arguments: dir")
	}

	var rangeID roachpb.RangeID
	if len(args) == 2 {
		var err error
		if rangeID, err = parseRangeID(args[1]); err != nil {
			return err
		}
	}

	db, err := openStore(cmd, args[0], stopper)
	if err != nil {
		return err
	}

	start := keys.RangeDescriptorKey(roachpb.RKeyMin)
	end := keys.RangeDescriptorKey(roachpb.RKeyMax)

	var descs []roachpb.RangeDescriptor

	if _, err := engine.MVCCIterate(db, start, end, roachpb.MaxTimestamp,
		false /* !consistent */, nil, /* txn */
		false /* !reverse */, func(kv roachpb.KeyValue) (bool, error) {
			var desc roachpb.RangeDescriptor
			_, suffix, _, err := keys.DecodeRangeKey(kv.Key)
			if err != nil {
				return false, err
			}
			if !bytes.Equal(suffix, keys.LocalRangeDescriptorSuffix) {
				return false, nil
			}
			if err := kv.Value.GetProto(&desc); err != nil {
				return false, err
			}
			if desc.RangeID == rangeID || rangeID == 0 {
				descs = append(descs, desc)
			}
			return desc.RangeID == rangeID, nil
		}); err != nil {
		return err
	}

	if len(descs) == 0 {
		return fmt.Errorf("no range matching the criteria found")
	}

	for _, desc := range descs {
		snap := db.NewSnapshot()
		defer snap.Close()
		_, info, err := storage.RunGC(&desc, snap, roachpb.Timestamp{WallTime: timeutil.Now().UnixNano()},
			config.GCPolicy{TTLSeconds: 24 * 60 * 60 /* 1 day */}, func(_ roachpb.Timestamp, _ *roachpb.Transaction, _ roachpb.PushTxnType) {
			}, func(_ []roachpb.Intent, _, _ bool) error { return nil })
		if err != nil {
			return err
		}
		fmt.Printf("RangeID: %d [%s, %s):\n", desc.RangeID, desc.StartKey, desc.EndKey)
		_, _ = pretty.Println(info)
	}
	return nil
}

func init() {
	debugCmd.AddCommand(debugCmds...)
}

var debugCmds = []*cobra.Command{
	debugKeysCmd,
	debugRangeDescriptorsCmd,
	debugRaftLogCmd,
	debugGCCmd,
	kvCmd,
	rangeCmd,
}

var debugCmd = &cobra.Command{
	Use:   "debug [command]",
	Short: "debugging commands",
	Long: `Various commands for debugging.

These commands are useful for extracting data from the data files of a
process that has failed and cannot restart.
`,
	Run: func(cmd *cobra.Command, args []string) {
		mustUsage(cmd)
	},
}
<|endoftext|>


<commit_before>// Copyright 2013 @atotto. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package clipboard read/write on clipboard
package clipboard

import ()

// ReadAll read string from clipboard
func ReadAll() (string, error) {
	return readAll()
}

// WriteAll write string to clipboard
func WriteAll(text string) error {
	return writeAll(text)
}

// Unsupported might be set true during clipboard init, to help callers decide
// whether or not to offer clipboard options.
var Unsupported bool
<commit_msg>remove unused import<commit_after>// Copyright 2013 @atotto. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package clipboard read/write on clipboard
package clipboard

// ReadAll read string from clipboard
func ReadAll() (string, error) {
	return readAll()
}

// WriteAll write string to clipboard
func WriteAll(text string) error {
	return writeAll(text)
}

// Unsupported might be set true during clipboard init, to help callers decide
// whether or not to offer clipboard options.
var Unsupported bool
<|endoftext|>


<commit_before>package bootstrap

import (
	"encoding/json"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/tinzenite/channel"
	"github.com/tinzenite/shared"
)

/*
Success is the callback that will be called once the bootstrap is complete.
*/
type Success func()

/*
Bootstrap is a temporary peer object that allows to bootstrap into an existing
Tinzenite network. NOTE: bootstrapping is only capable for now to trusted peers.
*/
type Bootstrap struct {
	path       string           // root path
	cInterface *chaninterface   // internal hidden struct for channel callbacks
	channel    *channel.Channel // tox communication channel
	peer       *shared.Peer     // self peer
	bootstrap  map[string]bool  // stores address of peers we need to bootstrap
	onDone     Success          // callback for when done
	wg         sync.WaitGroup   // stuff for background thread
	stop       chan bool        // stuff for background thread
}

/*
Start begins a bootstrap process to the given address.
*/
func (b *Bootstrap) Start(address string) error {
	// send own peer
	msg, err := json.Marshal(b.peer)
	if err != nil {
		return err
	}
	// send request
	return b.channel.RequestConnection(address, string(msg))
}

/*
Address returns the full address of this peer.
*/
func (b *Bootstrap) Address() (string, error) {
	return b.channel.ConnectionAddress()
}

/*
Store writes a bootstrapped .TINZENITEDIR to disk. Call this if you want
persistant bootstrapping (and why wouldn't you?).
*/
func (b *Bootstrap) Store() error {
	trusted := b.IsTrusted()
	var err error
	if trusted {
		err = shared.MakeTinzeniteDir(b.path)
	} else {
		err = shared.MakeEncryptedDir(b.path)
	}
	if err != nil {
		return err
	}
	// write self peer if TRUSTED peer. Encrypted don't write their own peer.
	if trusted {
		err = b.peer.StoreTo(b.path + "/" + shared.STOREPEERDIR)
	}
	if err != nil {
		return err
	}
	// store local peer info with toxdata
	toxData, err := b.channel.ToxData()
	if err != nil {
		return err
	}
	toxPeerDump := &shared.ToxPeerDump{
		SelfPeer: b.peer,
		ToxData:  toxData}
	// write toxpeerdump
	if trusted {
		err = toxPeerDump.StoreTo(b.path + "/" + shared.STORETOXDUMPDIR)
	} else {
		err = toxPeerDump.StoreTo(b.path + "/" + shared.LOCALDIR)
	}
	if err != nil {
		return err
	}
	return nil
}

/*
PrintStatus returns a formatted string of the peer status.
*/
func (b *Bootstrap) PrintStatus() string {
	var out string
	out += "Online:\n"
	addresses, err := b.channel.FriendAddresses()
	if err != nil {
		out += "channel.FriendAddresses failed!"
	} else {
		var count int
		for _, address := range addresses {
			online, err := b.channel.IsAddressOnline(address)
			var insert string
			if err != nil {
				insert = "ERROR"
			} else {
				insert = fmt.Sprintf("%v", online)
			}
			out += address[:16] + " :: " + insert + "\n"
			count++
		}
		out += "Total friends: " + fmt.Sprintf("%d", count)
	}
	return out
}

/*
IsTrusted can be used to read whether this bootstrap is creating an encrypted or
a trusted peer.
*/
func (b *Bootstrap) IsTrusted() bool {
	return b.peer.Trusted
}

/*
Close cleanly closes everything underlying.
*/
func (b *Bootstrap) Close() {
	// send stop signal
	b.stop <- true
	// wait for it to close
	b.wg.Wait()
	// finally close channel
	b.channel.Close()
}

/*
Run is the background thread that keeps checking if it can bootstrap.
*/
func (b *Bootstrap) run() {
	defer func() { log.Println("Bootstrap:", "Background process stopped.") }()
	online := false
	var interval time.Duration
	for {
		// this ensures 2 different tick spans depending on whether someone is online or not
		if online {
			interval = tickSpanOnline
		} else {
			interval = tickSpanNone
		}
		select {
		case <-b.stop:
			b.wg.Done()
			return
		case <-time.Tick(interval):
			online = false
			addresses, err := b.channel.OnlineAddresses()
			if err != nil {
				log.Println("Check:", err)
				break
			}
			if len(addresses) == 0 {
				log.Println("None available yet.")
				break
			}
			if len(addresses) > 1 {
				// since we'll always only try connecting to one, warn specifically!
				log.Println("WARNING: Multiple online! Will try connecting to ", addresses[0][:8], " only.")
			}
			online = true
			// if not trusted, we are done once the connection has been accepted.
			if !b.IsTrusted() {
				// execute callback
				b.done()
				// stop bg thread
				b.stop <- false
				// go quit
				continue
			}
			// yo, we want to bootstrap!
			rm := shared.CreateRequestMessage(shared.OtModel, shared.IDMODEL)
			b.channel.Send(addresses[0], rm.JSON())
		} // select
	} // for
}

/*
done is called to execute the callback (asynchroniously!)
*/
func (b *Bootstrap) done() {
	// notify of done
	if b.onDone != nil {
		go b.onDone()
	} else {
		log.Println("onDone is nil!")
	}
}
<commit_msg>applied improvements from enc_peer_boot branch<commit_after>package bootstrap

import (
	"encoding/json"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/tinzenite/channel"
	"github.com/tinzenite/shared"
)

/*
Success is the callback that will be called once the bootstrap is complete.
*/
type Success func()

/*
Bootstrap is a temporary peer object that allows to bootstrap into an existing
Tinzenite network. Also it is CORRECT and DESIRED that a model for a trusted peer
+is not stored between runs to allow resetting if something goes wrong.
*/
type Bootstrap struct {
	path       string           // root path
	cInterface *chaninterface   // internal hidden struct for channel callbacks
	channel    *channel.Channel // tox communication channel
	peer       *shared.Peer     // self peer
	bootstrap  map[string]bool  // stores address of peers we need to bootstrap
	onDone     Success          // callback for when done
	wg         sync.WaitGroup   // stuff for background thread
	stop       chan bool        // stuff for background thread
}

/*
Start begins a bootstrap process to the given address.
*/
func (b *Bootstrap) Start(address string) error {
	// send own peer
	msg, err := json.Marshal(b.peer)
	if err != nil {
		return err
	}
	// send request
	return b.channel.RequestConnection(address, string(msg))
}

/*
Address returns the full address of this peer.
*/
func (b *Bootstrap) Address() (string, error) {
	return b.channel.ConnectionAddress()
}

/*
Store writes a bootstrapped .TINZENITEDIR to disk. Call this if you want
persistant bootstrapping (and why wouldn't you?).
*/
func (b *Bootstrap) Store() error {
	trusted := b.IsTrusted()
	var err error
	if trusted {
		err = shared.MakeTinzeniteDir(b.path)
	} else {
		err = shared.MakeEncryptedDir(b.path)
	}
	if err != nil {
		return err
	}
	// write self peer if TRUSTED peer. Encrypted don't write their own peer.
	if trusted {
		err = b.peer.StoreTo(b.path + "/" + shared.STOREPEERDIR)
	}
	if err != nil {
		return err
	}
	// store local peer info with toxdata
	toxData, err := b.channel.ToxData()
	if err != nil {
		return err
	}
	toxPeerDump := &shared.ToxPeerDump{
		SelfPeer: b.peer,
		ToxData:  toxData}
	// write toxpeerdump
	if trusted {
		err = toxPeerDump.StoreTo(b.path + "/" + shared.STORETOXDUMPDIR)
	} else {
		err = toxPeerDump.StoreTo(b.path + "/" + shared.LOCALDIR)
	}
	if err != nil {
		return err
	}
	return nil
}

/*
PrintStatus returns a formatted string of the peer status.
*/
func (b *Bootstrap) PrintStatus() string {
	var out string
	out += "Online:\n"
	addresses, err := b.channel.FriendAddresses()
	if err != nil {
		out += "channel.FriendAddresses failed!"
	} else {
		var count int
		for _, address := range addresses {
			online, err := b.channel.IsAddressOnline(address)
			var insert string
			if err != nil {
				insert = "ERROR"
			} else {
				insert = fmt.Sprintf("%v", online)
			}
			out += address[:16] + " :: " + insert + "\n"
			count++
		}
		out += "Total friends: " + fmt.Sprintf("%d", count)
	}
	return out
}

/*
IsTrusted can be used to read whether this bootstrap is creating an encrypted or
a trusted peer.
*/
func (b *Bootstrap) IsTrusted() bool {
	return b.peer.Trusted
}

/*
Close cleanly closes everything underlying.
*/
func (b *Bootstrap) Close() {
	// send stop signal
	b.stop <- true
	// wait for it to close
	b.wg.Wait()
	// finally close channel
	b.channel.Close()
}

/*
Run is the background thread that keeps checking if it can bootstrap.
*/
func (b *Bootstrap) run() {
	defer func() { log.Println("Bootstrap:", "Background process stopped.") }()
	online := false
	var interval time.Duration
	for {
		// this ensures 2 different tick spans depending on whether someone is online or not
		if online {
			interval = tickSpanOnline
		} else {
			interval = tickSpanNone
		}
		select {
		case <-b.stop:
			b.wg.Done()
			return
		case <-time.Tick(interval):
			online = false
			addresses, err := b.channel.OnlineAddresses()
			if err != nil {
				log.Println("Check:", err)
				break
			}
			if len(addresses) == 0 {
				log.Println("None available yet.")
				break
			}
			if len(addresses) > 1 {
				// since we'll always only try connecting to one, warn specifically!
				log.Println("WARNING: Multiple online! Will try connecting to ", addresses[0][:8], " only.")
			}
			online = true
			// if not trusted, we are done once the connection has been accepted.
			if !b.IsTrusted() {
				// execute callback
				b.done()
				// stop bg thread
				b.stop <- false
				// go quit
				continue
			}
			// yo, we want to bootstrap!
			rm := shared.CreateRequestMessage(shared.OtModel, shared.IDMODEL)
			b.channel.Send(addresses[0], rm.JSON())
		} // select
	} // for
}

/*
done is called to execute the callback (asynchroniously!)
*/
func (b *Bootstrap) done() {
	// make sure background thread is done but if channel is blocked go on
	select {
	case b.stop <- true:
	default:
	}
	// notify of done
	if b.onDone != nil {
		go b.onDone()
	} else {
		log.Println("onDone is nil!")
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. 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 core

// Definition of labels supported in MetricSet.

var (
	LabelMetricSetType = LabelDescriptor{
		Key:         "type",
		Description: "Type of the metrics set (container, pod, namespace, node, cluster)",
	}
	MetricSetTypeSystemContainer = "sys_container"
	MetricSetTypePodContainer    = "pod_container"
	MetricSetTypePod             = "pod"
	MetricSetTypeNamespace       = "ns"
	MetricSetTypeNode            = "node"
	MetricSetTypeCluster         = "cluster"

	LabelPodId = LabelDescriptor{
		Key:         "pod_id",
		Description: "The unique ID of the pod",
	}
	LabelPodName = LabelDescriptor{
		Key:         "pod_name",
		Description: "The name of the pod",
	}
	// Deprecated label
	LabelPodNamespace = LabelDescriptor{
		Key:         "pod_namespace",
		Description: "The namespace of the pod",
	}
	LabelNamespaceName = LabelDescriptor{
		Key:         "namespace_name",
		Description: "The name of the namespace",
	}
	LabelPodNamespaceUID = LabelDescriptor{
		Key:         "namespace_id",
		Description: "The UID of namespace of the pod",
	}
	LabelContainerName = LabelDescriptor{
		Key:         "container_name",
		Description: "User-provided name of the container or full container name for system containers",
	}
	LabelLabels = LabelDescriptor{
		Key:         "labels",
		Description: "Comma-separated list of user-provided labels",
	}
	LabelNodename = LabelDescriptor{
		Key:         "nodename",
		Description: "nodename where the container ran",
	}
	LabelHostname = LabelDescriptor{
		Key:         "hostname",
		Description: "Hostname where the container ran",
	}
	LabelResourceID = LabelDescriptor{
		Key:         "resource_id",
		Description: "Identifier(s) specific to a metric",
	}
	LabelHostID = LabelDescriptor{
		Key:         "host_id",
		Description: "Identifier specific to a host. Set by cloud provider or user",
	}
	LabelContainerBaseImage = LabelDescriptor{
		Key:         "container_base_image",
		Description: "User-defined image name that is run inside the container",
	}
	// The label is populated only for GCM
	LabelCustomMetricName = LabelDescriptor{
		Key:         "custom_metric_name",
		Description: "User-defined name of the exported custom metric",
	}
	LabelGCEResourceID = LabelDescriptor{
		Key:         "compute.googleapis.com/resource_id",
		Description: "Resource id for nodes specific for GCE.",
	}
	LabelGCEResourceType = LabelDescriptor{
		Key:         "compute.googleapis.com/resource_type",
		Description: "Resource types for nodes specific for GCE.",
	}
)

type LabelDescriptor struct {
	// Key to use for the label.
	Key string `json:"key,omitempty"`

	// Description of the label.
	Description string `json:"description,omitempty"`
}

var commonLabels = []LabelDescriptor{
	LabelNodename,
	LabelHostname,
	LabelHostID,
}

var containerLabels = []LabelDescriptor{
	LabelContainerName,
	LabelContainerBaseImage,
}

var podLabels = []LabelDescriptor{
	LabelPodName,
	LabelPodId,
	LabelPodNamespace,
	LabelPodNamespaceUID,
	LabelLabels,
}

var metricLabels = []LabelDescriptor{
	LabelResourceID,
}

var customMetricLabels = []LabelDescriptor{
	LabelCustomMetricName,
}

// Labels exported to GCM. The number of labels that can be exported to GCM is limited by 10.
var gcmLabels = []LabelDescriptor{
	LabelMetricSetType,
	LabelPodName,
	LabelNamespaceName,
	LabelHostname,
	LabelHostID,
	LabelContainerName,
	LabelContainerBaseImage,
	LabelCustomMetricName,
}

var gcmNodeAutoscalingLabels = []LabelDescriptor{
	LabelGCEResourceID,
	LabelGCEResourceType,
	LabelHostname,
}

func CommonLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(commonLabels))
	copy(result, commonLabels)
	return result
}

func ContainerLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(containerLabels))
	copy(result, containerLabels)
	return result
}

func PodLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(podLabels))
	copy(result, podLabels)
	return result
}

func MetricLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(metricLabels)+len(customMetricLabels))
	copy(result, metricLabels)
	copy(result, customMetricLabels)
	return result
}

func SupportedLabels() []LabelDescriptor {
	result := CommonLabels()
	result = append(result, PodLabels()...)
	return append(result, MetricLabels()...)
}

func GcmLabels() map[string]LabelDescriptor {
	result := make(map[string]LabelDescriptor, len(gcmLabels))
	for _, l := range gcmLabels {
		result[l.Key] = l
	}
	return result
}
func GcmNodeAutoscalingLabels() map[string]LabelDescriptor {
	result := make(map[string]LabelDescriptor, len(gcmNodeAutoscalingLabels))
	for _, l := range gcmNodeAutoscalingLabels {
		result[l.Key] = l
	}
	return result
}
<commit_msg>Export resource id label in GCM sink<commit_after>// Copyright 2015 Google Inc. 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 core

// Definition of labels supported in MetricSet.

var (
	LabelMetricSetType = LabelDescriptor{
		Key:         "type",
		Description: "Type of the metrics set (container, pod, namespace, node, cluster)",
	}
	MetricSetTypeSystemContainer = "sys_container"
	MetricSetTypePodContainer    = "pod_container"
	MetricSetTypePod             = "pod"
	MetricSetTypeNamespace       = "ns"
	MetricSetTypeNode            = "node"
	MetricSetTypeCluster         = "cluster"

	LabelPodId = LabelDescriptor{
		Key:         "pod_id",
		Description: "The unique ID of the pod",
	}
	LabelPodName = LabelDescriptor{
		Key:         "pod_name",
		Description: "The name of the pod",
	}
	// Deprecated label
	LabelPodNamespace = LabelDescriptor{
		Key:         "pod_namespace",
		Description: "The namespace of the pod",
	}
	LabelNamespaceName = LabelDescriptor{
		Key:         "namespace_name",
		Description: "The name of the namespace",
	}
	LabelPodNamespaceUID = LabelDescriptor{
		Key:         "namespace_id",
		Description: "The UID of namespace of the pod",
	}
	LabelContainerName = LabelDescriptor{
		Key:         "container_name",
		Description: "User-provided name of the container or full container name for system containers",
	}
	LabelLabels = LabelDescriptor{
		Key:         "labels",
		Description: "Comma-separated list of user-provided labels",
	}
	LabelNodename = LabelDescriptor{
		Key:         "nodename",
		Description: "nodename where the container ran",
	}
	LabelHostname = LabelDescriptor{
		Key:         "hostname",
		Description: "Hostname where the container ran",
	}
	LabelResourceID = LabelDescriptor{
		Key:         "resource_id",
		Description: "Identifier(s) specific to a metric",
	}
	LabelHostID = LabelDescriptor{
		Key:         "host_id",
		Description: "Identifier specific to a host. Set by cloud provider or user",
	}
	LabelContainerBaseImage = LabelDescriptor{
		Key:         "container_base_image",
		Description: "User-defined image name that is run inside the container",
	}
	// The label is populated only for GCM
	LabelCustomMetricName = LabelDescriptor{
		Key:         "custom_metric_name",
		Description: "User-defined name of the exported custom metric",
	}
	LabelGCEResourceID = LabelDescriptor{
		Key:         "compute.googleapis.com/resource_id",
		Description: "Resource id for nodes specific for GCE.",
	}
	LabelGCEResourceType = LabelDescriptor{
		Key:         "compute.googleapis.com/resource_type",
		Description: "Resource types for nodes specific for GCE.",
	}
)

type LabelDescriptor struct {
	// Key to use for the label.
	Key string `json:"key,omitempty"`

	// Description of the label.
	Description string `json:"description,omitempty"`
}

var commonLabels = []LabelDescriptor{
	LabelNodename,
	LabelHostname,
	LabelHostID,
}

var containerLabels = []LabelDescriptor{
	LabelContainerName,
	LabelContainerBaseImage,
}

var podLabels = []LabelDescriptor{
	LabelPodName,
	LabelPodId,
	LabelPodNamespace,
	LabelPodNamespaceUID,
	LabelLabels,
}

var metricLabels = []LabelDescriptor{
	LabelResourceID,
}

var customMetricLabels = []LabelDescriptor{
	LabelCustomMetricName,
}

// Labels exported to GCM. The number of labels that can be exported to GCM is limited by 10.
var gcmLabels = []LabelDescriptor{
	LabelMetricSetType,
	LabelPodName,
	LabelNamespaceName,
	LabelHostname,
	LabelHostID,
	LabelContainerName,
	LabelContainerBaseImage,
	LabelCustomMetricName,
	LabelResourceID,
}

var gcmNodeAutoscalingLabels = []LabelDescriptor{
	LabelGCEResourceID,
	LabelGCEResourceType,
	LabelHostname,
}

func CommonLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(commonLabels))
	copy(result, commonLabels)
	return result
}

func ContainerLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(containerLabels))
	copy(result, containerLabels)
	return result
}

func PodLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(podLabels))
	copy(result, podLabels)
	return result
}

func MetricLabels() []LabelDescriptor {
	result := make([]LabelDescriptor, len(metricLabels)+len(customMetricLabels))
	copy(result, metricLabels)
	copy(result, customMetricLabels)
	return result
}

func SupportedLabels() []LabelDescriptor {
	result := CommonLabels()
	result = append(result, PodLabels()...)
	return append(result, MetricLabels()...)
}

func GcmLabels() map[string]LabelDescriptor {
	result := make(map[string]LabelDescriptor, len(gcmLabels))
	for _, l := range gcmLabels {
		result[l.Key] = l
	}
	return result
}
func GcmNodeAutoscalingLabels() map[string]LabelDescriptor {
	result := make(map[string]LabelDescriptor, len(gcmNodeAutoscalingLabels))
	for _, l := range gcmNodeAutoscalingLabels {
		result[l.Key] = l
	}
	return result
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/eneco/landscaper/pkg/landscaper"
	"github.com/spf13/cobra"
)

var prefixDisable bool

var addCmd = &cobra.Command{
	Use:   "apply",
	Short: "Makes the current landscape match the desired landscape",
	RunE: func(cmd *cobra.Command, args []string) error {
		// setup env
		if prefixDisable {
			env.ReleaseNamePrefix = ""
		} else {
			if env.ReleaseNamePrefix == "" {
				env.ReleaseNamePrefix = fmt.Sprintf("%s-", env.Namespace) // prefix not overridden; default to '<namespace>-'
			}
		}
		env.ChartLoader = landscaper.NewLocalCharts(env.ChartDir)

		v := landscaper.GetVersion()
		logrus.WithFields(logrus.Fields{"tag": v.GitTag, "commit": v.GitCommit}).Infof("This is Landscaper v%s", v.SemVer)
		logrus.WithFields(logrus.Fields{"namespace": env.Namespace, "releasePrefix": env.ReleaseNamePrefix, "dir": env.LandscapeDir, "dryRun": env.DryRun, "chartDir": env.ChartDir, "verbose": env.Verbose}).Info("Apply landscape desired state")

		sp := landscaper.NewSecretsProvider(env)
		cp := landscaper.NewComponentProvider(env, sp)
		executor := landscaper.NewExecutor(env, sp)

		desired, err := cp.Desired()
		if err != nil {
			logrus.WithFields(logrus.Fields{"error": err}).Error("Loading desired state failed")
			return err
		}

		current, err := cp.Current()
		if err != nil {
			logrus.WithFields(logrus.Fields{"error": err}).Error("Loading current state failed")
			return err
		}

		if err = executor.Apply(desired, current); err != nil {
			logrus.WithFields(logrus.Fields{"error": err}).Error("Applying desired state failed")
			return err
		}

		if env.DryRun {
			logrus.Warn("Since dry-run is enabled, no actual actions have been performed")
		}

		return nil
	},
}

func init() {
	f := addCmd.Flags()

	landscapePrefix := os.Getenv("LANDSCAPE_PREFIX")

	landscapeDir := os.Getenv("LANDSCAPE_DIR")
	if landscapeDir == "" {
		landscapeDir = "."
	}

	landscapeNamespace := os.Getenv("LANDSCAPE_NAMESPACE")
	if landscapeNamespace == "" {
		landscapeNamespace = "acceptance"
	}

	chartDir := os.ExpandEnv("$HOME/.helm")

	f.BoolVar(&env.DryRun, "dry-run", false, "simulate the applying of the landscape. useful in merge requests")
	f.BoolVarP(&env.Verbose, "verbose", "v", false, "be verbose")
	f.BoolVar(&prefixDisable, "no-prefix", false, "disable prefixing release names")
	f.StringVar(&env.ReleaseNamePrefix, "prefix", landscapePrefix, "prefix release names with this string instead of <namespace>; overrides LANDSCAPE_PREFIX")
	f.StringVar(&env.LandscapeDir, "dir", landscapeDir, "path to a folder that contains all the landscape desired state files; overrides LANDSCAPE_DIR")
	f.StringVar(&env.Namespace, "namespace", landscapeNamespace, "namespace to apply the landscape to; overrides LANDSCAPE_NAMESPACE")
	f.StringVar(&env.ChartDir, "chart-dir", chartDir, "where the charts are stored")
	f.BoolVar(&env.NoCronUpdate, "no-cronjob-update", false, "replaces CronJob updates with a create+delete; k8s #35149 work around")

	rootCmd.AddCommand(addCmd)
}
<commit_msg>Use 'default' as default namespace; fix #9<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/eneco/landscaper/pkg/landscaper"
	"github.com/spf13/cobra"
)

var prefixDisable bool

var addCmd = &cobra.Command{
	Use:   "apply",
	Short: "Makes the current landscape match the desired landscape",
	RunE: func(cmd *cobra.Command, args []string) error {
		// setup env
		if prefixDisable {
			env.ReleaseNamePrefix = ""
		} else {
			if env.ReleaseNamePrefix == "" {
				env.ReleaseNamePrefix = fmt.Sprintf("%s-", env.Namespace) // prefix not overridden; default to '<namespace>-'
			}
		}
		env.ChartLoader = landscaper.NewLocalCharts(env.ChartDir)

		v := landscaper.GetVersion()
		logrus.WithFields(logrus.Fields{"tag": v.GitTag, "commit": v.GitCommit}).Infof("This is Landscaper v%s", v.SemVer)
		logrus.WithFields(logrus.Fields{"namespace": env.Namespace, "releasePrefix": env.ReleaseNamePrefix, "dir": env.LandscapeDir, "dryRun": env.DryRun, "chartDir": env.ChartDir, "verbose": env.Verbose}).Info("Apply landscape desired state")

		sp := landscaper.NewSecretsProvider(env)
		cp := landscaper.NewComponentProvider(env, sp)
		executor := landscaper.NewExecutor(env, sp)

		desired, err := cp.Desired()
		if err != nil {
			logrus.WithFields(logrus.Fields{"error": err}).Error("Loading desired state failed")
			return err
		}

		current, err := cp.Current()
		if err != nil {
			logrus.WithFields(logrus.Fields{"error": err}).Error("Loading current state failed")
			return err
		}

		if err = executor.Apply(desired, current); err != nil {
			logrus.WithFields(logrus.Fields{"error": err}).Error("Applying desired state failed")
			return err
		}

		if env.DryRun {
			logrus.Warn("Since dry-run is enabled, no actual actions have been performed")
		}

		return nil
	},
}

func init() {
	f := addCmd.Flags()

	landscapePrefix := os.Getenv("LANDSCAPE_PREFIX")

	landscapeDir := os.Getenv("LANDSCAPE_DIR")
	if landscapeDir == "" {
		landscapeDir = "."
	}

	landscapeNamespace := os.Getenv("LANDSCAPE_NAMESPACE")
	if landscapeNamespace == "" {
		landscapeNamespace = "default"
	}

	chartDir := os.ExpandEnv("$HOME/.helm")

	f.BoolVar(&env.DryRun, "dry-run", false, "simulate the applying of the landscape. useful in merge requests")
	f.BoolVarP(&env.Verbose, "verbose", "v", false, "be verbose")
	f.BoolVar(&prefixDisable, "no-prefix", false, "disable prefixing release names")
	f.StringVar(&env.ReleaseNamePrefix, "prefix", landscapePrefix, "prefix release names with this string instead of <namespace>; overrides LANDSCAPE_PREFIX")
	f.StringVar(&env.LandscapeDir, "dir", landscapeDir, "path to a folder that contains all the landscape desired state files; overrides LANDSCAPE_DIR")
	f.StringVar(&env.Namespace, "namespace", landscapeNamespace, "namespace to apply the landscape to; overrides LANDSCAPE_NAMESPACE")
	f.StringVar(&env.ChartDir, "chart-dir", chartDir, "where the charts are stored")
	f.BoolVar(&env.NoCronUpdate, "no-cronjob-update", false, "replaces CronJob updates with a create+delete; k8s #35149 work around")

	rootCmd.AddCommand(addCmd)
}
<|endoftext|>


<commit_before>package cmd

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

	"github.com/codegangsta/cli"
	"github.com/exercism/cli/config"
	"github.com/exercism/cli/paths"
)

// Debug provides information about the user's environment and configuration.
func Debug(ctx *cli.Context) {
	defer fmt.Printf("\nIf you are having trouble and need to file a GitHub issue (https://github.com/exercism/exercism.io/issues) please include this information (except your API key. Keep that private).\n")

	client := http.Client{Timeout: 5 * time.Second}

	fmt.Printf("\n**** Debug Information ****\n")
	fmt.Printf("Exercism CLI Version: %s\n", ctx.App.Version)

	rel, err := fetchLatestRelease(client)
	if err != nil {
		log.Println("unable to fetch latest release: " + err.Error())
	} else {
		if rel.Version() != ctx.App.Version {
			defer fmt.Printf("\nA newer version of the CLI (%s) can be downloaded here: %s\n", rel.TagName, rel.Location)
		}
		fmt.Printf("Exercism CLI Latest Release: %s\n", rel.Version())
	}

	fmt.Printf("OS/Architecture: %s/%s\n", runtime.GOOS, runtime.GOARCH)
	fmt.Printf("Build OS/Architecture %s/%s\n", BuildOS, BuildARCH)
	if BuildARM != "" {
		fmt.Printf("Build ARMv%s\n", BuildARM)
	}

	fmt.Printf("Home Dir: %s\n", paths.Home)

	c, err := config.New(ctx.GlobalString("config"))
	if err != nil {
		log.Fatal(err)
	}

	configured := true
	if _, err = os.Stat(c.File); err != nil {
		if os.IsNotExist(err) {
			configured = false
		} else {
			log.Fatal(err)
		}
	}

	if configured {
		fmt.Printf("Config file: %s\n", c.File)
		fmt.Printf("API Key: %s\n", c.APIKey)
	} else {
		fmt.Println("Config file: <not configured>")
		fmt.Println("API Key: <not configured>")
	}

	fmt.Printf("API: %s [%s]\n", c.API, pingURL(client, c.API))
	fmt.Printf("XAPI: %s [%s]\n", c.XAPI, pingURL(client, c.XAPI))
	fmt.Printf("Exercises Directory: %s\n", c.Dir)
}

func pingURL(client http.Client, url string) string {
	res, err := client.Get(url)
	if err != nil {
		return err.Error()
	}
	defer res.Body.Close()

	return "connected"
}
<commit_msg>Add debug API call timing. Also, increased the timeout to 20 seconds which gives slow clients a bit more time to complete the calls<commit_after>package cmd

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"runtime"
	"sync"
	"time"

	"github.com/codegangsta/cli"
	"github.com/exercism/cli/config"
	"github.com/exercism/cli/paths"
)

type pingResult struct {
	URL     string
	Service string
	Status  string
	Latency time.Duration
}

// Debug provides information about the user's environment and configuration.
func Debug(ctx *cli.Context) {
	defer fmt.Printf("\nIf you are having trouble and need to file a GitHub issue (https://github.com/exercism/exercism.io/issues) please include this information (except your API key. Keep that private).\n")

	client := &http.Client{Timeout: 20 * time.Second}

	fmt.Printf("\n**** Debug Information ****\n")
	fmt.Printf("Exercism CLI Version: %s\n", ctx.App.Version)

	rel, err := fetchLatestRelease(*client)
	if err != nil {
		log.Println("unable to fetch latest release: " + err.Error())
	} else {
		if rel.Version() != ctx.App.Version {
			defer fmt.Printf("\nA newer version of the CLI (%s) can be downloaded here: %s\n", rel.TagName, rel.Location)
		}
		fmt.Printf("Exercism CLI Latest Release: %s\n", rel.Version())
	}

	fmt.Printf("OS/Architecture: %s/%s\n", runtime.GOOS, runtime.GOARCH)
	fmt.Printf("Build OS/Architecture %s/%s\n", BuildOS, BuildARCH)
	if BuildARM != "" {
		fmt.Printf("Build ARMv%s\n", BuildARM)
	}

	fmt.Printf("Home Dir: %s\n", paths.Home)

	c, err := config.New(ctx.GlobalString("config"))
	if err != nil {
		log.Fatal(err)
	}

	configured := true
	if _, err = os.Stat(c.File); err != nil {
		if os.IsNotExist(err) {
			configured = false
		} else {
			log.Fatal(err)
		}
	}

	if configured {
		fmt.Printf("Config file: %s\n", c.File)
		fmt.Printf("API Key: %s\n", c.APIKey)
	} else {
		fmt.Println("Config file: <not configured>")
		fmt.Println("API Key: <not configured>")
	}
	fmt.Printf("Exercises Directory: %s\n", c.Dir)

	fmt.Println("Testing API endpoints reachability")

	endpoints := map[string]string{
		"API":        c.API,
		"XAPI":       c.XAPI,
		"GitHub API": "https://api.github.com/",
	}

	var wg sync.WaitGroup
	results := make(chan pingResult)
	defer close(results)

	wg.Add(len(endpoints))

	for service, url := range endpoints {
		go func(service, url string) {
			now := time.Now()
			res, err := client.Get(url)
			delta := time.Since(now)
			if err != nil {
				results <- pingResult{
					URL:     url,
					Service: service,
					Status:  err.Error(),
					Latency: delta,
				}
				return
			}
			defer res.Body.Close()

			results <- pingResult{
				URL:     url,
				Service: service,
				Status:  "connected",
				Latency: delta,
			}
		}(service, url)
	}

	go func() {
		for r := range results {
			fmt.Printf(
				"\t* %s: %s [%s] %s\n",
				r.Service,
				r.URL,
				r.Status,
				r.Latency,
			)
			wg.Done()
		}
	}()

	wg.Wait()
}
<|endoftext|>


<commit_before>package cmd

import (
	"log"
	"net/http"

	"github.com/cagedtornado/centralconfig/api"
	"github.com/cagedtornado/centralconfig/datastores"

	"github.com/gorilla/mux"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	serverInterface   string
	serverPort        int
	serverUIDirectory string
)

// serveCmd represents the serve command
var serveCmd = &cobra.Command{
	Use:   "serve",
	Short: "Start the config server",
	Long: `Centralconfig provides its own webserver which can serve both the
	API and the UI for the app.`,
	Run: serve,
}

func serve(cmd *cobra.Command, args []string) {

	//	If we have a config file, report it:
	if viper.ConfigFileUsed() != "" {
		log.Println("[INFO] Using config file:", viper.ConfigFileUsed())
	}

	//	Log the datastore information we have:
	logDatastoreInfo()

	//	Create a router and setup our REST endpoints...
	var Router = mux.NewRouter()

	//	Setup our routes
	Router.HandleFunc("/", api.ShowUI)
	Router.HandleFunc("/config/get", api.GetConfig)
	Router.HandleFunc("/config/set", api.SetConfig)
	Router.HandleFunc("/config/remove", api.RemoveConfig)
	Router.HandleFunc("/config/getall", api.GetAllConfig)
	Router.HandleFunc("/config/getallforapp", api.GetAllConfigForApp)
	Router.HandleFunc("/config/init", api.InitStore)
	Router.HandleFunc("/applications/getall", api.GetAllApplications)

	//	If we don't have a UI directory specified...
	if viper.GetString("server.ui-dir") == "" {
		//	Use the static assets file generated with
		//	https://github.com/elazarl/go-bindata-assetfs using the centralconfig-ui from
		//	https://github.com/danesparza/centralconfig-ui.
		//
		//	To generate this file, place the 'ui'
		//	directory under the main centralconfig directory and run the commands:
		//	go-bindata-assetfs.exe -pkg cmd ./ui/...
		//	mv bindata_assetfs.go cmd
		//	go install ./...
		Router.PathPrefix("/ui").Handler(http.StripPrefix("/ui", http.FileServer(assetFS())))
	} else {
		//	Use the supplied directory:
		log.Printf("[INFO] Using UI directory: %s\n", viper.GetString("server.ui-dir"))
		Router.PathPrefix("/ui").Handler(http.StripPrefix("/ui", http.FileServer(http.Dir(viper.GetString("server.ui-dir")))))
	}

	//	Format the bound interface:
	formattedInterface := viper.GetString("server.bind")
	if formattedInterface == "" {
		formattedInterface = "127.0.0.1"
	}

	//	If we have an SSL cert specified, use it:
	if viper.GetString("server.sslcert") != "" {
		log.Printf("[INFO] Using SSL cert: %s\n", viper.GetString("server.sslcert"))
		log.Printf("[INFO] Using SSL key: %s\n", viper.GetString("server.sslkey"))
		log.Printf("[INFO] Starting HTTPS server: https://%s:%s\n", formattedInterface, viper.GetString("server.port"))

		log.Printf("%v\n", http.ListenAndServeTLS(viper.GetString("server.bind")+":"+viper.GetString("server.port"), viper.GetString("server.sslcert"), viper.GetString("server.sslkey"), Router))
	} else {
		log.Printf("[INFO] Starting HTTP server: http://%s:%s\n", formattedInterface, viper.GetString("server.port"))
		log.Printf("%v\n", http.ListenAndServe(viper.GetString("server.bind")+":"+viper.GetString("server.port"), Router))
	}
}

func init() {
	RootCmd.AddCommand(serveCmd)

	//	Setup our flags
	serveCmd.Flags().IntVarP(&serverPort, "port", "p", 1313, "port on which the server will listen")
	serveCmd.Flags().StringVarP(&serverInterface, "bind", "i", "", "interface to which the server will bind")
	serveCmd.Flags().StringVarP(&serverUIDirectory, "ui-dir", "u", "", "directory for the UI")

	//	Bind config flags for optional config file override:
	viper.BindPFlag("server.port", serveCmd.Flags().Lookup("port"))
	viper.BindPFlag("server.bind", serveCmd.Flags().Lookup("bind"))
	viper.BindPFlag("server.ui-dir", serveCmd.Flags().Lookup("ui-dir"))
}

func logDatastoreInfo() {
	//	Get configuration information
	ds := datastores.GetConfigDatastore()

	switch t := ds.(type) {
	case datastores.MySqlDB:
		log.Printf("[INFO] Using MySQL server: %s\n", ds.(datastores.MySqlDB).Address)
		log.Printf("[INFO] Using MySQL database: %s\n", ds.(datastores.MySqlDB).Database)
	case datastores.MSSqlDB:
		log.Printf("[INFO] Using MSSQL server: %s\n", ds.(datastores.MSSqlDB).Address)
		log.Printf("[INFO] Using MSSQL database: %s\n", ds.(datastores.MSSqlDB).Database)
	case datastores.BoltDB:
		log.Printf("[INFO] Using BoltDB database: %s\n", ds.(datastores.BoltDB).Database)
	default:
		_ = t
		log.Println("[ERROR] Can't determine datastore type")
	}
}
<commit_msg>Adjusted server error reporting<commit_after>package cmd

import (
	"log"
	"net/http"

	"github.com/cagedtornado/centralconfig/api"
	"github.com/cagedtornado/centralconfig/datastores"

	"github.com/gorilla/mux"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	serverInterface   string
	serverPort        int
	serverUIDirectory string
)

// serveCmd represents the serve command
var serveCmd = &cobra.Command{
	Use:   "serve",
	Short: "Start the config server",
	Long: `Centralconfig provides its own webserver which can serve both the
	API and the UI for the app.`,
	Run: serve,
}

func serve(cmd *cobra.Command, args []string) {

	//	If we have a config file, report it:
	if viper.ConfigFileUsed() != "" {
		log.Println("[INFO] Using config file:", viper.ConfigFileUsed())
	}

	//	Log the datastore information we have:
	logDatastoreInfo()

	//	Create a router and setup our REST endpoints...
	var Router = mux.NewRouter()

	//	Setup our routes
	Router.HandleFunc("/", api.ShowUI)
	Router.HandleFunc("/config/get", api.GetConfig)
	Router.HandleFunc("/config/set", api.SetConfig)
	Router.HandleFunc("/config/remove", api.RemoveConfig)
	Router.HandleFunc("/config/getall", api.GetAllConfig)
	Router.HandleFunc("/config/getallforapp", api.GetAllConfigForApp)
	Router.HandleFunc("/config/init", api.InitStore)
	Router.HandleFunc("/applications/getall", api.GetAllApplications)

	//	If we don't have a UI directory specified...
	if viper.GetString("server.ui-dir") == "" {
		//	Use the static assets file generated with
		//	https://github.com/elazarl/go-bindata-assetfs using the centralconfig-ui from
		//	https://github.com/danesparza/centralconfig-ui.
		//
		//	To generate this file, place the 'ui'
		//	directory under the main centralconfig directory and run the commands:
		//	go-bindata-assetfs.exe -pkg cmd ./ui/...
		//	mv bindata_assetfs.go cmd
		//	go install ./...
		Router.PathPrefix("/ui").Handler(http.StripPrefix("/ui", http.FileServer(assetFS())))
	} else {
		//	Use the supplied directory:
		log.Printf("[INFO] Using UI directory: %s\n", viper.GetString("server.ui-dir"))
		Router.PathPrefix("/ui").Handler(http.StripPrefix("/ui", http.FileServer(http.Dir(viper.GetString("server.ui-dir")))))
	}

	//	Format the bound interface:
	formattedInterface := viper.GetString("server.bind")
	if formattedInterface == "" {
		formattedInterface = "127.0.0.1"
	}

	//	If we have an SSL cert specified, use it:
	if viper.GetString("server.sslcert") != "" {
		log.Printf("[INFO] Using SSL cert: %s\n", viper.GetString("server.sslcert"))
		log.Printf("[INFO] Using SSL key: %s\n", viper.GetString("server.sslkey"))
		log.Printf("[INFO] Starting HTTPS server: https://%s:%s\n", formattedInterface, viper.GetString("server.port"))

		log.Printf("[ERROR] %v\n", http.ListenAndServeTLS(viper.GetString("server.bind")+":"+viper.GetString("server.port"), viper.GetString("server.sslcert"), viper.GetString("server.sslkey"), Router))
	} else {
		log.Printf("[INFO] Starting HTTP server: http://%s:%s\n", formattedInterface, viper.GetString("server.port"))
		log.Printf("[ERROR] %v\n", http.ListenAndServe(viper.GetString("server.bind")+":"+viper.GetString("server.port"), Router))
	}
}

func init() {
	RootCmd.AddCommand(serveCmd)

	//	Setup our flags
	serveCmd.Flags().IntVarP(&serverPort, "port", "p", 1313, "port on which the server will listen")
	serveCmd.Flags().StringVarP(&serverInterface, "bind", "i", "", "interface to which the server will bind")
	serveCmd.Flags().StringVarP(&serverUIDirectory, "ui-dir", "u", "", "directory for the UI")

	//	Bind config flags for optional config file override:
	viper.BindPFlag("server.port", serveCmd.Flags().Lookup("port"))
	viper.BindPFlag("server.bind", serveCmd.Flags().Lookup("bind"))
	viper.BindPFlag("server.ui-dir", serveCmd.Flags().Lookup("ui-dir"))
}

func logDatastoreInfo() {
	//	Get configuration information
	ds := datastores.GetConfigDatastore()

	switch t := ds.(type) {
	case datastores.MySqlDB:
		log.Printf("[INFO] Using MySQL server: %s\n", ds.(datastores.MySqlDB).Address)
		log.Printf("[INFO] Using MySQL database: %s\n", ds.(datastores.MySqlDB).Database)
	case datastores.MSSqlDB:
		log.Printf("[INFO] Using MSSQL server: %s\n", ds.(datastores.MSSqlDB).Address)
		log.Printf("[INFO] Using MSSQL database: %s\n", ds.(datastores.MSSqlDB).Database)
	case datastores.BoltDB:
		log.Printf("[INFO] Using BoltDB database: %s\n", ds.(datastores.BoltDB).Database)
	default:
		_ = t
		log.Println("[ERROR] Can't determine datastore type")
	}
}
<|endoftext|>


<commit_before>package jwt

import (
	"errors"
	"fmt"
	"reflect"

	"golang.org/x/net/context"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/go-kit/kit/endpoint"
)

const (
	// JWTContextKey holds the key used to store a JWT Token in the context
	JWTTokenContextKey = "JWTToken"
	// JWTContextKey holds the key used to store a JWT in the context
	JWTClaimsContextKey = "JWTClaims"
)

// Create a new JWT token generating middleware, specifying signing method and the claims
// you would like it to contain. Particularly useful for clients.
func NewSigner(key string, method jwt.SigningMethod, claims jwt.Claims) endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			token := jwt.NewWithClaims(method, claims)

			// Sign and get the complete encoded token as a string using the secret
			tokenString, err := token.SignedString([]byte(key))
			if err != nil {
				return nil, err
			}
			ctx = context.WithValue(ctx, JWTTokenContextKey, tokenString)

			return next(ctx, request)
		}
	}
}

// Create a new JWT token parsing middleware, specifying a jwt.Keyfunc interface and the
// signing method. Adds the resulting claims to endpoint context or returns error on invalid
// token. Particularly useful for servers.
func NewParser(keyFunc jwt.Keyfunc, method jwt.SigningMethod) endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			// tokenString is stored in the context from the transport handlers
			tokenString, ok := ctx.Value(JWTTokenContextKey).(string)
			if !ok {
				return nil, errors.New("Token up for parsing was not passed through the context")
			}

			// Parse takes the token string and a function for looking up the key. The latter is especially
			// useful if you use multiple keys for your application.  The standard is to use 'kid' in the
			// head of the token to identify which key to use, but the parsed token (head and claims) is provided
			// to the callback, providing flexibility.
			token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
				// Don't forget to validate the alg is what you expect:
				if reflect.TypeOf(token.Method) != reflect.TypeOf(method) {
					return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
				}
				return keyFunc(token)
			})
			if err != nil {
				return nil, err
			}

			if !token.Valid {
				return nil, errors.New("Could not parse JWT Token")
			}

			if claims, ok := token.Claims.(jwt.MapClaims); ok {
				ctx = context.WithValue(ctx, JWTClaimsContextKey, claims)
			}

			return next(ctx, request)
		}
	}
}
<commit_msg>Refactor away from passing a function to passing a struct with multiple options for signing keys<commit_after>package jwt

import (
	"errors"

	"golang.org/x/net/context"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/go-kit/kit/endpoint"
)

const (
	// JWTContextKey holds the key used to store a JWT Token in the context
	JWTTokenContextKey = "JWTToken"
	// JWTContextKey holds the key used to store a JWT in the context
	JWTClaimsContextKey = "JWTClaims"
)

var (
	ErrTokenContextMissing     = errors.New("Token up for parsing was not passed through the context")
	ErrTokenInvalid            = errors.New("JWT Token was invalid")
	ErrUnexpectedSigningMethod = errors.New("Unexptected signing method")
	ErrKIDNotFound             = errors.New("Key ID was not found in key set")
	ErrNoKIDHeader             = errors.New("Token doesn't have 'kid' header")
)

type Claims map[string]interface{}

type KeySet map[string]struct {
	Method jwt.SigningMethod
	Key    []byte
}

// Create a new JWT token generating middleware, specifying signing method and the claims
// you would like it to contain. Particularly useful for clients.
func NewSigner(kid string, keys KeySet, claims Claims) endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			key, ok := keys[kid]
			if !ok {
				return nil, ErrKIDNotFound
			}

			token := jwt.NewWithClaims(key.Method, jwt.MapClaims(claims))
			token.Header["kid"] = kid
			// Sign and get the complete encoded token as a string using the secret
			tokenString, err := token.SignedString(key.Key)
			if err != nil {
				return nil, err
			}
			ctx = context.WithValue(ctx, JWTTokenContextKey, tokenString)

			return next(ctx, request)
		}
	}
}

// Create a new JWT token parsing middleware, specifying a jwt.Keyfunc interface and the
// signing method. Adds the resulting claims to endpoint context or returns error on invalid
// token. Particularly useful for servers.
func NewParser(keys KeySet) endpoint.Middleware {
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			// tokenString is stored in the context from the transport handlers
			tokenString, ok := ctx.Value(JWTTokenContextKey).(string)
			if !ok {
				return nil, ErrTokenContextMissing
			}

			// Parse takes the token string and a function for looking up the key. The latter is especially
			// useful if you use multiple keys for your application.  The standard is to use 'kid' in the
			// head of the token to identify which key to use, but the parsed token (head and claims) is provided
			// to the callback, providing flexibility.
			token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
				kid, ok := token.Header["kid"]
				if !ok {
					return nil, ErrNoKIDHeader
				}

				key, ok := keys[kid.(string)]
				if !ok {
					return nil, ErrKIDNotFound
				}

				// Don't forget to validate the alg is what you expect:
				if token.Method != key.Method {
					return nil, ErrUnexpectedSigningMethod
				}

				return key.Key, nil
			})
			if err != nil {
				return nil, err
			}

			if !token.Valid {
				return nil, ErrTokenInvalid
			}

			if claims, ok := token.Claims.(jwt.MapClaims); ok {
				ctx = context.WithValue(ctx, JWTClaimsContextKey, Claims(claims))
			}

			return next(ctx, request)
		}
	}
}
<|endoftext|>


<commit_before>package life

import "bytes"

type Grid struct {
	relations map[*cell][]*cell
	cells     [][]*cell
}

func New(grid string) *Grid {
	self := new(Grid)
	self.cells = initialize(grid)
	self.relations = formRelationships(self.cells)
	return self
}
func initialize(grid string) [][]*cell {
	var rows [][]*cell
	var row []*cell

	for _, c := range grid {
		if c == '\n' && len(row) > 0 {
			rows = append(rows, row)
			row = []*cell{}
		} else if c == '-' {
			row = append(row, newDeadCell())
		} else if c == 'x' {
			row = append(row, newLiveCell())
		}
	}
	if len(row) > 0 {
		rows = append(rows, row)
	}
	return rows
}
func formRelationships(grid [][]*cell) map[*cell][]*cell {
	relations := map[*cell][]*cell{}

	for y, row := range grid {
		for x, cell := range row {
			relations[cell] = neighbors(grid, x, y)
		}
	}
	return relations
}
func neighbors(grid [][]*cell, x, y int) []*cell {
	var yes []*cell

	for _, candidate := range adjoining(x, y) {
		if candidate.isOnGrid(grid) {
			yes = append(yes, grid[candidate.y][candidate.x])
		}
	}
	return yes
}
func adjoining(x, y int) []point {
	return []point{
		{x - 1, y - 1}, // upper left
		{x, y - 1},     // upper
		{x + 1, y - 1}, // upper right
		{x - 1, y},     // left
		{x + 1, y},     // right
		{x - 1, y + 1}, // lower left
		{x, y + 1},     // lower
		{x + 1, y + 1}, // lower right
	}
}

func (self *Grid) Scan() {
	for cell, neighbors := range self.relations {
		cell.scan(neighbors)
	}

	for cell := range self.relations {
		cell.update()
	}
}

func (self *Grid) String() string {
	builder := bytes.NewBufferString("\n")
	for _, row := range self.cells {
		for _, cell := range row {
			if cell.isAlive() {
				builder.WriteString("x")
			} else {
				builder.WriteString("-")
			}
		}
		builder.WriteString("\n")
	}
	return builder.String()
}

type point struct {
	x int
	y int
}

func (self point) isOnGrid(grid [][]*cell) bool {
	return self.x >= 0 &&
		self.y >= 0 &&
		self.x < len(grid[0]) &&
		self.y < len(grid)
}
<commit_msg>How many cells are currently alive?<commit_after>package life

import (
	"bytes"
	"strings"
)

type Grid struct {
	relations map[*cell][]*cell
	cells     [][]*cell
}

func New(grid string) *Grid {
	self := new(Grid)
	self.cells = initialize(grid)
	self.relations = formRelationships(self.cells)
	return self
}
func initialize(grid string) [][]*cell {
	var rows [][]*cell
	var row []*cell

	for _, c := range grid {
		if c == '\n' && len(row) > 0 {
			rows = append(rows, row)
			row = []*cell{}
		} else if c == '-' {
			row = append(row, newDeadCell())
		} else if c == 'x' {
			row = append(row, newLiveCell())
		}
	}
	if len(row) > 0 {
		rows = append(rows, row)
	}
	return rows
}
func formRelationships(grid [][]*cell) map[*cell][]*cell {
	relations := map[*cell][]*cell{}

	for y, row := range grid {
		for x, cell := range row {
			relations[cell] = neighbors(grid, x, y)
		}
	}
	return relations
}
func neighbors(grid [][]*cell, x, y int) []*cell {
	var yes []*cell

	for _, candidate := range adjoining(x, y) {
		if candidate.isOnGrid(grid) {
			yes = append(yes, grid[candidate.y][candidate.x])
		}
	}
	return yes
}
func adjoining(x, y int) []point {
	return []point{
		{x - 1, y - 1}, // upper left
		{x, y - 1},     // upper
		{x + 1, y - 1}, // upper right
		{x - 1, y},     // left
		{x + 1, y},     // right
		{x - 1, y + 1}, // lower left
		{x, y + 1},     // lower
		{x + 1, y + 1}, // lower right
	}
}

func (self *Grid) Scan() {
	for cell, neighbors := range self.relations {
		cell.scan(neighbors)
	}

	for cell := range self.relations {
		cell.update()
	}
}

func (self *Grid) String() string {
	builder := bytes.NewBufferString("\n")
	for _, row := range self.cells {
		for _, cell := range row {
			if cell.isAlive() {
				builder.WriteString("x")
			} else {
				builder.WriteString("-")
			}
		}
		builder.WriteString("\n")
	}
	return builder.String()
}

type point struct {
	x int
	y int
}

func (self point) isOnGrid(grid [][]*cell) bool {
	return self.x >= 0 &&
		self.y >= 0 &&
		self.x < len(grid[0]) &&
		self.y < len(grid)
}

func (this *Grid) CountAlive() int {
	return strings.Count(this.String(), "x")
}
<|endoftext|>