<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

package fxa

import (
	"code.google.com/p/go.crypto/hkdf"
	"code.google.com/p/go.crypto/pbkdf2"
	"crypto/sha256"
	"io"
)

func quickStretchPassword(email, password string) []byte {
	salt := "identity.mozilla.com/picl/v1/quickStretch:" + email
	return pbkdf2.Key([]byte(password), []byte(salt), 1000, 32, sha256.New)
}

func deriveAuthPWFromQuickStretchedPassword(stretchedPassword []byte) ([]byte, error) {
	secret := make([]byte, sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, stretchedPassword, nil, []byte("identity.mozilla.com/picl/v1/authPW")), secret); err != nil {
		return nil, err
	}
	return secret, nil
}

func deriveUnwrapBKeyFromQuickStretchedPassword(stretchedPassword []byte) ([]byte, error) {
	secret := make([]byte, sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, stretchedPassword, nil, []byte("identity.mozilla.com/picl/v1/unwrapBkey")), secret); err != nil {
		return nil, err
	}
	return secret, nil
}

type requestCredentials struct {
	TokenId        []byte
	RequestHMACKey []byte
	RequestKey     []byte
}

func newRequestCredentials(token []byte, name string) (*requestCredentials, error) {
	secret := make([]byte, 3*sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, token, nil, []byte("identity.mozilla.com/picl/v1/"+name)), secret); err != nil {
		return nil, err
	}
	return &requestCredentials{
		TokenId:        secret[0:32],
		RequestHMACKey: secret[32:64],
		RequestKey:     secret[64:96],
	}, nil
}

type accountKeys struct {
	HMACKey []byte
	XORKey  []byte
}

func newAccountKeys(requestKey []byte) (*accountKeys, error) {
	secret := make([]byte, 3*sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, requestKey, nil, []byte("identity.mozilla.com/picl/v1/account/keys")), secret); err != nil {
		return nil, err
	}
	return &accountKeys{
		HMACKey: secret[0:32],
		XORKey:  secret[32:96],
	}, nil
}
<commit_msg>Update old code.google.com dependencies<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

package fxa

import (
	"golang.org/x/crypto/hkdf"
	"golang.org/x/crypto/pbkdf2"
	"crypto/sha256"
	"io"
)

func quickStretchPassword(email, password string) []byte {
	salt := "identity.mozilla.com/picl/v1/quickStretch:" + email
	return pbkdf2.Key([]byte(password), []byte(salt), 1000, 32, sha256.New)
}

func deriveAuthPWFromQuickStretchedPassword(stretchedPassword []byte) ([]byte, error) {
	secret := make([]byte, sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, stretchedPassword, nil, []byte("identity.mozilla.com/picl/v1/authPW")), secret); err != nil {
		return nil, err
	}
	return secret, nil
}

func deriveUnwrapBKeyFromQuickStretchedPassword(stretchedPassword []byte) ([]byte, error) {
	secret := make([]byte, sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, stretchedPassword, nil, []byte("identity.mozilla.com/picl/v1/unwrapBkey")), secret); err != nil {
		return nil, err
	}
	return secret, nil
}

type requestCredentials struct {
	TokenId        []byte
	RequestHMACKey []byte
	RequestKey     []byte
}

func newRequestCredentials(token []byte, name string) (*requestCredentials, error) {
	secret := make([]byte, 3*sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, token, nil, []byte("identity.mozilla.com/picl/v1/"+name)), secret); err != nil {
		return nil, err
	}
	return &requestCredentials{
		TokenId:        secret[0:32],
		RequestHMACKey: secret[32:64],
		RequestKey:     secret[64:96],
	}, nil
}

type accountKeys struct {
	HMACKey []byte
	XORKey  []byte
}

func newAccountKeys(requestKey []byte) (*accountKeys, error) {
	secret := make([]byte, 3*sha256.Size)
	if _, err := io.ReadFull(hkdf.New(sha256.New, requestKey, nil, []byte("identity.mozilla.com/picl/v1/account/keys")), secret); err != nil {
		return nil, err
	}
	return &accountKeys{
		HMACKey: secret[0:32],
		XORKey:  secret[32:96],
	}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"time"

	"github.com/metal-tile/land/dqn"
	"github.com/metal-tile/land/firedb"
	"github.com/pkg/errors"
	"github.com/sinmetal/slog"
	"github.com/sinmetal/stime"
	"github.com/tenntenn/sync/recoverable"
)

var monsterPositionMap map[string]*firedb.MonsterPosition

func init() {
	monsterPositionMap = make(map[string]*firedb.MonsterPosition)
}

// MonsterClient is Monsterに関連する処理を行うClient
type MonsterClient struct {
	DQN dqn.Client
	firedb.PlayerStore
}

// RunControlMonster is MonsterのControlを開始する
func RunControlMonster(client *MonsterClient) error {
	// TODO dummy monsterをdebugのために追加する
	const monsterID = "dummy"
	monsterPositionMap[monsterID] = &firedb.MonsterPosition{
		ID:    monsterID,
		X:     950,
		Y:     1000,
		Angle: 180,
		Speed: 4,
	}

	for {
		t := time.NewTicker(100 * time.Millisecond)
		for {
			select {
			case <-t.C:
				ctx := slog.WithLog(context.Background())

				f := recoverable.Func(func() {
					if err := handleMonster(ctx, client, monsterID); err != nil {
						panic(err) // panicを上で拾ってもらうために投げる
					}
				})

				// TODO recoverableの力を発揮するために、f() を go f() にする必要がある
				if err := f(); err != nil {
					v, ok := recoverable.RecoveredValue(err)
					if ok {
						slog.Info(ctx, "FailedHandleMonster:RecoveredValue", fmt.Sprintf("%+v", v))
					} else {
						slog.Info(ctx, "FailedHandleMonster", fmt.Sprintf("%+v", err))
					}
				}

				slog.Flush(ctx)
			}
		}
	}
}

func handleMonster(ctx context.Context, client *MonsterClient, monsterID string) error {
	if firedb.ExistsActivePlayer(client.PlayerStore.GetPlayerMapSnapshot()) == false {
		return nil
	}

	mob, ok := monsterPositionMap[monsterID]
	if !ok {
		slog.Info(ctx, "NotFoundMonster", fmt.Sprintf("%s is not found monsterPositionMap.", monsterID))
		return nil
	}
	ppm := client.PlayerStore.GetPositionMapSnapshot()
	dp, err := BuildDQNPayload(ctx, mob, ppm)
	if err != nil {
		slog.Warning(ctx, "FailedBuildDQNPayload", fmt.Sprintf("failed BuildDQNPayload. %+v,%+v,%+v", mob, ppm, err))
		return nil
	}
	err = client.UpdateMonster(ctx, mob, dp)
	if err != nil {
		slog.Warning(ctx, "FailedUpdateMonster", fmt.Sprintf("failed UpdateMonster. %+v", err))
		return nil
	}

	return nil
}

// UpdateMonster is DQN Predictionに基づき、Firestore上のMonsterの位置を更新する
func (client *MonsterClient) UpdateMonster(ctx context.Context, mob *firedb.MonsterPosition, dp *dqn.Payload) error {
	ans, err := client.DQN.Prediction(ctx, dp)
	if err != nil {
		slog.Info(ctx, "DQNPayload", slog.KV{"DQNPayload", dp})
		return errors.Wrap(err, "failed DQN.Prediction")
	}
	slog.Info(ctx, "DQNAnswer", slog.KV{"DQNAnswer", ans})

	ms := firedb.NewMonsterStore()

	mob.X += ans.X * mob.Speed
	mob.Y += ans.Y * mob.Speed
	mob.IsMove = ans.IsMove
	mob.Angle = ans.Angle
	monsterPositionMap[mob.ID] = mob
	return ms.UpdatePosition(ctx, mob)
}

// BuildDQNPayload is DQNに渡すPayloadを構築する
func BuildDQNPayload(ctx context.Context, mp *firedb.MonsterPosition, playerPositionMap map[string]*firedb.PlayerPosition) (*dqn.Payload, error) {
	payload := &dqn.Payload{
		Instances: []dqn.Instance{
			dqn.Instance{},
		},
	}
	// Monsterが中心ぐらいにいる状態
	payload.Instances[0].State[(dqn.SenseRangeRow / 2)][(dqn.SenseRangeCol / 2)][dqn.MonsterLayer] = 1

	mobRow, mobCol := ConvertXYToRowCol(mp.X, mp.Y, 1.0)
	slog.Info(ctx, "StartPlayerPositionMapRange", "Start playerPositionMap.Range.")
	for _, p := range playerPositionMap {
		if stime.InTime(stime.Now(), p.FirestoreUpdateAt, 10*time.Second) == false {
			continue
		}
		plyRow, plyCol := ConvertXYToRowCol(p.X, p.Y, 1.0)

		row := plyRow - mobRow + (dqn.SenseRangeRow / 2)
		if row < 0 || row >= dqn.SenseRangeRow {
			// 索敵範囲外にいる
			slog.Info(ctx, "DQN.TargetIsFarAway", slog.KV{"row", row})
			continue
		}
		col := plyCol - mobCol + (dqn.SenseRangeCol / 2)
		if col < 0 || col >= dqn.SenseRangeCol {
			slog.Info(ctx, "DQN.TargetIsFarAway", slog.KV{"col", col})
			// 索敵範囲外にいる
			continue
		}

		slog.Info(ctx, "DQNPayloadPlayerPosition", fmt.Sprintf("DQN.Payload.PlayerPosition row=%d,col=%d", row, col))
		payload.Instances[0].State[row][col][dqn.PlayerLayer] = 1
	}

	return payload, nil
}
<commit_msg>HandleMonsterにCloud Traceを仕込んだ refs #36<commit_after>package main

import (
	"context"
	"fmt"
	"time"

	"github.com/metal-tile/land/dqn"
	"github.com/metal-tile/land/firedb"
	"github.com/pkg/errors"
	"github.com/sinmetal/slog"
	"github.com/sinmetal/stime"
	"github.com/tenntenn/sync/recoverable"
	"go.opencensus.io/trace"
)

var monsterPositionMap map[string]*firedb.MonsterPosition

func init() {
	monsterPositionMap = make(map[string]*firedb.MonsterPosition)
}

// MonsterClient is Monsterに関連する処理を行うClient
type MonsterClient struct {
	DQN dqn.Client
	firedb.PlayerStore
}

// RunControlMonster is MonsterのControlを開始する
func RunControlMonster(client *MonsterClient) error {
	// TODO dummy monsterをdebugのために追加する
	const monsterID = "dummy"
	monsterPositionMap[monsterID] = &firedb.MonsterPosition{
		ID:    monsterID,
		X:     950,
		Y:     1000,
		Angle: 180,
		Speed: 4,
	}

	for {
		t := time.NewTicker(100 * time.Millisecond)
		for {
			select {
			case <-t.C:
				ctx := slog.WithLog(context.Background())

				f := recoverable.Func(func() {
					if err := handleMonster(ctx, client, monsterID); err != nil {
						panic(err) // panicを上で拾ってもらうために投げる
					}
				})

				// TODO recoverableの力を発揮するために、f() を go f() にする必要がある
				if err := f(); err != nil {
					v, ok := recoverable.RecoveredValue(err)
					if ok {
						slog.Info(ctx, "FailedHandleMonster:RecoveredValue", fmt.Sprintf("%+v", v))
					} else {
						slog.Info(ctx, "FailedHandleMonster", fmt.Sprintf("%+v", err))
					}
				}

				slog.Flush(ctx)
			}
		}
	}
}

func handleMonster(ctx context.Context, client *MonsterClient, monsterID string) error {
	ctx, span := trace.StartSpan(ctx, "/monster/handleMonster")
	defer span.End()

	if firedb.ExistsActivePlayer(client.PlayerStore.GetPlayerMapSnapshot()) == false {
		return nil
	}

	mob, ok := monsterPositionMap[monsterID]
	if !ok {
		slog.Info(ctx, "NotFoundMonster", fmt.Sprintf("%s is not found monsterPositionMap.", monsterID))
		return nil
	}
	ppm := client.PlayerStore.GetPositionMapSnapshot()
	dp, err := BuildDQNPayload(ctx, mob, ppm)
	if err != nil {
		slog.Warning(ctx, "FailedBuildDQNPayload", fmt.Sprintf("failed BuildDQNPayload. %+v,%+v,%+v", mob, ppm, err))
		return nil
	}
	err = client.UpdateMonster(ctx, mob, dp)
	if err != nil {
		slog.Warning(ctx, "FailedUpdateMonster", fmt.Sprintf("failed UpdateMonster. %+v", err))
		return nil
	}

	return nil
}

// UpdateMonster is DQN Predictionに基づき、Firestore上のMonsterの位置を更新する
func (client *MonsterClient) UpdateMonster(ctx context.Context, mob *firedb.MonsterPosition, dp *dqn.Payload) error {
	ctx, span := trace.StartSpan(ctx, "/monster/updateMonster")
	defer span.End()

	ans, err := client.DQN.Prediction(ctx, dp)
	if err != nil {
		slog.Info(ctx, "DQNPayload", slog.KV{"DQNPayload", dp})
		return errors.Wrap(err, "failed DQN.Prediction")
	}
	slog.Info(ctx, "DQNAnswer", slog.KV{"DQNAnswer", ans})

	ms := firedb.NewMonsterStore()

	mob.X += ans.X * mob.Speed
	mob.Y += ans.Y * mob.Speed
	mob.IsMove = ans.IsMove
	mob.Angle = ans.Angle
	monsterPositionMap[mob.ID] = mob
	return ms.UpdatePosition(ctx, mob)
}

// BuildDQNPayload is DQNに渡すPayloadを構築する
func BuildDQNPayload(ctx context.Context, mp *firedb.MonsterPosition, playerPositionMap map[string]*firedb.PlayerPosition) (*dqn.Payload, error) {
	payload := &dqn.Payload{
		Instances: []dqn.Instance{
			dqn.Instance{},
		},
	}
	// Monsterが中心ぐらいにいる状態
	payload.Instances[0].State[(dqn.SenseRangeRow / 2)][(dqn.SenseRangeCol / 2)][dqn.MonsterLayer] = 1

	mobRow, mobCol := ConvertXYToRowCol(mp.X, mp.Y, 1.0)
	slog.Info(ctx, "StartPlayerPositionMapRange", "Start playerPositionMap.Range.")
	for _, p := range playerPositionMap {
		if stime.InTime(stime.Now(), p.FirestoreUpdateAt, 10*time.Second) == false {
			continue
		}
		plyRow, plyCol := ConvertXYToRowCol(p.X, p.Y, 1.0)

		row := plyRow - mobRow + (dqn.SenseRangeRow / 2)
		if row < 0 || row >= dqn.SenseRangeRow {
			// 索敵範囲外にいる
			slog.Info(ctx, "DQN.TargetIsFarAway", slog.KV{"row", row})
			continue
		}
		col := plyCol - mobCol + (dqn.SenseRangeCol / 2)
		if col < 0 || col >= dqn.SenseRangeCol {
			slog.Info(ctx, "DQN.TargetIsFarAway", slog.KV{"col", col})
			// 索敵範囲外にいる
			continue
		}

		slog.Info(ctx, "DQNPayloadPlayerPosition", fmt.Sprintf("DQN.Payload.PlayerPosition row=%d,col=%d", row, col))
		payload.Instances[0].State[row][col][dqn.PlayerLayer] = 1
	}

	return payload, nil
}
<|endoftext|>


<commit_before>package gcsresource

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

	"github.com/cheggaaa/pb"
	"golang.org/x/oauth2"
	oauthgoogle "golang.org/x/oauth2/google"
	"google.golang.org/api/storage/v1"
)

type GCSClient interface {
	BucketObjects(bucketName string, prefix string) ([]string, error)
	ObjectGenerations(bucketName string, objectPath string) ([]int64, error)
	DownloadFile(bucketName string, objectPath string, generation int64, localPath string) error
	UploadFile(bucketName string, objectPath string, localPath string) (int64, error)
	URL(bucketName string, objectPath string, generation int64) (string, error)
	DeleteObject(bucketName string, objectPath string, generation int64) error
}

type gcsclient struct {
	client         *storage.Service
	progressOutput io.Writer
}

func NewGCSClient(
	progressOutput io.Writer,
	jsonKey string,
) (GCSClient, error) {
	var err error
	var storageClient *http.Client
	var userAgent = "gcs-resource/0.0.1"

	if jsonKey != "" {
		storageJwtConf, err := oauthgoogle.JWTConfigFromJSON([]byte(jsonKey), storage.DevstorageFullControlScope)
		if err != nil {
			return &gcsclient{}, err
		}
		storageClient = storageJwtConf.Client(oauth2.NoContext)
	} else {
		storageClient, err = oauthgoogle.DefaultClient(oauth2.NoContext, storage.DevstorageFullControlScope)
		if err != nil {
			return &gcsclient{}, err
		}
	}

	storageService, err := storage.New(storageClient)
	if err != nil {
		return &gcsclient{}, err
	}
	storageService.UserAgent = userAgent

	return &gcsclient{
		client:         storageService,
		progressOutput: progressOutput,
	}, nil
}

func (client *gcsclient) BucketObjects(bucketName string, prefix string) ([]string, error) {
	bucketObjects, err := client.getBucketObjects(bucketName, prefix)
	if err != nil {
		return []string{}, err
	}

	return bucketObjects, nil
}

func (client *gcsclient) ObjectGenerations(bucketName string, objectPath string) ([]int64, error) {
	isBucketVersioned, err := client.getBucketVersioning(bucketName)
	if err != nil {
		return []int64{}, err
	}

	if !isBucketVersioned {
		return []int64{}, errors.New("bucket is not versioned")
	}

	objectGenerations, err := client.getObjectGenerations(bucketName, objectPath)
	if err != nil {
		return []int64{}, err
	}

	return objectGenerations, nil
}

func (client *gcsclient) DownloadFile(bucketName string, objectPath string, generation int64, localPath string) error {
	isBucketVersioned, err := client.getBucketVersioning(bucketName)
	if err != nil {
		return err
	}

	if !isBucketVersioned && generation != 0 {
		return errors.New("bucket is not versioned")
	}

	getCall := client.client.Objects.Get(bucketName, objectPath)
	if generation != 0 {
		getCall = getCall.Generation(generation)
	}

	object, err := getCall.Do()
	if err != nil {
		return err
	}

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

	progress := client.newProgressBar(int64(object.Size))
	progress.Start()
	defer progress.Finish()

	response, err := getCall.Download()
	if err != nil {
		return err
	}
	defer response.Body.Close()

	reader := progress.NewProxyReader(response.Body)
	io.Copy(localFile, reader)

	return nil
}

func (client *gcsclient) UploadFile(bucketName string, objectPath string, localPath string) (int64, error) {
	isBucketVersioned, err := client.getBucketVersioning(bucketName)
	if err != nil {
		return 0, err
	}

	stat, err := os.Stat(localPath)
	if err != nil {
		return 0, err
	}

	localFile, err := os.Open(localPath)
	if err != nil {
		return 0, err
	}
	defer localFile.Close()

	progress := client.newProgressBar(stat.Size())
	progress.Start()
	defer progress.Finish()

	object := &storage.Object{
		Name: objectPath,
	}

	uploadedObject, err := client.client.Objects.Insert(bucketName, object).Media(progress.NewProxyReader(localFile)).Do()
	if err != nil {
		return 0, err
	}

	if isBucketVersioned {
		return uploadedObject.Generation, nil
	}

	return 0, nil
}

func (client *gcsclient) URL(bucketName string, objectPath string, generation int64) (string, error) {
	getCall := client.client.Objects.Get(bucketName, objectPath)
	if generation != 0 {
		getCall = getCall.Generation(generation)
	}

	_, err := getCall.Do()
	if err != nil {
		return "", err
	}

	var url string
	if generation != 0 {
		url = fmt.Sprintf("gs://%s/%s#%d", bucketName, objectPath, generation)
	} else {
		url = fmt.Sprintf("gs://%s/%s", bucketName, objectPath)
	}

	return url, nil
}

func (client *gcsclient) DeleteObject(bucketName string, objectPath string, generation int64) error {
	deleteCall := client.client.Objects.Delete(bucketName, objectPath)
	if generation != 0 {
		deleteCall = deleteCall.Generation(generation)
	}

	err := deleteCall.Do()
	if err != nil {
		return err
	}

	return nil
}

func (client *gcsclient) getBucketObjects(bucketName string, prefix string) ([]string, error) {
	var bucketObjects []string

	pageToken := ""
	for {
		listCall := client.client.Objects.List(bucketName)
		listCall = listCall.PageToken(pageToken)
		listCall = listCall.Prefix(prefix)
		listCall = listCall.Versions(false)

		objects, err := listCall.Do()
		if err != nil {
			return bucketObjects, err
		}

		for _, object := range objects.Items {
			bucketObjects = append(bucketObjects, object.Name)
		}

		if objects.NextPageToken != "" {
			pageToken = objects.NextPageToken
		} else {
			break
		}
	}

	return bucketObjects, nil
}

func (client *gcsclient) getBucketVersioning(bucketName string) (bool, error) {
	bucket, err := client.client.Buckets.Get(bucketName).Do()
	if err != nil {
		return false, err
	}

	return bucket.Versioning.Enabled, nil
}

func (client *gcsclient) getObjectGenerations(bucketName string, objectPath string) ([]int64, error) {
	var objectGenerations []int64

	pageToken := ""
	for {
		listCall := client.client.Objects.List(bucketName)
		listCall = listCall.PageToken(pageToken)
		listCall = listCall.Prefix(objectPath)
		listCall = listCall.Versions(true)

		objects, err := listCall.Do()
		if err != nil {
			return objectGenerations, err
		}

		for _, object := range objects.Items {
			if object.Name == objectPath {
				objectGenerations = append(objectGenerations, object.Generation)
			}
		}

		if objects.NextPageToken != "" {
			pageToken = objects.NextPageToken
		} else {
			break
		}
	}

	return objectGenerations, nil
}

func (client *gcsclient) newProgressBar(total int64) *pb.ProgressBar {
	progress := pb.New64(total)

	progress.Output = client.progressOutput
	progress.ShowSpeed = true
	progress.Units = pb.U_BYTES
	progress.NotPrint = true

	return progress.SetWidth(80)
}
<commit_msg>Rename gcsclient<commit_after>package gcsresource

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

	"github.com/cheggaaa/pb"
	"golang.org/x/oauth2"
	oauthgoogle "golang.org/x/oauth2/google"
	"google.golang.org/api/storage/v1"
)

type GCSClient interface {
	BucketObjects(bucketName string, prefix string) ([]string, error)
	ObjectGenerations(bucketName string, objectPath string) ([]int64, error)
	DownloadFile(bucketName string, objectPath string, generation int64, localPath string) error
	UploadFile(bucketName string, objectPath string, localPath string) (int64, error)
	URL(bucketName string, objectPath string, generation int64) (string, error)
	DeleteObject(bucketName string, objectPath string, generation int64) error
}

type gcsclient struct {
	storageService  *storage.Service
	progressOutput io.Writer
}

func NewGCSClient(
	progressOutput io.Writer,
	jsonKey string,
) (GCSClient, error) {
	var err error
	var storageClient *http.Client
	var userAgent = "gcs-resource/0.0.1"

	if jsonKey != "" {
		storageJwtConf, err := oauthgoogle.JWTConfigFromJSON([]byte(jsonKey), storage.DevstorageFullControlScope)
		if err != nil {
			return &gcsclient{}, err
		}
		storageClient = storageJwtConf.Client(oauth2.NoContext)
	} else {
		storageClient, err = oauthgoogle.DefaultClient(oauth2.NoContext, storage.DevstorageFullControlScope)
		if err != nil {
			return &gcsclient{}, err
		}
	}

	storageService, err := storage.New(storageClient)
	if err != nil {
		return &gcsclient{}, err
	}
	storageService.UserAgent = userAgent

	return &gcsclient{
		storageService: storageService,
		progressOutput: progressOutput,
	}, nil
}

func (gcsclient *gcsclient) BucketObjects(bucketName string, prefix string) ([]string, error) {
	bucketObjects, err := gcsclient.getBucketObjects(bucketName, prefix)
	if err != nil {
		return []string{}, err
	}

	return bucketObjects, nil
}

func (gcsclient *gcsclient) ObjectGenerations(bucketName string, objectPath string) ([]int64, error) {
	isBucketVersioned, err := gcsclient.getBucketVersioning(bucketName)
	if err != nil {
		return []int64{}, err
	}

	if !isBucketVersioned {
		return []int64{}, errors.New("bucket is not versioned")
	}

	objectGenerations, err := gcsclient.getObjectGenerations(bucketName, objectPath)
	if err != nil {
		return []int64{}, err
	}

	return objectGenerations, nil
}

func (gcsclient *gcsclient) DownloadFile(bucketName string, objectPath string, generation int64, localPath string) error {
	isBucketVersioned, err := gcsclient.getBucketVersioning(bucketName)
	if err != nil {
		return err
	}

	if !isBucketVersioned && generation != 0 {
		return errors.New("bucket is not versioned")
	}

	getCall := gcsclient.storageService.Objects.Get(bucketName, objectPath)
	if generation != 0 {
		getCall = getCall.Generation(generation)
	}

	object, err := getCall.Do()
	if err != nil {
		return err
	}

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

	progress := gcsclient.newProgressBar(int64(object.Size))
	progress.Start()
	defer progress.Finish()

	response, err := getCall.Download()
	if err != nil {
		return err
	}
	defer response.Body.Close()

	reader := progress.NewProxyReader(response.Body)
	io.Copy(localFile, reader)

	return nil
}

func (gcsclient *gcsclient) UploadFile(bucketName string, objectPath string, localPath string) (int64, error) {
	isBucketVersioned, err := gcsclient.getBucketVersioning(bucketName)
	if err != nil {
		return 0, err
	}

	stat, err := os.Stat(localPath)
	if err != nil {
		return 0, err
	}

	localFile, err := os.Open(localPath)
	if err != nil {
		return 0, err
	}
	defer localFile.Close()

	progress := gcsclient.newProgressBar(stat.Size())
	progress.Start()
	defer progress.Finish()

	object := &storage.Object{
		Name: objectPath,
	}

	uploadedObject, err := gcsclient.storageService.Objects.Insert(bucketName, object).Media(progress.NewProxyReader(localFile)).Do()
	if err != nil {
		return 0, err
	}

	if isBucketVersioned {
		return uploadedObject.Generation, nil
	}

	return 0, nil
}

func (gcsclient *gcsclient) URL(bucketName string, objectPath string, generation int64) (string, error) {
	getCall := gcsclient.storageService.Objects.Get(bucketName, objectPath)
	if generation != 0 {
		getCall = getCall.Generation(generation)
	}

	_, err := getCall.Do()
	if err != nil {
		return "", err
	}

	var url string
	if generation != 0 {
		url = fmt.Sprintf("gs://%s/%s#%d", bucketName, objectPath, generation)
	} else {
		url = fmt.Sprintf("gs://%s/%s", bucketName, objectPath)
	}

	return url, nil
}

func (gcsclient *gcsclient) DeleteObject(bucketName string, objectPath string, generation int64) error {
	deleteCall := gcsclient.storageService.Objects.Delete(bucketName, objectPath)
	if generation != 0 {
		deleteCall = deleteCall.Generation(generation)
	}

	err := deleteCall.Do()
	if err != nil {
		return err
	}

	return nil
}

func (gcsclient *gcsclient) getBucketObjects(bucketName string, prefix string) ([]string, error) {
	var bucketObjects []string

	pageToken := ""
	for {
		listCall := gcsclient.storageService.Objects.List(bucketName)
		listCall = listCall.PageToken(pageToken)
		listCall = listCall.Prefix(prefix)
		listCall = listCall.Versions(false)

		objects, err := listCall.Do()
		if err != nil {
			return bucketObjects, err
		}

		for _, object := range objects.Items {
			bucketObjects = append(bucketObjects, object.Name)
		}

		if objects.NextPageToken != "" {
			pageToken = objects.NextPageToken
		} else {
			break
		}
	}

	return bucketObjects, nil
}

func (gcsclient *gcsclient) getBucketVersioning(bucketName string) (bool, error) {
	bucket, err := gcsclient.storageService.Buckets.Get(bucketName).Do()
	if err != nil {
		return false, err
	}

	return bucket.Versioning.Enabled, nil
}

func (gcsclient *gcsclient) getObjectGenerations(bucketName string, objectPath string) ([]int64, error) {
	var objectGenerations []int64

	pageToken := ""
	for {
		listCall := gcsclient.storageService.Objects.List(bucketName)
		listCall = listCall.PageToken(pageToken)
		listCall = listCall.Prefix(objectPath)
		listCall = listCall.Versions(true)

		objects, err := listCall.Do()
		if err != nil {
			return objectGenerations, err
		}

		for _, object := range objects.Items {
			if object.Name == objectPath {
				objectGenerations = append(objectGenerations, object.Generation)
			}
		}

		if objects.NextPageToken != "" {
			pageToken = objects.NextPageToken
		} else {
			break
		}
	}

	return objectGenerations, nil
}

func (gcsclient *gcsclient) newProgressBar(total int64) *pb.ProgressBar {
	progress := pb.New64(total)

	progress.Output = gcsclient.progressOutput
	progress.ShowSpeed = true
	progress.Units = pb.U_BYTES
	progress.NotPrint = true

	return progress.SetWidth(80)
}
<|endoftext|>


<commit_before>package goinsta

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"net/url"
	"strings"
)

const (
	volatileSeed = "12345"
)

func generateMD5Hash(text string) string {
	hasher := md5.New()
	hasher.Write([]byte(text))
	return hex.EncodeToString(hasher.Sum(nil))
}

func generateHMAC(text, key string) string {
	hasher := hmac.New(sha256.New, []byte(key))
	hasher.Write([]byte(text))
	return hex.EncodeToString(hasher.Sum(nil))
}

func generateDeviceID(seed string) string {
	hash := generateMD5Hash(seed + volatileSeed)
	return "android-" + hash[:16]
}

func newUUID() (string, error) {
	uuid := make([]byte, 16)
	n, err := io.ReadFull(rand.Reader, uuid)
	if n != len(uuid) || err != nil {
		return "", err
	}
	// variant bits; see section 4.1.1
	uuid[8] = uuid[8]&^0xc0 | 0x80
	// version 4 (pseudo-random); see section 4.1.3
	uuid[6] = uuid[6]&^0xf0 | 0x40
	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
}

func generateUUID(replace bool) string {
	uuid, err := newUUID()
	if err != nil {
		return "cb479ee7-a50d-49e7-8b7b-60cc1a105e22" // default value when error occurred
	}
	if replace {
		return strings.Replace(uuid, "-", "", -1)
	}
	return uuid
}

func generateSignature(data string) map[string]string {
	m := make(map[string]string)
	m["ig_sig_key_version"] = goInstaSigKeyVersion
	m["signed_body"] = fmt.Sprintf(
		"%s.%s", generateHMAC(data, goInstaIGSigKey), data,
	)
	return m
}
<commit_msg>fixed error: unused package<commit_after>package goinsta

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"strings"
)

const (
	volatileSeed = "12345"
)

func generateMD5Hash(text string) string {
	hasher := md5.New()
	hasher.Write([]byte(text))
	return hex.EncodeToString(hasher.Sum(nil))
}

func generateHMAC(text, key string) string {
	hasher := hmac.New(sha256.New, []byte(key))
	hasher.Write([]byte(text))
	return hex.EncodeToString(hasher.Sum(nil))
}

func generateDeviceID(seed string) string {
	hash := generateMD5Hash(seed + volatileSeed)
	return "android-" + hash[:16]
}

func newUUID() (string, error) {
	uuid := make([]byte, 16)
	n, err := io.ReadFull(rand.Reader, uuid)
	if n != len(uuid) || err != nil {
		return "", err
	}
	// variant bits; see section 4.1.1
	uuid[8] = uuid[8]&^0xc0 | 0x80
	// version 4 (pseudo-random); see section 4.1.3
	uuid[6] = uuid[6]&^0xf0 | 0x40
	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
}

func generateUUID(replace bool) string {
	uuid, err := newUUID()
	if err != nil {
		return "cb479ee7-a50d-49e7-8b7b-60cc1a105e22" // default value when error occurred
	}
	if replace {
		return strings.Replace(uuid, "-", "", -1)
	}
	return uuid
}

func generateSignature(data string) map[string]string {
	m := make(map[string]string)
	m["ig_sig_key_version"] = goInstaSigKeyVersion
	m["signed_body"] = fmt.Sprintf(
		"%s.%s", generateHMAC(data, goInstaIGSigKey), data,
	)
	return m
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"flag"
	"io"
	"io/ioutil"
	"net"
	"encoding/binary"
	"crypto/sha256"
	"os/user"
	"path"
	"strconv"
	"strings"
	"time"
	"math/rand"

	"github.com/mitnk/goutils/encrypt"
)

var remoteDebug = false
var countConnected = 0

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

type DataInfo struct {
	data []byte
	size int
}

func main() {
	port := flag.String("p", "3389", "port")
	debug := flag.Bool("v", false, "debug")
	flag.Usage = func() {
        fmt.Printf("lightsocks [flags]\nwhere flags are:\n")
        flag.PrintDefaults()
    }
    flag.Parse()
    fmt.Printf("lightsocks v0.10\n")

	remoteDebug = *debug
	remote, err := net.Listen("tcp", ":" + *port)
	check(err)
	defer remote.Close()
    fmt.Printf("listen on port %s\n", *port)

	for {
        local, err := remote.Accept()
        if err != nil {
			fmt.Printf("Error: %v\n", err)
            continue
        }
        go handleClient(local)
    }
}

func handleClient(local net.Conn) {
    defer local.Close()
	countConnected += 1
    defer func() {
		countConnected -= 1
	}()

	info("local connected: %v.", local.RemoteAddr())
	key := getKey()
	buffer := make([]byte, 1)
	_, err := io.ReadFull(local, buffer)
	if err != nil {
		fmt.Printf("cannot read size from local.\n")
		return
	}

	buffer = make([]byte, buffer[0])
	_, err = io.ReadFull(local, buffer)
	if err != nil {
		fmt.Printf("cannot read host from local.\n")
		return
	}
	host, err := encrypt.Decrypt(buffer, key[:])
	if err != nil {
		fmt.Printf("ERROR: cannot decrypt host.\n")
		return
	}

	buffer = make([]byte, 2)
	_, err = io.ReadFull(local, buffer)
	if err != nil {
		fmt.Printf("cannot read port from local.\n")
		return
	}
	port := binary.BigEndian.Uint16(buffer)

	url := net.JoinHostPort(string(host), strconv.Itoa(int(port)))
	server, err := net.Dial("tcp", url)
	if err != nil {
		fmt.Printf("ERROR: cannot dial to server %s\n", url)
		return
	}
	info("connected to server: %s", url)
	defer server.Close()

	ch_local := make(chan []byte)
	ch_server := make(chan DataInfo)
	go readDataFromLocal(ch_local, ch_server, local, key[:])
	go readDataFromServer(ch_server, server)

	shouldStop := false
	for {
		if shouldStop {
			break
		}

		select {
		case data := <-ch_local:
			if data == nil {
				local.Close()
				info("local closed %v", local.RemoteAddr())
				shouldStop = true
				break
			}
			server.Write(data)
		case di := <-ch_server:
			if di.data == nil {
				server.Close()
				info("server closed %v", server.RemoteAddr())
				break
			}
			buffer = encrypt.Encrypt(di.data[:di.size], key[:])
			b := make([]byte, 2)
			binary.BigEndian.PutUint16(b, uint16(len(buffer)))
			local.Write(b)
			local.Write(buffer)
		}
	}
}

func readDataFromServer(ch chan DataInfo, conn net.Conn) {
	for {
		data := make([]byte, 7000 + rand.Intn(2000))
		n, err := conn.Read(data)
		if err != nil {
			ch <- DataInfo{nil, 0}
			return
		}
		info("got %d bytes from server", n)
		ch <- DataInfo{data, n}
	}
}

func readDataFromLocal(ch chan []byte, ch2 chan DataInfo, conn net.Conn, key []byte) {
	for {
		buffer := make([]byte, 2)
		_, err := io.ReadFull(conn, buffer)
		if err != nil {
			ch <- nil
			ch2 <- DataInfo{nil, 0}
			return
		}
		size := binary.BigEndian.Uint16(buffer)
		buffer = make([]byte, size)
		_, err = io.ReadFull(conn, buffer)
		if err != nil {
			ch <- nil
			return
		}
		data, err := encrypt.Decrypt(buffer, key)
		if err != nil {
			fmt.Printf("ERROR: cannot decrypt data from local.")
			ch <- nil
			return
		}
		ch <- data
	}
}

func getKey() [32]byte {
	usr, err := user.Current()
	check(err)
	fileKey := path.Join(usr.HomeDir, ".lightsockskey")
	data, err := ioutil.ReadFile(fileKey)
	s := strings.TrimSpace(string(data))
	check(err)
	return sha256.Sum256([]byte(s))
}

func info(format string, a...interface{}) (n int, err error) {
	if !remoteDebug {
		return 0, nil
	}
	ts := time.Now().Format("2006-01-02 15:04:05")
	prefix := fmt.Sprintf("[%s][%d] ", ts, countConnected)
	return fmt.Printf(prefix + format + "\n", a...)
}
<commit_msg>random the upstream (2)<commit_after>package main

import (
	"fmt"
	"flag"
	"io"
	"io/ioutil"
	"net"
	"encoding/binary"
	"crypto/sha256"
	"os/user"
	"path"
	"strconv"
	"strings"
	"time"
	"math/rand"

	"github.com/mitnk/goutils/encrypt"
)

var remoteDebug = false
var countConnected = 0

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

type DataInfo struct {
	data []byte
	size int
}

func main() {
	port := flag.String("p", "3389", "port")
	debug := flag.Bool("v", false, "debug")
	flag.Usage = func() {
        fmt.Printf("lightsocks [flags]\nwhere flags are:\n")
        flag.PrintDefaults()
    }
    flag.Parse()
    fmt.Printf("lightsocks v0.10\n")

	remoteDebug = *debug
	remote, err := net.Listen("tcp", ":" + *port)
	check(err)
	defer remote.Close()
    fmt.Printf("listen on port %s\n", *port)

	for {
        local, err := remote.Accept()
        if err != nil {
			fmt.Printf("Error: %v\n", err)
            continue
        }
        go handleClient(local)
    }
}

func handleClient(local net.Conn) {
    defer local.Close()
	countConnected += 1
    defer func() {
		countConnected -= 1
	}()

	info("local connected: %v.", local.RemoteAddr())
	key := getKey()
	buffer := make([]byte, 1)
	_, err := io.ReadFull(local, buffer)
	if err != nil {
		fmt.Printf("cannot read size from local.\n")
		return
	}

	buffer = make([]byte, buffer[0])
	_, err = io.ReadFull(local, buffer)
	if err != nil {
		fmt.Printf("cannot read host from local.\n")
		return
	}
	host, err := encrypt.Decrypt(buffer, key[:])
	if err != nil {
		fmt.Printf("ERROR: cannot decrypt host.\n")
		return
	}

	buffer = make([]byte, 2)
	_, err = io.ReadFull(local, buffer)
	if err != nil {
		fmt.Printf("cannot read port from local.\n")
		return
	}
	port := binary.BigEndian.Uint16(buffer)

	url := net.JoinHostPort(string(host), strconv.Itoa(int(port)))
	server, err := net.Dial("tcp", url)
	if err != nil {
		fmt.Printf("ERROR: cannot dial to server %s\n", url)
		return
	}
	info("connected to server: %s", url)
	defer server.Close()

	ch_local := make(chan []byte)
	ch_server := make(chan DataInfo)
	go readDataFromLocal(ch_local, ch_server, local, key[:])
	go readDataFromServer(ch_server, server)

	shouldStop := false
	for {
		if shouldStop {
			break
		}

		select {
		case data := <-ch_local:
			if data == nil {
				local.Close()
				info("local closed %v", local.RemoteAddr())
				shouldStop = true
				break
			}
			server.Write(data)
		case di := <-ch_server:
			if di.data == nil {
				server.Close()
				info("server closed %v", server.RemoteAddr())
				break
			}
			buffer = encrypt.Encrypt(di.data[:di.size], key[:])
			b := make([]byte, 2)
			binary.BigEndian.PutUint16(b, uint16(len(buffer)))
			local.Write(b)
			local.Write(buffer)
		}
	}
}

func readDataFromServer(ch chan DataInfo, conn net.Conn) {
	for {
		data := make([]byte, 7000 + rand.Intn(2000))
		n, err := conn.Read(data)
		if err != nil {
			ch <- DataInfo{nil, 0}
			return
		}
		ch <- DataInfo{data, n}
	}
}

func readDataFromLocal(ch chan []byte, ch2 chan DataInfo, conn net.Conn, key []byte) {
	for {
		buffer := make([]byte, 2)
		_, err := io.ReadFull(conn, buffer)
		if err != nil {
			ch <- nil
			ch2 <- DataInfo{nil, 0}
			return
		}
		size := binary.BigEndian.Uint16(buffer)
		buffer = make([]byte, size)
		_, err = io.ReadFull(conn, buffer)
		if err != nil {
			ch <- nil
			return
		}
		data, err := encrypt.Decrypt(buffer, key)
		if err != nil {
			fmt.Printf("ERROR: cannot decrypt data from local.")
			ch <- nil
			return
		}
		ch <- data
	}
}

func getKey() [32]byte {
	usr, err := user.Current()
	check(err)
	fileKey := path.Join(usr.HomeDir, ".lightsockskey")
	data, err := ioutil.ReadFile(fileKey)
	s := strings.TrimSpace(string(data))
	check(err)
	return sha256.Sum256([]byte(s))
}

func info(format string, a...interface{}) (n int, err error) {
	if !remoteDebug {
		return 0, nil
	}
	ts := time.Now().Format("2006-01-02 15:04:05")
	prefix := fmt.Sprintf("[%s][%d] ", ts, countConnected)
	return fmt.Printf(prefix + format + "\n", a...)
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
//
// 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 cmd

import (
	"bytes"
	"fmt"
	api "github.com/osrg/gobgp/api"
	"github.com/osrg/gobgp/packet"
	"github.com/spf13/cobra"
	"golang.org/x/net/context"
	"io"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"strconv"
	"text/template"
	"time"
)

func printMrtMsgs(data []byte) {
	buffer := bytes.NewBuffer(data)

	for buffer.Len() > bgp.MRT_COMMON_HEADER_LEN {
		buf := make([]byte, bgp.MRT_COMMON_HEADER_LEN)
		_, err := buffer.Read(buf)
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println("failed to read:", err)
			os.Exit(1)
		}

		h := &bgp.MRTHeader{}
		err = h.DecodeFromBytes(buf)
		if err != nil {
			fmt.Println("failed to parse")
			os.Exit(1)
		}

		buf = make([]byte, h.Len)
		_, err = buffer.Read(buf)
		if err != nil {
			fmt.Println("failed to read")
			os.Exit(1)
		}

		msg, err := bgp.ParseMRTBody(h, buf)
		if err != nil {
			fmt.Println("failed to parse:", err)
			os.Exit(1)
		}

		fmt.Println(msg)
	}

}

func dumpRib(r string, remoteIP net.IP, args []string) error {
	var resource api.Resource
	switch r {
	case CMD_GLOBAL:
		resource = api.Resource_GLOBAL
	case CMD_LOCAL:
		resource = api.Resource_LOCAL
	default:
		return fmt.Errorf("unknown resource type: %s", r)
	}

	family, err := checkAddressFamily(addr2AddressFamily(remoteIP))
	if err != nil {
		return err
	}

	var interval uint64
	if len(args) > 0 {
		i, err := strconv.Atoi(args[0])
		if err != nil {
			return err
		}
		interval = uint64(i)
	}

	arg := &api.MrtArguments{
		Resource:        resource,
		Family:          uint32(family),
		Interval:        interval,
		NeighborAddress: remoteIP.String(),
	}

	afi, _ := bgp.RouteFamilyToAfiSafi(family)
	var af string
	switch afi {
	case bgp.AFI_IP:
		af = "ipv4"
	case bgp.AFI_IP6:
		af = "ipv6"
	case bgp.AFI_L2VPN:
		af = "l2vpn"
	}

	seed := struct {
		Y               string
		M               string
		D               string
		H               string
		Min             string
		Sec             string
		Af              string
		NeighborAddress string
		Resource        string
	}{
		Af:              af,
		NeighborAddress: remoteIP.String(),
		Resource:        r,
	}

	stream, err := client.GetMrt(context.Background(), arg)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var fileformat string

	if mrtOpts.FileFormat != "" {
		fileformat = mrtOpts.FileFormat
	} else if r == CMD_GLOBAL {
		fileformat = "rib_{{.Af}}_{{.Y}}{{.M}}{{.D}}_{{.H}}{{.Min}}{{.Sec}}"
	} else {
		fileformat = "rib_{{.NeighborAddress}}_{{.Y}}{{.M}}{{.D}}_{{.H}}{{.Min}}{{.Sec}}"
	}

	for {
		s, err := stream.Recv()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		if globalOpts.Debug {
			printMrtMsgs(s.Data)
		}

		now := time.Now()
		y, m, d := now.Date()
		seed.Y = fmt.Sprintf("%04d", y)
		seed.M = fmt.Sprintf("%02d", int(m))
		seed.D = fmt.Sprintf("%02d", d)
		h, min, sec := now.Clock()
		seed.H = fmt.Sprintf("%02d", h)
		seed.Min = fmt.Sprintf("%02d", min)
		seed.Sec = fmt.Sprintf("%02d", sec)
		t, err := template.New("f").Parse(fileformat)
		if err != nil {
			return err
		}
		buf := bytes.NewBuffer(make([]byte, 0, 32))
		err = t.Execute(buf, seed)
		if err != nil {
			return err
		}
		filename := fmt.Sprintf("%s/%s", mrtOpts.OutputDir, buf.String())

		err = ioutil.WriteFile(filename, s.Data, 0600)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		fmt.Println("mrt dump:", filepath.Clean(filename))
	}
	return nil
}

func injectMrt(r string, filename string, count int) error {

	var resource api.Resource
	switch r {
	case CMD_GLOBAL:
		resource = api.Resource_GLOBAL
	default:
		return fmt.Errorf("unknown resource type: %s", r)
	}

	file, err := os.Open(filename)
	if err != nil {
		return fmt.Errorf("failed to open file: %s", err)
	}

	idx := 0

	ch := make(chan *api.ModPathsArguments, 1<<20)

	go func() {

		var peers []*bgp.Peer

		for {
			buf := make([]byte, bgp.MRT_COMMON_HEADER_LEN)
			_, err := file.Read(buf)
			if err == io.EOF {
				break
			} else if err != nil {
				fmt.Println("failed to read:", err)
				os.Exit(1)
			}

			h := &bgp.MRTHeader{}
			err = h.DecodeFromBytes(buf)
			if err != nil {
				fmt.Println("failed to parse")
				os.Exit(1)
			}

			buf = make([]byte, h.Len)
			_, err = file.Read(buf)
			if err != nil {
				fmt.Println("failed to read")
				os.Exit(1)
			}

			msg, err := bgp.ParseMRTBody(h, buf)
			if err != nil {
				fmt.Println("failed to parse:", err)
				os.Exit(1)
			}

			if globalOpts.Debug {
				fmt.Println(msg)
			}

			if msg.Header.Type == bgp.TABLE_DUMPv2 {
				subType := bgp.MRTSubTypeTableDumpv2(msg.Header.SubType)
				var rf bgp.RouteFamily
				switch subType {
				case bgp.PEER_INDEX_TABLE:
					peers = msg.Body.(*bgp.PeerIndexTable).Peers
					continue
				case bgp.RIB_IPV4_UNICAST:
					rf = bgp.RF_IPv4_UC
				case bgp.RIB_IPV6_UNICAST:
					rf = bgp.RF_IPv6_UC
				default:
					fmt.Println("unsupported subType:", subType)
					os.Exit(1)
				}

				if peers == nil {
					fmt.Println("not found PEER_INDEX_TABLE")
					os.Exit(1)
				}

				rib := msg.Body.(*bgp.Rib)
				nlri := rib.Prefix

				paths := make([]*api.Path, 0, len(rib.Entries))

				for _, e := range rib.Entries {
					if len(peers) < int(e.PeerIndex) {
						fmt.Printf("invalid peer index: %d (PEER_INDEX_TABLE has only %d peers)\n", e.PeerIndex, len(peers))
						os.Exit(1)
					}

					path := &api.Path{
						Pattrs:             make([][]byte, 0),
						NoImplicitWithdraw: true,
						SourceAsn:          peers[e.PeerIndex].AS,
						SourceId:           peers[e.PeerIndex].BgpId.String(),
					}

					if rf == bgp.RF_IPv4_UC {
						path.Nlri, _ = nlri.Serialize()
					}

					for _, p := range e.PathAttributes {
						b, err := p.Serialize()
						if err != nil {
							continue
						}
						path.Pattrs = append(path.Pattrs, b)
					}

					paths = append(paths, path)
				}

				ch <- &api.ModPathsArguments{
					Resource: resource,
					Paths:    paths,
				}

				idx += 1
				if idx == count {
					break
				}
			}
		}

		close(ch)
	}()

	stream, err := client.ModPaths(context.Background())
	if err != nil {
		return fmt.Errorf("failed to modpath: %s", err)
	}

	for arg := range ch {
		err = stream.Send(arg)
		if err != nil {
			return fmt.Errorf("failed to send: %s", err)
		}
	}

	res, err := stream.CloseAndRecv()
	if err != nil {
		return fmt.Errorf("failed to send: %s", err)
	}
	if res.Code != api.Error_SUCCESS {
		return fmt.Errorf("error: code: %d, msg: %s", res.Code, res.Msg)
	}
	return nil
}

func NewMrtCmd() *cobra.Command {

	globalDumpCmd := &cobra.Command{
		Use: CMD_GLOBAL,
		Run: func(cmd *cobra.Command, args []string) {
			err := dumpRib(CMD_GLOBAL, net.IP{}, args)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}

	neighborCmd := &cobra.Command{
		Use: CMD_NEIGHBOR,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) < 1 {
				fmt.Println("usage: gobgp mrt dump neighbor <neighbor address> [<interval>]")
				os.Exit(1)
			}
			remoteIP := net.ParseIP(args[0])
			if remoteIP == nil {
				fmt.Println("invalid ip address:", args[0])
				os.Exit(1)
			}
			err := dumpRib(CMD_LOCAL, remoteIP, args[1:])
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}

	ribCmd := &cobra.Command{
		Use: CMD_RIB,
	}
	ribCmd.AddCommand(globalDumpCmd, neighborCmd)
	ribCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family")

	dumpCmd := &cobra.Command{
		Use: CMD_DUMP,
	}
	dumpCmd.AddCommand(ribCmd)
	dumpCmd.PersistentFlags().StringVarP(&mrtOpts.OutputDir, "outdir", "o", ".", "output directory")
	dumpCmd.PersistentFlags().StringVarP(&mrtOpts.FileFormat, "format", "f", "", "file format")

	globalInjectCmd := &cobra.Command{
		Use: CMD_GLOBAL,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) < 1 {
				fmt.Println("usage: gobgp mrt inject global <filename> [<count>]")
				os.Exit(1)
			}
			filename := args[0]
			count := -1
			if len(args) > 1 {
				var err error
				count, err = strconv.Atoi(args[1])
				if err != nil {
					fmt.Println("invalid count value:", args[1])
					os.Exit(1)
				}
			}
			err := injectMrt(CMD_GLOBAL, filename, count)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}

	injectCmd := &cobra.Command{
		Use: CMD_INJECT,
	}
	injectCmd.AddCommand(globalInjectCmd)

	modMrt := func(op api.Operation, filename string) {
		arg := &api.ModMrtArguments{
			Operation: op,
			Filename:  filename,
		}
		client.ModMrt(context.Background(), arg)
	}

	enableCmd := &cobra.Command{
		Use: CMD_ENABLE,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) != 1 {
				fmt.Println("usage: gobgp mrt update enable <filename>")
				os.Exit(1)
			}
			modMrt(api.Operation_ADD, args[0])
		},
	}

	disableCmd := &cobra.Command{
		Use: CMD_DISABLE,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) != 0 {
				fmt.Println("usage: gobgp mrt update disable")
				os.Exit(1)
			}
			modMrt(api.Operation_DEL, "")
		},
	}

	rotateCmd := &cobra.Command{
		Use: CMD_ROTATE,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) != 1 {
				fmt.Println("usage: gobgp mrt update rotate <filename>")
				os.Exit(1)
			}
			modMrt(api.Operation_REPLACE, args[0])
		},
	}

	restartCmd := &cobra.Command{
		Use: CMD_RESET,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) > 0 {
				fmt.Println("usage: gobgp mrt update reset")
				os.Exit(1)
			}
			modMrt(api.Operation_REPLACE, "")
		},
	}

	updateCmd := &cobra.Command{
		Use: CMD_UPDATE,
	}
	updateCmd.AddCommand(enableCmd, disableCmd, restartCmd, rotateCmd)

	mrtCmd := &cobra.Command{
		Use: CMD_MRT,
	}
	mrtCmd.AddCommand(dumpCmd, injectCmd, updateCmd)

	return mrtCmd
}
<commit_msg>mrt: ability to skip entries when injecting<commit_after>// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
//
// 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 cmd

import (
	"bytes"
	"fmt"
	api "github.com/osrg/gobgp/api"
	"github.com/osrg/gobgp/packet"
	"github.com/spf13/cobra"
	"golang.org/x/net/context"
	"io"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"strconv"
	"text/template"
	"time"
)

func printMrtMsgs(data []byte) {
	buffer := bytes.NewBuffer(data)

	for buffer.Len() > bgp.MRT_COMMON_HEADER_LEN {
		buf := make([]byte, bgp.MRT_COMMON_HEADER_LEN)
		_, err := buffer.Read(buf)
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println("failed to read:", err)
			os.Exit(1)
		}

		h := &bgp.MRTHeader{}
		err = h.DecodeFromBytes(buf)
		if err != nil {
			fmt.Println("failed to parse")
			os.Exit(1)
		}

		buf = make([]byte, h.Len)
		_, err = buffer.Read(buf)
		if err != nil {
			fmt.Println("failed to read")
			os.Exit(1)
		}

		msg, err := bgp.ParseMRTBody(h, buf)
		if err != nil {
			fmt.Println("failed to parse:", err)
			os.Exit(1)
		}

		fmt.Println(msg)
	}

}

func dumpRib(r string, remoteIP net.IP, args []string) error {
	var resource api.Resource
	switch r {
	case CMD_GLOBAL:
		resource = api.Resource_GLOBAL
	case CMD_LOCAL:
		resource = api.Resource_LOCAL
	default:
		return fmt.Errorf("unknown resource type: %s", r)
	}

	family, err := checkAddressFamily(addr2AddressFamily(remoteIP))
	if err != nil {
		return err
	}

	var interval uint64
	if len(args) > 0 {
		i, err := strconv.Atoi(args[0])
		if err != nil {
			return err
		}
		interval = uint64(i)
	}

	arg := &api.MrtArguments{
		Resource:        resource,
		Family:          uint32(family),
		Interval:        interval,
		NeighborAddress: remoteIP.String(),
	}

	afi, _ := bgp.RouteFamilyToAfiSafi(family)
	var af string
	switch afi {
	case bgp.AFI_IP:
		af = "ipv4"
	case bgp.AFI_IP6:
		af = "ipv6"
	case bgp.AFI_L2VPN:
		af = "l2vpn"
	}

	seed := struct {
		Y               string
		M               string
		D               string
		H               string
		Min             string
		Sec             string
		Af              string
		NeighborAddress string
		Resource        string
	}{
		Af:              af,
		NeighborAddress: remoteIP.String(),
		Resource:        r,
	}

	stream, err := client.GetMrt(context.Background(), arg)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var fileformat string

	if mrtOpts.FileFormat != "" {
		fileformat = mrtOpts.FileFormat
	} else if r == CMD_GLOBAL {
		fileformat = "rib_{{.Af}}_{{.Y}}{{.M}}{{.D}}_{{.H}}{{.Min}}{{.Sec}}"
	} else {
		fileformat = "rib_{{.NeighborAddress}}_{{.Y}}{{.M}}{{.D}}_{{.H}}{{.Min}}{{.Sec}}"
	}

	for {
		s, err := stream.Recv()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		if globalOpts.Debug {
			printMrtMsgs(s.Data)
		}

		now := time.Now()
		y, m, d := now.Date()
		seed.Y = fmt.Sprintf("%04d", y)
		seed.M = fmt.Sprintf("%02d", int(m))
		seed.D = fmt.Sprintf("%02d", d)
		h, min, sec := now.Clock()
		seed.H = fmt.Sprintf("%02d", h)
		seed.Min = fmt.Sprintf("%02d", min)
		seed.Sec = fmt.Sprintf("%02d", sec)
		t, err := template.New("f").Parse(fileformat)
		if err != nil {
			return err
		}
		buf := bytes.NewBuffer(make([]byte, 0, 32))
		err = t.Execute(buf, seed)
		if err != nil {
			return err
		}
		filename := fmt.Sprintf("%s/%s", mrtOpts.OutputDir, buf.String())

		err = ioutil.WriteFile(filename, s.Data, 0600)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		fmt.Println("mrt dump:", filepath.Clean(filename))
	}
	return nil
}

func injectMrt(r string, filename string, count int, skip int) error {

	var resource api.Resource
	switch r {
	case CMD_GLOBAL:
		resource = api.Resource_GLOBAL
	default:
		return fmt.Errorf("unknown resource type: %s", r)
	}

	file, err := os.Open(filename)
	if err != nil {
		return fmt.Errorf("failed to open file: %s", err)
	}

	idx := 0

	ch := make(chan *api.ModPathsArguments, 1<<20)

	go func() {

		var peers []*bgp.Peer

		for {
			buf := make([]byte, bgp.MRT_COMMON_HEADER_LEN)
			_, err := file.Read(buf)
			if err == io.EOF {
				break
			} else if err != nil {
				fmt.Println("failed to read:", err)
				os.Exit(1)
			}

			h := &bgp.MRTHeader{}
			err = h.DecodeFromBytes(buf)
			if err != nil {
				fmt.Println("failed to parse")
				os.Exit(1)
			}

			buf = make([]byte, h.Len)
			_, err = file.Read(buf)
			if err != nil {
				fmt.Println("failed to read")
				os.Exit(1)
			}

			msg, err := bgp.ParseMRTBody(h, buf)
			if err != nil {
				fmt.Println("failed to parse:", err)
				os.Exit(1)
			}

			if globalOpts.Debug {
				fmt.Println(msg)
			}

			if msg.Header.Type == bgp.TABLE_DUMPv2 {
				subType := bgp.MRTSubTypeTableDumpv2(msg.Header.SubType)
				var rf bgp.RouteFamily
				switch subType {
				case bgp.PEER_INDEX_TABLE:
					peers = msg.Body.(*bgp.PeerIndexTable).Peers
					continue
				case bgp.RIB_IPV4_UNICAST:
					rf = bgp.RF_IPv4_UC
				case bgp.RIB_IPV6_UNICAST:
					rf = bgp.RF_IPv6_UC
				default:
					fmt.Println("unsupported subType:", subType)
					os.Exit(1)
				}

				if peers == nil {
					fmt.Println("not found PEER_INDEX_TABLE")
					os.Exit(1)
				}

				rib := msg.Body.(*bgp.Rib)
				nlri := rib.Prefix

				paths := make([]*api.Path, 0, len(rib.Entries))

				for _, e := range rib.Entries {
					if len(peers) < int(e.PeerIndex) {
						fmt.Printf("invalid peer index: %d (PEER_INDEX_TABLE has only %d peers)\n", e.PeerIndex, len(peers))
						os.Exit(1)
					}

					path := &api.Path{
						Pattrs:             make([][]byte, 0),
						NoImplicitWithdraw: true,
						SourceAsn:          peers[e.PeerIndex].AS,
						SourceId:           peers[e.PeerIndex].BgpId.String(),
					}

					if rf == bgp.RF_IPv4_UC {
						path.Nlri, _ = nlri.Serialize()
					}

					for _, p := range e.PathAttributes {
						b, err := p.Serialize()
						if err != nil {
							continue
						}
						path.Pattrs = append(path.Pattrs, b)
					}

					paths = append(paths, path)
				}

				if idx >= skip {
					ch <- &api.ModPathsArguments{
						Resource: resource,
						Paths:    paths,
					}
				}

				idx += 1
				if idx == count+skip {
					break
				}
			}
		}

		close(ch)
	}()

	stream, err := client.ModPaths(context.Background())
	if err != nil {
		return fmt.Errorf("failed to modpath: %s", err)
	}

	for arg := range ch {
		err = stream.Send(arg)
		if err != nil {
			return fmt.Errorf("failed to send: %s", err)
		}
	}

	res, err := stream.CloseAndRecv()
	if err != nil {
		return fmt.Errorf("failed to send: %s", err)
	}
	if res.Code != api.Error_SUCCESS {
		return fmt.Errorf("error: code: %d, msg: %s", res.Code, res.Msg)
	}
	return nil
}

func NewMrtCmd() *cobra.Command {

	globalDumpCmd := &cobra.Command{
		Use: CMD_GLOBAL,
		Run: func(cmd *cobra.Command, args []string) {
			err := dumpRib(CMD_GLOBAL, net.IP{}, args)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}

	neighborCmd := &cobra.Command{
		Use: CMD_NEIGHBOR,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) < 1 {
				fmt.Println("usage: gobgp mrt dump neighbor <neighbor address> [<interval>]")
				os.Exit(1)
			}
			remoteIP := net.ParseIP(args[0])
			if remoteIP == nil {
				fmt.Println("invalid ip address:", args[0])
				os.Exit(1)
			}
			err := dumpRib(CMD_LOCAL, remoteIP, args[1:])
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}

	ribCmd := &cobra.Command{
		Use: CMD_RIB,
	}
	ribCmd.AddCommand(globalDumpCmd, neighborCmd)
	ribCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family")

	dumpCmd := &cobra.Command{
		Use: CMD_DUMP,
	}
	dumpCmd.AddCommand(ribCmd)
	dumpCmd.PersistentFlags().StringVarP(&mrtOpts.OutputDir, "outdir", "o", ".", "output directory")
	dumpCmd.PersistentFlags().StringVarP(&mrtOpts.FileFormat, "format", "f", "", "file format")

	globalInjectCmd := &cobra.Command{
		Use: CMD_GLOBAL,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) < 1 {
				fmt.Println("usage: gobgp mrt inject global <filename> [<count> [<skip>]]")
				os.Exit(1)
			}
			filename := args[0]
			count := -1
			skip := 0
			if len(args) > 1 {
				var err error
				count, err = strconv.Atoi(args[1])
				if err != nil {
					fmt.Println("invalid count value:", args[1])
					os.Exit(1)
				}
				if len(args) > 2 {
					skip, err = strconv.Atoi(args[2])
					if err != nil {
						fmt.Println("invalid skip value:", args[2])
						os.Exit(1)
					}
				}
			}
			err := injectMrt(CMD_GLOBAL, filename, count, skip)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}

	injectCmd := &cobra.Command{
		Use: CMD_INJECT,
	}
	injectCmd.AddCommand(globalInjectCmd)

	modMrt := func(op api.Operation, filename string) {
		arg := &api.ModMrtArguments{
			Operation: op,
			Filename:  filename,
		}
		client.ModMrt(context.Background(), arg)
	}

	enableCmd := &cobra.Command{
		Use: CMD_ENABLE,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) != 1 {
				fmt.Println("usage: gobgp mrt update enable <filename>")
				os.Exit(1)
			}
			modMrt(api.Operation_ADD, args[0])
		},
	}

	disableCmd := &cobra.Command{
		Use: CMD_DISABLE,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) != 0 {
				fmt.Println("usage: gobgp mrt update disable")
				os.Exit(1)
			}
			modMrt(api.Operation_DEL, "")
		},
	}

	rotateCmd := &cobra.Command{
		Use: CMD_ROTATE,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) != 1 {
				fmt.Println("usage: gobgp mrt update rotate <filename>")
				os.Exit(1)
			}
			modMrt(api.Operation_REPLACE, args[0])
		},
	}

	restartCmd := &cobra.Command{
		Use: CMD_RESET,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) > 0 {
				fmt.Println("usage: gobgp mrt update reset")
				os.Exit(1)
			}
			modMrt(api.Operation_REPLACE, "")
		},
	}

	updateCmd := &cobra.Command{
		Use: CMD_UPDATE,
	}
	updateCmd.AddCommand(enableCmd, disableCmd, restartCmd, rotateCmd)

	mrtCmd := &cobra.Command{
		Use: CMD_MRT,
	}
	mrtCmd.AddCommand(dumpCmd, injectCmd, updateCmd)

	return mrtCmd
}
<|endoftext|>


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

package godiff

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

	"github.com/pmezard/go-difflib/difflib"
)

func UnifiedDiffLines(a []string, b []string) (string, error) {
	diff := difflib.UnifiedDiff{
		A:        a,
		B:        b,
		FromFile: "Original",
		ToFile:   "Current",
		Context:  3,
		Eol:      "\n",
	}
	return difflib.GetUnifiedDiffString(diff)
}

func UnifiedDiffString(a string, b string) (string, error) {
	diff := difflib.UnifiedDiff{
		A:        difflib.SplitLines(a),
		B:        difflib.SplitLines(b),
		FromFile: "Original",
		ToFile:   "Current",
		Context:  3,
		Eol:      "\n",
	}
	return difflib.GetUnifiedDiffString(diff)
}

func UnifiedDiffBytesByCmd(b1, b2 []byte) (data []byte, err error) {
	f1, err := ioutil.TempFile("", "godiff")
	if err != nil {
		return
	}
	defer os.Remove(f1.Name())
	defer f1.Close()

	f2, err := ioutil.TempFile("", "godiff")
	if err != nil {
		return
	}
	defer os.Remove(f2.Name())
	defer f2.Close()

	f1.Write(b1)
	f2.Write(b2)

	data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
	if len(data) > 0 {
		// diff exits with a non-zero status when the files don't match.
		// Ignore that failure as long as we get output.
		err = nil
	}
	return
}
<commit_msg>use fixed go-difflib<commit_after>// Copyright 2011-2015 visualfc <visualfc@gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package godiff

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

	"github.com/visualfc/go-difflib/difflib"
)

func UnifiedDiffLines(a []string, b []string) (string, error) {
	diff := difflib.UnifiedDiff{
		A:        a,
		B:        b,
		FromFile: "Original",
		ToFile:   "Current",
		Context:  3,
		Eol:      "\n",
	}
	return difflib.GetUnifiedDiffString(diff)
}

func UnifiedDiffString(a string, b string) (string, error) {
	diff := difflib.UnifiedDiff{
		A:        difflib.SplitLines(a),
		B:        difflib.SplitLines(b),
		FromFile: "Original",
		ToFile:   "Current",
		Context:  3,
		Eol:      "\n",
	}
	return difflib.GetUnifiedDiffString(diff)
}

func UnifiedDiffBytesByCmd(b1, b2 []byte) (data []byte, err error) {
	f1, err := ioutil.TempFile("", "godiff")
	if err != nil {
		return
	}
	defer os.Remove(f1.Name())
	defer f1.Close()

	f2, err := ioutil.TempFile("", "godiff")
	if err != nil {
		return
	}
	defer os.Remove(f2.Name())
	defer f2.Close()

	f1.Write(b1)
	f2.Write(b2)

	data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
	if len(data) > 0 {
		// diff exits with a non-zero status when the files don't match.
		// Ignore that failure as long as we get output.
		err = nil
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/droundy/goopt"
	"time"
	"fmt"
	"bitbucket.org/cswank/gogadgets"
	"os"
)

var (
	host = goopt.String([]string{"-h", "--host"}, "localhost", "Name of Host")
	config = goopt.String([]string{"-g", "--gadgets"}, "", "Path to a Gadgets config file")
	cmd = goopt.String([]string{"-c", "--cmd"}, "", "a Robot Command Language string")
)

func main() {
	goopt.Parse(nil)
	fmt.Println(len(*config))
	if len(*config) > 0 {
		runGadgets()
	} else if len(*cmd) > 0 {
		sendCommand()
	}
}

func runGadgets() {
	a := gogadgets.NewApp(config)
	a.Start()
}

func sendCommand() {
	s, err := gogadgets.NewClientSockets(*host)
	defer s.Close()
	if err != nil {
		panic(err)
	}
	time.Sleep(100 * time.Millisecond)
	fmt.Println(*cmd, "host", *host)
	s.Send(*cmd)
	time.Sleep(100 * time.Millisecond)
	os.Exit(0)
}

//Waits for a zmq message that contains a gogadgets
//config.  When one is recieved it is parsed and a
//a gogadgts system is started.
func listen() {

}
<commit_msg>fixed cli error<commit_after>package main

import (
	"github.com/droundy/goopt"
	"time"
	"fmt"
	"bitbucket.org/cswank/gogadgets"
	"os"
)

var (
	host = goopt.String([]string{"-h", "--host"}, "localhost", "Name of Host")
	config = goopt.String([]string{"-g", "--gadgets"}, "", "Path to a Gadgets config file")
	cmd = goopt.String([]string{"-c", "--cmd"}, "", "a Robot Command Language string")
)

func main() {
	goopt.Parse(nil)
	fmt.Println(len(*config))
	if len(*config) > 0 {
		runGadgets()
	} else if len(*cmd) > 0 {
		sendCommand()
	}
}

func runGadgets() {
	a := gogadgets.NewApp(*config)
	a.Start()
}

func sendCommand() {
	s, err := gogadgets.NewClientSockets(*host)
	defer s.Close()
	if err != nil {
		panic(err)
	}
	time.Sleep(100 * time.Millisecond)
	fmt.Println(*cmd, "host", *host)
	s.Send(*cmd)
	time.Sleep(100 * time.Millisecond)
	os.Exit(0)
}

//Waits for a zmq message that contains a gogadgets
//config.  When one is recieved it is parsed and a
//a gogadgts system is started.
func listen() {

}
<|endoftext|>


<commit_before>package main

import (
	"reflect"
	"regexp"
	"testing"
)

var delimiterSetTests = []struct {
	useRegexp bool
	expr      string
	re        *regexp.Regexp
}{
	// fixed
	{false, `=`, regexp.MustCompile(`=`)},
	{false, `=+`, regexp.MustCompile(`=\+`)},
	{false, `-*>`, regexp.MustCompile(`-\*>`)},
	{false, `abc`, regexp.MustCompile(`abc`)},
	{false, `\w+:`, regexp.MustCompile(`\\w\+:`)},
	{false, `[:/]+`, regexp.MustCompile(`\[:/\]\+`)},

	// regexp
	{true, `=`, regexp.MustCompile(`=`)},
	{true, `=+`, regexp.MustCompile(`=+`)},
	{true, `-*>`, regexp.MustCompile(`-*>`)},
	{true, `abc`, regexp.MustCompile(`abc`)},
	{true, `\w+:`, regexp.MustCompile(`\w+:`)},
	{true, `[:/]+`, regexp.MustCompile(`[:/]+`)},
}

func TestDelimiterSet(t *testing.T) {
	for _, test := range delimiterSetTests {
		d, err := NewDelimiter(test.expr, test.useRegexp, -1)
		if err != nil {
			t.Errorf("NewDelimiter(%q, %v, %v) returns %q; want nil",
				test.expr, test.useRegexp, -1, err)
		}
		if !reflect.DeepEqual(d.re, test.re) {
			t.Errorf("NewDelimiter(%q, %v, %v).re got %q; want %q",
				test.expr, test.useRegexp, -1, d.re, test.re)
		}
	}
}

var delimiterSplitDefaultTests = []struct {
	src string
	dst []string
}{
	// normal
	{"a", []string{"a"}},
	{"a b", []string{"a", "b"}},
	{"a b c", []string{"a", "b", "c"}},
	{"a b c d", []string{"a", "b", "c", "d"}},
	{"ab cd", []string{"ab", "cd"}},
	{"日本 語", []string{"日本", "語"}},

	// long spaces
	{"a  b", []string{"a", "b"}},
	{"a  b c", []string{"a", "b", "c"}},
	{"a \t b c", []string{"a", "b", "c"}},

	// head and tail spaces
	{"  a b c", []string{"", "a", "b", "c"}},
	{"a b c ", []string{"a", "b", "c", ""}},
}

func TestDelimiterDefaultSplit(t *testing.T) {
	d := NewDelimiterDefault()
	for _, test := range delimiterSplitDefaultTests {
		actual := d.Split(test.src)
		expect := test.dst
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("NewDelimiterDefault().Split(%q) = %q; want %q",
				test.src, actual, expect)
		}
	}
}

var delimiterSplitTests = []struct {
	useRegexp bool
	expr      string
	src       string
	dst       []string
}{
	{false, `=`, "n", []string{"n"}},
	{false, `=`, "n=", []string{"n", "=", ""}},
	{false, `=`, "=n", []string{"", "=", "n"}},

	{false, `=`, "n=100", []string{"n", "=", "100"}},
	{false, `=`, "n  =  100", []string{"n", "=", "100"}},
	{false, `=`, "n  = 100=200", []string{"n", "=", "100", "=", "200"}},
	{false, `=`, "n=100 =  200", []string{"n", "=", "100", "=", "200"}},

	{false, `=`, "n==100", []string{"n", "=", "", "=", "100"}},
	{false, `=`, "n===100", []string{"n", "=", "", "=", "", "=", "100"}},

	{false, `=>`, "a=>b=>c", []string{"a", "=>", "b", "=>", "c"}},
	{false, `=>`, "a => b => c", []string{"a", "=>", "b", "=>", "c"}},
	{false, `=>`, "a==>=b==>=c", []string{"a=", "=>", "=b=", "=>", "=c"}},

	{true, `=+>`, "a => b",
		[]string{"a", "=>", "b"}},
	{true, `=+>`, "a => b ==> c ===> d",
		[]string{"a", "=>", "b", "==>", "c", "===>", "d"}},
	{true, `=+>`, "a=>b==>=c",
		[]string{"a", "=>", "b", "==>", "=c"}},
}

func TestDelimiterSplit(t *testing.T) {
	for _, test := range delimiterSplitTests {
		d, err := NewDelimiter(test.expr, test.useRegexp, -1)
		if err != nil {
			t.Errorf("NewDelimiter(%q, %v, %v) returns %q; want nil",
				test.expr, test.useRegexp, -1, err)
		}

		actual := d.Split(test.src)
		expect := test.dst
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("NewDelimiter(%q, %v, %v).Split(%q) = %q; want %q",
				test.expr, test.useRegexp, -1, test.src, actual, expect)
		}
	}
}

var delimiterSplitWithCountTests = []struct {
	count int
	src   string
	dst   []string
}{
	// less than 1
	{-2, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
	{-1, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
	{0, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},

	// greater than 0
	{1, "n =  m   =    100", []string{"n", "=  m   =    100"}},
	{2, "n =  m   =    100", []string{"n", "=", "m   =    100"}},
	{3, "n =  m   =    100", []string{"n", "=", "m", "=    100"}},
	{4, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
	{5, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
}

func TestSplitWithCount(t *testing.T) {
	delim := "="
	for _, test := range delimiterSplitWithCountTests {
		d, err := NewDelimiter(delim, false, test.count)
		if err != nil {
			t.Errorf("NewDelimiter(%q, %v, %v) returns %q; want nil",
				delim, false, test.count, err)
		}

		actual := d.Split(test.src)
		expect := test.dst
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("NewDelimiter(%q, %v, %v).Split(%q) = %q; want %q",
				delim, false, test.count, test.src, actual, expect)
		}
	}
}
<commit_msg>Rewrite test to remove NewDelimiterDefault<commit_after>package main

import (
	"reflect"
	"regexp"
	"testing"
)

var delimiterSetTests = []struct {
	useRegexp bool
	expr      string
	re        *regexp.Regexp
}{
	// fixed
	{false, `=`, regexp.MustCompile(`=`)},
	{false, `=+`, regexp.MustCompile(`=\+`)},
	{false, `-*>`, regexp.MustCompile(`-\*>`)},
	{false, `abc`, regexp.MustCompile(`abc`)},
	{false, `\w+:`, regexp.MustCompile(`\\w\+:`)},
	{false, `[:/]+`, regexp.MustCompile(`\[:/\]\+`)},

	// regexp
	{true, `=`, regexp.MustCompile(`=`)},
	{true, `=+`, regexp.MustCompile(`=+`)},
	{true, `-*>`, regexp.MustCompile(`-*>`)},
	{true, `abc`, regexp.MustCompile(`abc`)},
	{true, `\w+:`, regexp.MustCompile(`\w+:`)},
	{true, `[:/]+`, regexp.MustCompile(`[:/]+`)},
}

func TestDelimiterSet(t *testing.T) {
	for _, test := range delimiterSetTests {
		d, err := NewDelimiter(test.expr, test.useRegexp, -1)
		if err != nil {
			t.Errorf("NewDelimiter(%q, %v, %v) returns %q; want nil",
				test.expr, test.useRegexp, -1, err)
		}
		if !reflect.DeepEqual(d.re, test.re) {
			t.Errorf("NewDelimiter(%q, %v, %v).re got %q; want %q",
				test.expr, test.useRegexp, -1, d.re, test.re)
		}
	}
}

var delimiterSplitDefaultTests = []struct {
	src string
	dst []string
}{
	// normal
	{"a", []string{"a"}},
	{"a b", []string{"a", "b"}},
	{"a b c", []string{"a", "b", "c"}},
	{"a b c d", []string{"a", "b", "c", "d"}},
	{"ab cd", []string{"ab", "cd"}},
	{"日本 語", []string{"日本", "語"}},

	// long spaces
	{"a  b", []string{"a", "b"}},
	{"a  b c", []string{"a", "b", "c"}},
	{"a \t b c", []string{"a", "b", "c"}},

	// head and tail spaces
	{"  a b c", []string{"", "a", "b", "c"}},
	{"a b c ", []string{"a", "b", "c", ""}},
}

func TestDelimiterDefaultSplit(t *testing.T) {
	d, _ := NewDelimiter("", false, 0)
	for _, test := range delimiterSplitDefaultTests {
		actual := d.Split(test.src)
		expect := test.dst
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("NewDelimiter(%q, %v, %v).Split(%q) = %q; want %q",
				"", false, 0, test.src, actual, expect)
		}
	}
}

var delimiterSplitTests = []struct {
	useRegexp bool
	expr      string
	src       string
	dst       []string
}{
	{false, `=`, "n", []string{"n"}},
	{false, `=`, "n=", []string{"n", "=", ""}},
	{false, `=`, "=n", []string{"", "=", "n"}},

	{false, `=`, "n=100", []string{"n", "=", "100"}},
	{false, `=`, "n  =  100", []string{"n", "=", "100"}},
	{false, `=`, "n  = 100=200", []string{"n", "=", "100", "=", "200"}},
	{false, `=`, "n=100 =  200", []string{"n", "=", "100", "=", "200"}},

	{false, `=`, "n==100", []string{"n", "=", "", "=", "100"}},
	{false, `=`, "n===100", []string{"n", "=", "", "=", "", "=", "100"}},

	{false, `=>`, "a=>b=>c", []string{"a", "=>", "b", "=>", "c"}},
	{false, `=>`, "a => b => c", []string{"a", "=>", "b", "=>", "c"}},
	{false, `=>`, "a==>=b==>=c", []string{"a=", "=>", "=b=", "=>", "=c"}},

	{true, `=+>`, "a => b",
		[]string{"a", "=>", "b"}},
	{true, `=+>`, "a => b ==> c ===> d",
		[]string{"a", "=>", "b", "==>", "c", "===>", "d"}},
	{true, `=+>`, "a=>b==>=c",
		[]string{"a", "=>", "b", "==>", "=c"}},
}

func TestDelimiterSplit(t *testing.T) {
	for _, test := range delimiterSplitTests {
		d, err := NewDelimiter(test.expr, test.useRegexp, -1)
		if err != nil {
			t.Errorf("NewDelimiter(%q, %v, %v) returns %q; want nil",
				test.expr, test.useRegexp, -1, err)
		}

		actual := d.Split(test.src)
		expect := test.dst
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("NewDelimiter(%q, %v, %v).Split(%q) = %q; want %q",
				test.expr, test.useRegexp, -1, test.src, actual, expect)
		}
	}
}

var delimiterSplitWithCountTests = []struct {
	count int
	src   string
	dst   []string
}{
	// less than 1
	{-2, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
	{-1, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
	{0, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},

	// greater than 0
	{1, "n =  m   =    100", []string{"n", "=  m   =    100"}},
	{2, "n =  m   =    100", []string{"n", "=", "m   =    100"}},
	{3, "n =  m   =    100", []string{"n", "=", "m", "=    100"}},
	{4, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
	{5, "n =  m   =    100", []string{"n", "=", "m", "=", "100"}},
}

func TestSplitWithCount(t *testing.T) {
	delim := "="
	for _, test := range delimiterSplitWithCountTests {
		d, err := NewDelimiter(delim, false, test.count)
		if err != nil {
			t.Errorf("NewDelimiter(%q, %v, %v) returns %q; want nil",
				delim, false, test.count, err)
		}

		actual := d.Split(test.src)
		expect := test.dst
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("NewDelimiter(%q, %v, %v).Split(%q) = %q; want %q",
				delim, false, test.count, test.src, actual, expect)
		}
	}
}
<|endoftext|>


<commit_before>package amqptee

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	_ "code.google.com/p/gosqlite/sqlite3"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	"github.com/modcloth-labs/schema_ensurer"
	"github.com/nu7hatch/gouuid"
	"github.com/streadway/amqp"
)

var (
	migrationFormats = map[string][]string{
		"20131108000000_%s": {`
	  CREATE TABLE IF NOT EXISTS %s(
		uuid char(32),

    content_type character varying(256),
    content_encoding character varying(256),
    delivery_mode smallint,
    priority smallint,
    correlation_id character varying(256),
    reply_to character varying(256),
    expiration character varying(256),
    timestamp timestamp with time zone,
    type character varying(256),
    user_id character varying(256),

    exchange character varying(256),
    routing_key character varying(256),

		body text,

		created_at timestamp without time zone NOT NULL
	  );
	  `,
		},
	}
	insertSqlNormalFormat = `
      INSERT INTO %s(
        uuid,
        content_type,
        content_encoding,
        delivery_mode,
        priority,
        correlation_id,
        reply_to,
        expiration,
        timestamp,
        type,
        user_id,
        exchange,
        routing_key,
        body,
        created_at
      ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  `
	insertSqlPostgresFormat = `
      INSERT INTO %s(
        uuid,
        content_type,
        content_encoding,
        delivery_mode,
        priority,
        correlation_id,
        reply_to,
        expiration,
        timestamp,
        type,
        user_id,
        exchange,
        routing_key,
        body,
        created_at
      ) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
  `
)

type DeliveryStore struct {
	db              *sql.DB
	insertStatement *sql.Stmt
}

func NewDeliveryStore(databaseDriver string, databaseUri string, table string) (deliveryStore *DeliveryStore, err error) {
	me := &DeliveryStore{}

	if me.db, err = sql.Open(databaseDriver, databaseUri); err != nil {
		return nil, err
	}

	if err = me.runMigrations(table); err != nil {
		return nil, err
	}

	insertSqlFormat := insertSqlNormalFormat
	if databaseDriver == "postgres" {
		insertSqlFormat = insertSqlPostgresFormat
	}

	if me.insertStatement, err = me.db.Prepare(fmt.Sprintf(insertSqlFormat, table)); err != nil {
		return nil, err
	}

	return me, nil
}

func (me *DeliveryStore) runMigrations(table string) (err error) {
	migrations := map[string][]string{}

	for migrationFormatTag, migrationStatementFormats := range migrationFormats {
		for _, migrationStatementFormat := range migrationStatementFormats {
			migrations[fmt.Sprintf(migrationFormatTag, table)] = append(
				migrations[fmt.Sprintf(migrationFormatTag, table)],
				fmt.Sprintf(migrationStatementFormat, table))
		}
	}

	schemaEnsurer := sensurer.New(me.db, migrations, log.New(ioutil.Discard, "", 0))
	if err = schemaEnsurer.EnsureSchema(); err != nil {
		return err
	}

	return nil
}

func (me *DeliveryStore) Store(delivery *amqp.Delivery) (err error) {
	var (
		u4 *uuid.UUID
	)

	if u4, err = uuid.NewV4(); err != nil {
		return err
	}

	_, err = me.insertStatement.Exec(
		u4.String(),
		delivery.ContentType,
		delivery.ContentEncoding,
		delivery.DeliveryMode,
		delivery.Priority,
		delivery.CorrelationId,
		delivery.ReplyTo,
		delivery.Expiration,
		delivery.Timestamp,
		delivery.Type,
		delivery.UserId,
		delivery.Exchange,
		delivery.RoutingKey,
		delivery.Body,
		time.Now())

	return err
}

func (me *DeliveryStore) Close() {
	me.db.Close()
}
<commit_msg>Increasing UUID length to include -s<commit_after>package amqptee

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	_ "code.google.com/p/gosqlite/sqlite3"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	"github.com/modcloth-labs/schema_ensurer"
	"github.com/nu7hatch/gouuid"
	"github.com/streadway/amqp"
)

var (
	migrationFormats = map[string][]string{
		"20131108000000_%s": {`
	  CREATE TABLE IF NOT EXISTS %s(
		uuid char(36),

    content_type character varying(256),
    content_encoding character varying(256),
    delivery_mode smallint,
    priority smallint,
    correlation_id character varying(256),
    reply_to character varying(256),
    expiration character varying(256),
    timestamp timestamp with time zone,
    type character varying(256),
    user_id character varying(256),

    exchange character varying(256),
    routing_key character varying(256),

		body text,

		created_at timestamp without time zone NOT NULL
	  );
	  `,
		},
	}
	insertSqlNormalFormat = `
      INSERT INTO %s(
        uuid,
        content_type,
        content_encoding,
        delivery_mode,
        priority,
        correlation_id,
        reply_to,
        expiration,
        timestamp,
        type,
        user_id,
        exchange,
        routing_key,
        body,
        created_at
      ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  `
	insertSqlPostgresFormat = `
      INSERT INTO %s(
        uuid,
        content_type,
        content_encoding,
        delivery_mode,
        priority,
        correlation_id,
        reply_to,
        expiration,
        timestamp,
        type,
        user_id,
        exchange,
        routing_key,
        body,
        created_at
      ) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
  `
)

type DeliveryStore struct {
	db              *sql.DB
	insertStatement *sql.Stmt
}

func NewDeliveryStore(databaseDriver string, databaseUri string, table string) (deliveryStore *DeliveryStore, err error) {
	me := &DeliveryStore{}

	if me.db, err = sql.Open(databaseDriver, databaseUri); err != nil {
		return nil, err
	}

	if err = me.runMigrations(table); err != nil {
		return nil, err
	}

	insertSqlFormat := insertSqlNormalFormat
	if databaseDriver == "postgres" {
		insertSqlFormat = insertSqlPostgresFormat
	}

	if me.insertStatement, err = me.db.Prepare(fmt.Sprintf(insertSqlFormat, table)); err != nil {
		return nil, err
	}

	return me, nil
}

func (me *DeliveryStore) runMigrations(table string) (err error) {
	migrations := map[string][]string{}

	for migrationFormatTag, migrationStatementFormats := range migrationFormats {
		for _, migrationStatementFormat := range migrationStatementFormats {
			migrations[fmt.Sprintf(migrationFormatTag, table)] = append(
				migrations[fmt.Sprintf(migrationFormatTag, table)],
				fmt.Sprintf(migrationStatementFormat, table))
		}
	}

	schemaEnsurer := sensurer.New(me.db, migrations, log.New(ioutil.Discard, "", 0))
	if err = schemaEnsurer.EnsureSchema(); err != nil {
		return err
	}

	return nil
}

func (me *DeliveryStore) Store(delivery *amqp.Delivery) (err error) {
	var (
		u4 *uuid.UUID
	)

	if u4, err = uuid.NewV4(); err != nil {
		return err
	}

	_, err = me.insertStatement.Exec(
		u4.String(),
		delivery.ContentType,
		delivery.ContentEncoding,
		delivery.DeliveryMode,
		delivery.Priority,
		delivery.CorrelationId,
		delivery.ReplyTo,
		delivery.Expiration,
		delivery.Timestamp,
		delivery.Type,
		delivery.UserId,
		delivery.Exchange,
		delivery.RoutingKey,
		delivery.Body,
		time.Now())

	return err
}

func (me *DeliveryStore) Close() {
	me.db.Close()
}
<|endoftext|>


<commit_before>package drivers

import (
	"github.com/lxc/lxd/lxd/state"
)

var drivers = map[string]func() driver{
	"dir": func() driver { return &dir{} },
}

// Load returns a Driver for an existing low-level storage pool.
func Load(state *state.State, driverName string, name string, config map[string]string, volIDFunc func(volType VolumeType, volName string) (int64, error), commonRulesFunc func() map[string]func(string) error) (Driver, error) {
	// Locate the driver loader.
	driverFunc, ok := drivers[driverName]
	if !ok {
		return nil, ErrUnknownDriver
	}

	d := driverFunc()
	d.init(state, name, config, volIDFunc, commonRulesFunc)

	return d, nil
}

// Info represents information about a storage driver.
type Info struct {
	Name            string
	Version         string
	Usable          bool
	Remote          bool
	OptimizedImages bool
	PreservesInodes bool
	VolumeTypes     []VolumeType
}

// SupportedDrivers returns a list of supported storage drivers.
func SupportedDrivers() []Info {
	supportedDrivers := []Info{}

	for driverName := range drivers {
		driver, err := Load(nil, driverName, "", nil, nil, nil)
		if err != nil {
			continue
		}

		supportedDrivers = append(supportedDrivers, driver.Info())
	}

	return supportedDrivers
}
<commit_msg>lxd/storage/drivers/load: Updates loaders to support contextual loggers<commit_after>package drivers

import (
	"github.com/lxc/lxd/lxd/state"
	"github.com/lxc/lxd/shared/logger"
)

var drivers = map[string]func() driver{
	"dir": func() driver { return &dir{} },
}

// Load returns a Driver for an existing low-level storage pool.
func Load(state *state.State, driverName string, name string, config map[string]string, logger logger.Logger, volIDFunc func(volType VolumeType, volName string) (int64, error), commonRulesFunc func() map[string]func(string) error) (Driver, error) {
	// Locate the driver loader.
	driverFunc, ok := drivers[driverName]
	if !ok {
		return nil, ErrUnknownDriver
	}

	d := driverFunc()
	d.init(state, name, config, logger, volIDFunc, commonRulesFunc)

	return d, nil
}

// Info represents information about a storage driver.
type Info struct {
	Name            string
	Version         string
	Usable          bool
	Remote          bool
	OptimizedImages bool
	PreservesInodes bool
	VolumeTypes     []VolumeType
}

// SupportedDrivers returns a list of supported storage drivers.
func SupportedDrivers() []Info {
	supportedDrivers := []Info{}

	for driverName := range drivers {
		driver, err := Load(nil, driverName, "", nil, nil, nil, nil)
		if err != nil {
			continue
		}

		supportedDrivers = append(supportedDrivers, driver.Info())
	}

	return supportedDrivers
}
<|endoftext|>


<commit_before>package obj

import (
	"fmt"
	"reflect"

	"github.com/polydawn/go-xlate/obj/atlas"
	. "github.com/polydawn/go-xlate/tok"
)

type MarshalMachineStructAtlas struct {
	target interface{}
	atlas  atlas.Atlas // Populate on initialization.
	index  int         // Progress marker
	value  bool        // Progress marker
}

func NewMarshalMachineStructAtlas(atl atlas.Atlas) MarshalMachine {
	atl.Init()
	return &MarshalMachineStructAtlas{atlas: atl}
}

func (m *MarshalMachineStructAtlas) Reset(s *Suite, target interface{}) error {
	m.target = target
	m.index = -1
	m.value = false
	if !reflect.ValueOf(target).CanAddr() {
		return fmt.Errorf("error resetting MarshalMachineStructAtlas: target is not addressable")
	}
	return nil
}

func (m *MarshalMachineStructAtlas) Step(driver *MarshalDriver, s *Suite, tok *Token) (done bool, err error) {
	if m.index < 0 {
		if m.target == nil { // REVIEW p sure should have ptr cast and indirect
			*tok = nil
			m.index++
			return true, nil
		}
		*tok = Token_MapOpen
		m.index++
		return false, nil
	}
	nEntries := len(m.atlas.Fields)
	if m.index == nEntries {
		*tok = Token_MapClose
		m.index++
		return true, nil
	}
	if m.index > nEntries {
		return true, fmt.Errorf("invalid state: entire struct (%d fields) already consumed", nEntries)
	}

	entry := m.atlas.Fields[m.index]
	if m.value {
		valp := entry.Grab(m.target)
		m.index++
		m.value = false
		return false, driver.Recurse(tok, valp, s.pickMarshalMachine(valp))
	}
	*tok = &entry.Name
	m.value = true
	return false, nil
}
<commit_msg>Remove review/todo comment.<commit_after>package obj

import (
	"fmt"
	"reflect"

	"github.com/polydawn/go-xlate/obj/atlas"
	. "github.com/polydawn/go-xlate/tok"
)

type MarshalMachineStructAtlas struct {
	target interface{}
	atlas  atlas.Atlas // Populate on initialization.
	index  int         // Progress marker
	value  bool        // Progress marker
}

func NewMarshalMachineStructAtlas(atl atlas.Atlas) MarshalMachine {
	atl.Init()
	return &MarshalMachineStructAtlas{atlas: atl}
}

func (m *MarshalMachineStructAtlas) Reset(s *Suite, target interface{}) error {
	m.target = target
	m.index = -1
	m.value = false
	if !reflect.ValueOf(target).CanAddr() {
		return fmt.Errorf("error resetting MarshalMachineStructAtlas: target is not addressable")
	}
	return nil
}

func (m *MarshalMachineStructAtlas) Step(driver *MarshalDriver, s *Suite, tok *Token) (done bool, err error) {
	if m.index < 0 {
		if m.target == nil {
			*tok = nil
			m.index++
			return true, nil
		}
		*tok = Token_MapOpen
		m.index++
		return false, nil
	}
	nEntries := len(m.atlas.Fields)
	if m.index == nEntries {
		*tok = Token_MapClose
		m.index++
		return true, nil
	}
	if m.index > nEntries {
		return true, fmt.Errorf("invalid state: entire struct (%d fields) already consumed", nEntries)
	}

	entry := m.atlas.Fields[m.index]
	if m.value {
		valp := entry.Grab(m.target)
		m.index++
		m.value = false
		return false, driver.Recurse(tok, valp, s.pickMarshalMachine(valp))
	}
	*tok = &entry.Name
	m.value = true
	return false, nil
}
<|endoftext|>


<commit_before>package observable

import (
	"errors"
	"testing"
	"time"

	"github.com/raininfall/gorx/observer"
	"github.com/stretchr/testify/assert"
)

func TestObservableOf(t *testing.T) {
	assert := assert.New(t)

	oba := Of(1, 2, 3, errors.New("Bang"), 4, nil)
	obs := observer.New(0)
	oba.Subscribe(obs)

	values := []int{}
	for v := range obs.Out() {
		switch v := v.(type) {
		case error:
			assert.Exactly(errors.New("Bang"), v)
			continue
		default:
			values = append(values, v.(int))
		}
	}

	assert.Exactly([]int{1, 2, 3}, values)
}

func TestObservableOfUnsubscribe(t *testing.T) {
	assert := assert.New(t)

	oba := Of(1, 2, 3, 4, 5, errors.New("Bang"), 6, nil)
	obs := observer.New(0)
	oba.Subscribe(obs)

	values := []int{}
	i := 0
	for v := range obs.Out() {
		switch v := v.(type) {
		case error:
			assert.Exactly(errors.New("Bang"), v)
			continue
		default:
			values = append(values, v.(int))
		}
		i++
		if i == 3 {
			<-time.After(50 * time.Millisecond) /*Give it some time to fill next value*/
			obs.Unsubscribe()
		}
	}

	assert.Exactly([]int{1, 2, 3}, values)
}
<commit_msg>fix of test of unsubscribe<commit_after>package observable

import (
	"errors"
	"testing"

	"github.com/raininfall/gorx/observer"
	"github.com/stretchr/testify/assert"
)

func TestObservableOf(t *testing.T) {
	assert := assert.New(t)

	oba := Of(1, 2, 3, errors.New("Bang"), 4, nil)
	obs := observer.New(0)
	oba.Subscribe(obs)

	values := []int{}
	for v := range obs.Out() {
		switch v := v.(type) {
		case error:
			assert.Exactly(errors.New("Bang"), v)
			continue
		default:
			values = append(values, v.(int))
		}
	}

	assert.Exactly([]int{1, 2, 3}, values)
}

func TestObservableOfUnsubscribe(t *testing.T) {
	assert := assert.New(t)

	oba := Of(1, 2, 3, 4, 5, errors.New("Bang"), 6, nil)
	obs := observer.New(0)
	oba.Subscribe(obs)
	err := errors.New("Not")

	values := []int{}
	i := 0
	for v := range obs.Out() {
		switch v := v.(type) {
		case error:
			assert.Exactly(errors.New("Bang"), v)
			continue
		default:
			values = append(values, v.(int))
		}
		i++
		if i == 3 {
			obs.Unsubscribe()
		}
	}

	assert.Exactly(errors.New("Not"), err)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/mgutz/ansi"
	"golang.org/x/tools/cover"
)

const usageMessage = `go-carpet - show coverage for Go source files

usage: go-carpet [options] [dirs]`

func getDirsWithTests(roots ...string) []string {
	if len(roots) == 0 {
		roots = []string{"."}
	}

	dirs := map[string]struct{}{}
	for _, root := range roots {
		filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
			if strings.HasSuffix(path, "_test.go") {
				dirs[filepath.Dir(path)] = struct{}{}
			}
			return nil
		})
	}

	result := make([]string, 0, len(dirs))
	for dir := range dirs {
		result = append(result, "./"+dir)
	}
	return result
}

func readFile(fileName string) (result []byte, err error) {
	fileReader, err := os.Open(fileName)
	if err != nil {
		return result, err
	}
	defer fileReader.Close()

	result, err = ioutil.ReadAll(fileReader)
	return result, err
}

// isStringInSlice - one of the elements of the array contained in the string
func isSliceInString(src string, slice []string) bool {
	for _, dst := range slice {
		if strings.Contains(src, dst) {
			return true
		}
	}
	return false
}

func getShadeOfGreen(normCover float64) string {
	/*
		Get all colors for 255-colors terminal:
			gommand 'for i := 0; i < 256; i++ {fmt.Println(i, ansi.ColorCode(strconv.Itoa(i)) + "String" + ansi.ColorCode("reset"))}'
	*/
	var tenShadesOfGreen = []string{
		"29",
		"30",
		"34",
		"36",
		"40",
		"42",
		"46",
		"48",
		"50",
		"51",
	}
	if normCover < 0 {
		normCover = 0
	}
	if normCover > 1 {
		normCover = 1
	}
	index := int((normCover - 0.00001) * float64(len(tenShadesOfGreen)))
	return tenShadesOfGreen[index]
}

func getCoverForDir(path string, coverFileName string, filesFilter []string, colors256 bool) (result []byte, err error) {
	osExec := exec.Command("go", "test", "-coverprofile="+coverFileName, "-covermode=count", path)
	osExec.Stderr = os.Stderr
	err = osExec.Run()
	if err != nil {
		return result, err
	}

	coverProfile, err := cover.ParseProfiles(coverFileName)
	if err != nil {
		return result, err
	}

	for _, fileProfile := range coverProfile {
		fileName := ""
		if strings.HasPrefix(fileProfile.FileName, "_") {
			// absolute path
			fileName = strings.TrimLeft(fileProfile.FileName, "_")
		} else {
			// file in GOPATH
			fileName = os.Getenv("GOPATH") + "/src/" + fileProfile.FileName
		}
		if _, err := os.Stat(fileName); os.IsNotExist(err) {
			fmt.Printf("File '%s' is not exists\n", fileName)
			continue
		}

		if len(filesFilter) > 0 && !isSliceInString(fileName, filesFilter) {
			continue
		}

		fileBytes, err := readFile(fileName)
		if err != nil {
			return result, err
		}

		fileNameDisplay := fileProfile.FileName

		result = append(result,
			[]byte(ansi.ColorCode("yellow")+
				fileNameDisplay+ansi.ColorCode("reset")+"\n"+
				ansi.ColorCode("black+h")+
				strings.Repeat("~", len(fileNameDisplay))+
				ansi.ColorCode("reset")+"\n",
			)...,
		)

		boundaries := fileProfile.Boundaries(fileBytes)
		curOffset := 0
		for _, boundary := range boundaries {
			if boundary.Offset > curOffset {
				result = append(result, fileBytes[curOffset:boundary.Offset]...)
			}
			switch {
			case boundary.Start && boundary.Count > 0:
				coverColor := ansi.ColorCode("green")
				if colors256 {
					coverColor = ansi.ColorCode(getShadeOfGreen(boundary.Norm))
				}
				result = append(result, []byte(coverColor)...)
			case boundary.Start && boundary.Count == 0:
				result = append(result, []byte(ansi.ColorCode("red"))...)
			case !boundary.Start:
				result = append(result, []byte(ansi.ColorCode("reset"))...)
			}

			curOffset = boundary.Offset
		}
		if curOffset < len(fileBytes) {
			result = append(result, fileBytes[curOffset:len(fileBytes)]...)
		}
		result = append(result, []byte("\n")...)
	}

	return result, err
}

func getTempFileName() string {
	tmpFile, err := ioutil.TempFile(".", "go-carpet-coverage-out-")
	if err != nil {
		log.Fatal(err)
	}
	tmpFile.Close()

	return tmpFile.Name()
}

func main() {
	filesFilter, colors256 := "", false
	flag.StringVar(&filesFilter, "file", "", "comma separated list of files to test (defualt: all)")
	flag.BoolVar(&colors256, "256colors", false, "use more colors on 256-color terminal")
	flag.Usage = func() {
		fmt.Println(usageMessage)
		flag.PrintDefaults()
		os.Exit(0)
	}
	flag.Parse()
	testDirs := flag.Args()

	coverFileName := getTempFileName()
	defer os.RemoveAll(coverFileName)
	stdOut := getColorWriter()

	if len(testDirs) > 0 {
		testDirs = getDirsWithTests(testDirs...)
	} else {
		testDirs = getDirsWithTests(".")
	}
	for _, path := range testDirs {
		coverInBytes, err := getCoverForDir(path, coverFileName, strings.Split(filesFilter, ","), colors256)
		if err != nil {
			log.Print(err)
		}
		stdOut.Write(coverInBytes)
	}
}
<commit_msg>Updated docs<commit_after>/*
go-carpet - show test coverage for Go source files

Install/update:

	go get -u github.com/msoap/go-carpet
	ln -s $GOPATH/bin/go-carpet ~/bin/go-carpet

Usage:

	go-carpet [-options] [paths]
	options:
		-256colors - use more colors on 256-color terminal
		-file string - comma separated list of files to test (defualt: all)

Source: https://github.com/msoap/go-carpet

*/
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/mgutz/ansi"
	"golang.org/x/tools/cover"
)

const usageMessage = `go-carpet - show test coverage for Go source files

usage: go-carpet [options] [paths]`

func getDirsWithTests(roots ...string) []string {
	if len(roots) == 0 {
		roots = []string{"."}
	}

	dirs := map[string]struct{}{}
	for _, root := range roots {
		filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
			if strings.HasSuffix(path, "_test.go") {
				dirs[filepath.Dir(path)] = struct{}{}
			}
			return nil
		})
	}

	result := make([]string, 0, len(dirs))
	for dir := range dirs {
		result = append(result, "./"+dir)
	}
	return result
}

func readFile(fileName string) (result []byte, err error) {
	fileReader, err := os.Open(fileName)
	if err != nil {
		return result, err
	}
	defer fileReader.Close()

	result, err = ioutil.ReadAll(fileReader)
	return result, err
}

// isStringInSlice - one of the elements of the array contained in the string
func isSliceInString(src string, slice []string) bool {
	for _, dst := range slice {
		if strings.Contains(src, dst) {
			return true
		}
	}
	return false
}

func getShadeOfGreen(normCover float64) string {
	/*
		Get all colors for 255-colors terminal:
			gommand 'for i := 0; i < 256; i++ {fmt.Println(i, ansi.ColorCode(strconv.Itoa(i)) + "String" + ansi.ColorCode("reset"))}'
	*/
	var tenShadesOfGreen = []string{
		"29",
		"30",
		"34",
		"36",
		"40",
		"42",
		"46",
		"48",
		"50",
		"51",
	}
	if normCover < 0 {
		normCover = 0
	}
	if normCover > 1 {
		normCover = 1
	}
	index := int((normCover - 0.00001) * float64(len(tenShadesOfGreen)))
	return tenShadesOfGreen[index]
}

func getCoverForDir(path string, coverFileName string, filesFilter []string, colors256 bool) (result []byte, err error) {
	osExec := exec.Command("go", "test", "-coverprofile="+coverFileName, "-covermode=count", path)
	osExec.Stderr = os.Stderr
	err = osExec.Run()
	if err != nil {
		return result, err
	}

	coverProfile, err := cover.ParseProfiles(coverFileName)
	if err != nil {
		return result, err
	}

	for _, fileProfile := range coverProfile {
		fileName := ""
		if strings.HasPrefix(fileProfile.FileName, "_") {
			// absolute path
			fileName = strings.TrimLeft(fileProfile.FileName, "_")
		} else {
			// file in GOPATH
			fileName = os.Getenv("GOPATH") + "/src/" + fileProfile.FileName
		}
		if _, err := os.Stat(fileName); os.IsNotExist(err) {
			fmt.Printf("File '%s' is not exists\n", fileName)
			continue
		}

		if len(filesFilter) > 0 && !isSliceInString(fileName, filesFilter) {
			continue
		}

		fileBytes, err := readFile(fileName)
		if err != nil {
			return result, err
		}

		fileNameDisplay := fileProfile.FileName

		result = append(result,
			[]byte(ansi.ColorCode("yellow")+
				fileNameDisplay+ansi.ColorCode("reset")+"\n"+
				ansi.ColorCode("black+h")+
				strings.Repeat("~", len(fileNameDisplay))+
				ansi.ColorCode("reset")+"\n",
			)...,
		)

		boundaries := fileProfile.Boundaries(fileBytes)
		curOffset := 0
		for _, boundary := range boundaries {
			if boundary.Offset > curOffset {
				result = append(result, fileBytes[curOffset:boundary.Offset]...)
			}
			switch {
			case boundary.Start && boundary.Count > 0:
				coverColor := ansi.ColorCode("green")
				if colors256 {
					coverColor = ansi.ColorCode(getShadeOfGreen(boundary.Norm))
				}
				result = append(result, []byte(coverColor)...)
			case boundary.Start && boundary.Count == 0:
				result = append(result, []byte(ansi.ColorCode("red"))...)
			case !boundary.Start:
				result = append(result, []byte(ansi.ColorCode("reset"))...)
			}

			curOffset = boundary.Offset
		}
		if curOffset < len(fileBytes) {
			result = append(result, fileBytes[curOffset:len(fileBytes)]...)
		}
		result = append(result, []byte("\n")...)
	}

	return result, err
}

func getTempFileName() string {
	tmpFile, err := ioutil.TempFile(".", "go-carpet-coverage-out-")
	if err != nil {
		log.Fatal(err)
	}
	tmpFile.Close()

	return tmpFile.Name()
}

func main() {
	filesFilter, colors256 := "", false
	flag.StringVar(&filesFilter, "file", "", "comma separated list of files to test (defualt: all)")
	flag.BoolVar(&colors256, "256colors", false, "use more colors on 256-color terminal")
	flag.Usage = func() {
		fmt.Println(usageMessage)
		flag.PrintDefaults()
		os.Exit(0)
	}
	flag.Parse()
	testDirs := flag.Args()

	coverFileName := getTempFileName()
	defer os.RemoveAll(coverFileName)
	stdOut := getColorWriter()

	if len(testDirs) > 0 {
		testDirs = getDirsWithTests(testDirs...)
	} else {
		testDirs = getDirsWithTests(".")
	}
	for _, path := range testDirs {
		coverInBytes, err := getCoverForDir(path, coverFileName, strings.Split(filesFilter, ","), colors256)
		if err != nil {
			log.Print(err)
		}
		stdOut.Write(coverInBytes)
	}
}
<|endoftext|>