<commit_before>package dragoon

import (
	"fmt"
	"net/http"
	"os"
	"testing"
	"time"

	"github.com/osamingo/dragoon/identifier"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"golang.org/x/net/context"
	"google.golang.org/appengine"
	"google.golang.org/appengine/aetest"
	"google.golang.org/appengine/datastore"
	"gopkg.in/go-playground/validator.v9"
)

type Entity struct {
	ID          string    `datastore:"-" valid:"min=1,max=11"`
	Name        string    `datastore:"name" valid:"required"`
	Description string    `datastore:"description,omitempty,noindex" valid:"max=140"`
	CreatedAt   time.Time `datastore:"created_at"`
	UpdatedAt   time.Time `datastore:"updated_at"`
}

var (
	inst aetest.Instance
	s    *Spear
)

func (e *Entity) GetID() string {
	return e.ID
}

func (e *Entity) SetID(id string) {
	e.ID = id
}

func (e *Entity) SetCreatedAt(t time.Time) {
	if e.CreatedAt.IsZero() {
		e.CreatedAt = t
	}
}

func (e *Entity) SetUpdatedAt(t time.Time) {
	e.UpdatedAt = t
}

func TestMain(m *testing.M) {
	os.Exit(run(m))
}

func run(m *testing.M) int {

	var err error
	s, err = NewSpear("test-ns", "test-kind", true, identifier.DatastoreAllocate{}, validator.New())
	if err != nil {
		fmt.Fprint(os.Stderr, "failed to generate spear - error =", err.Error())
		os.Exit(1)
	}

	inst, err = aetest.NewInstance(&aetest.Options{
		AppID: "dragoon-test",
		StronglyConsistentDatastore: true,
	})
	if err != nil {
		fmt.Fprint(os.Stderr, "failed to generate test instance - error =", err.Error())
		os.Exit(1)
	}
	defer inst.Close()

	return m.Run()
}

func newTestContext() (context.Context, error) {
	req, err := inst.NewRequest(http.MethodGet, "/", nil)
	if err != nil {
		return nil, err
	}
	return appengine.NewContext(req), nil
}

func TestNewSpear(t *testing.T) {
	_, err := NewSpear("", "", false, identifier.DatastoreAllocate{}, validator.New())
	require.Error(t, err)
	s, err := NewSpear("+", "test", false, identifier.DatastoreAllocate{}, validator.New())
	require.Error(t, err)
	s, err = NewSpear("", "test", false, identifier.DatastoreAllocate{}, validator.New())
	require.NoError(t, err)
	assert.NotNil(t, s)
}

func TestSpear(t *testing.T) {

	c, err := newTestContext()
	require.NoError(t, err)

	src := &Entity{
		Name: "Single_1",
	}
	require.NoError(t, s.Put(c, src))
	require.EqualError(t, s.Save(c, src), ErrConflictEntity.Error())

	dst := &Entity{
		ID: src.ID,
	}
	require.NoError(t, s.Get(c, dst))
	assert.EqualValues(t, src, dst)

	require.NoError(t, s.Delete(c, dst))

	require.NoError(t, s.Save(c, src))
	require.NoError(t, s.Delete(c, dst))
}

func TestSpearMulti(t *testing.T) {

	c, err := newTestContext()
	require.NoError(t, err)

	src := []Identifier{
		&Entity{
			Name: "Multi_1",
		},
		&Entity{
			Name: "Multi_2",
		},
	}

	require.NoError(t, s.PutMulti(c, src))

	id1 := src[0].(Identifier).GetID()
	id2 := src[1].(Identifier).GetID()
	dst := []Identifier{
		&Entity{
			ID: id1,
		},
		&Entity{
			ID: id2,
		},
	}
	require.NoError(t, s.GetMulti(c, dst))
	assert.EqualValues(t, src[0], dst[0])
	assert.EqualValues(t, src[1], dst[1])

	require.NoError(t, s.DeleteMulti(c, dst))

	err = s.GetMulti(c, []Identifier{
		&Entity{
			ID: id1,
		},
		&Entity{
			ID: id2,
		},
	})
	require.EqualError(t, errors.Cause(err).(appengine.MultiError)[0], datastore.ErrNoSuchEntity.Error())
	require.EqualError(t, errors.Cause(err).(appengine.MultiError)[1], datastore.ErrNoSuchEntity.Error())
}

func TestIsNotFound(t *testing.T) {
	require.True(t, IsNotFound(datastore.ErrNoSuchEntity))
}

func TestFillID(t *testing.T) {

	c, err := newTestContext()
	require.NoError(t, err)

	ks := []*datastore.Key{
		nil,
		datastore.NewKey(c, "test", "test-id", 0, nil),
	}
	es := []Identifier{
		&Entity{},
		&Entity{},
	}
	FillID(ks, es)

	assert.Empty(t, es[0].GetID())
	assert.Equal(t, "test-id", es[1].GetID())
}

func TestAsMap(t *testing.T) {

	is := []Identifier{
		&Entity{
			ID: "item1",
		},
		&Entity{
			ID: "item2",
		},
	}

	m := AsMap(is)
	require.NotNil(t, m)

	assert.Equal(t, "item1", m["item1"].(*Entity).GetID())
	assert.Equal(t, "item2", m["item2"].(*Entity).GetID())
}
<commit_msg>Refactor TestMain func<commit_after>package dragoon

import (
	"fmt"
	"net/http"
	"os"
	"testing"
	"time"

	"github.com/osamingo/dragoon/identifier"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"golang.org/x/net/context"
	"google.golang.org/appengine"
	"google.golang.org/appengine/aetest"
	"google.golang.org/appengine/datastore"
	"gopkg.in/go-playground/validator.v9"
)

type Entity struct {
	ID          string    `datastore:"-" valid:"min=1,max=11"`
	Name        string    `datastore:"name" valid:"required"`
	Description string    `datastore:"description,omitempty,noindex" valid:"max=140"`
	CreatedAt   time.Time `datastore:"created_at"`
	UpdatedAt   time.Time `datastore:"updated_at"`
}

var (
	inst aetest.Instance
	s    *Spear
)

func (e *Entity) GetID() string {
	return e.ID
}

func (e *Entity) SetID(id string) {
	e.ID = id
}

func (e *Entity) SetCreatedAt(t time.Time) {
	if e.CreatedAt.IsZero() {
		e.CreatedAt = t
	}
}

func (e *Entity) SetUpdatedAt(t time.Time) {
	e.UpdatedAt = t
}

func TestMain(m *testing.M) {
	var e interface{} = &Entity{}
	if _, ok := e.(Identifier); !ok {
		fmt.Fprint(os.Stderr, "Identifier not implemented")
		os.Exit(1)
	}
	if _, ok := e.(CreateTimeStamper); !ok {
		fmt.Fprint(os.Stderr, "CreateTimeStamper not implemented")
		os.Exit(1)
	}
	if _, ok := e.(UpdateTimeStamper); !ok {
		fmt.Fprint(os.Stderr, "UpdateTimeStamper not implemented")
		os.Exit(1)
	}
	os.Exit(run(m))
}

func run(m *testing.M) int {

	var err error
	s, err = NewSpear("test-ns", "test-kind", true, identifier.DatastoreAllocate{}, validator.New())
	if err != nil {
		fmt.Fprint(os.Stderr, "failed to generate spear - error =", err.Error())
		os.Exit(1)
	}

	inst, err = aetest.NewInstance(&aetest.Options{
		AppID: "dragoon-test",
		StronglyConsistentDatastore: true,
	})
	if err != nil {
		fmt.Fprint(os.Stderr, "failed to generate test instance - error =", err.Error())
		os.Exit(1)
	}
	defer inst.Close()

	return m.Run()
}

func newTestContext() (context.Context, error) {
	req, err := inst.NewRequest(http.MethodGet, "/", nil)
	if err != nil {
		return nil, err
	}
	return appengine.NewContext(req), nil
}

func TestNewSpear(t *testing.T) {
	_, err := NewSpear("", "", false, identifier.DatastoreAllocate{}, validator.New())
	require.Error(t, err)
	s, err := NewSpear("+", "test", false, identifier.DatastoreAllocate{}, validator.New())
	require.Error(t, err)
	s, err = NewSpear("", "test", false, identifier.DatastoreAllocate{}, validator.New())
	require.NoError(t, err)
	assert.NotNil(t, s)
}

func TestSpear(t *testing.T) {

	c, err := newTestContext()
	require.NoError(t, err)

	src := &Entity{
		Name: "Single_1",
	}
	require.NoError(t, s.Put(c, src))
	require.EqualError(t, s.Save(c, src), ErrConflictEntity.Error())

	dst := &Entity{
		ID: src.ID,
	}
	require.NoError(t, s.Get(c, dst))
	assert.EqualValues(t, src, dst)

	require.NoError(t, s.Delete(c, dst))

	require.NoError(t, s.Save(c, src))
	require.NoError(t, s.Delete(c, dst))
}

func TestSpearMulti(t *testing.T) {

	c, err := newTestContext()
	require.NoError(t, err)

	src := []Identifier{
		&Entity{
			Name: "Multi_1",
		},
		&Entity{
			Name: "Multi_2",
		},
	}

	require.NoError(t, s.PutMulti(c, src))

	id1 := src[0].(Identifier).GetID()
	id2 := src[1].(Identifier).GetID()
	dst := []Identifier{
		&Entity{
			ID: id1,
		},
		&Entity{
			ID: id2,
		},
	}
	require.NoError(t, s.GetMulti(c, dst))
	assert.EqualValues(t, src[0], dst[0])
	assert.EqualValues(t, src[1], dst[1])

	require.NoError(t, s.DeleteMulti(c, dst))

	err = s.GetMulti(c, []Identifier{
		&Entity{
			ID: id1,
		},
		&Entity{
			ID: id2,
		},
	})
	require.EqualError(t, errors.Cause(err).(appengine.MultiError)[0], datastore.ErrNoSuchEntity.Error())
	require.EqualError(t, errors.Cause(err).(appengine.MultiError)[1], datastore.ErrNoSuchEntity.Error())
}

func TestIsNotFound(t *testing.T) {
	require.True(t, IsNotFound(datastore.ErrNoSuchEntity))
}

func TestFillID(t *testing.T) {

	c, err := newTestContext()
	require.NoError(t, err)

	ks := []*datastore.Key{
		nil,
		datastore.NewKey(c, "test", "test-id", 0, nil),
	}
	es := []Identifier{
		&Entity{},
		&Entity{},
	}
	FillID(ks, es)

	assert.Empty(t, es[0].GetID())
	assert.Equal(t, "test-id", es[1].GetID())
}

func TestAsMap(t *testing.T) {

	is := []Identifier{
		&Entity{
			ID: "item1",
		},
		&Entity{
			ID: "item2",
		},
	}

	m := AsMap(is)
	require.NotNil(t, m)

	assert.Equal(t, "item1", m["item1"].(*Entity).GetID())
	assert.Equal(t, "item2", m["item2"].(*Entity).GetID())
}
<|endoftext|>


<commit_before>package goship

import (
	"fmt"
	"path/filepath"

	"github.com/coreos/go-etcd/etcd"
)

// gitHubPaginationLimit is the default pagination limit for requests to the GitHub API that return multiple items.
const (
	gitHubPaginationLimit = 30
	pivotalCommentURL     = "https://www.pivotaltracker.com/services/v5/projects/%s/stories/%s/comments"
	gitHubAPITokenEnvVar  = "GITHUB_API_TOKEN"
)

// Host stores information on a host, such as URI and the latest commit revision.
type Host struct {
	URI             string
	LatestCommit    string
	GitHubCommitURL string
	GitHubDiffURL   string
	ShortCommitHash string
}

// Environment stores information about an individual environment, such as its name and whether it is deployable.
type Environment struct {
	Name               string
	Deploy             string
	RepoPath           string
	Hosts              []Host
	Branch             string
	Revision           string
	LatestGitHubCommit string
	IsDeployable       bool
}

// Project stores information about a GitHub project, such as its GitHub URL and repo name.
type Project struct {
	Name         string
	GitHubURL    string
	RepoName     string
	RepoOwner    string
	Environments []Environment
}

// gitHubCommitURL takes a project and returns the GitHub URL for its latest commit hash.
func (h *Host) LatestGitHubCommitURL(p Project) string {
	return fmt.Sprintf("%s/commit/%s", p.GitHubURL, h.LatestCommit)
}

// gitHubDiffURL takes a project and an environment and returns the GitHub diff URL
// for the latest commit on the host compared to the latest commit on GitHub.
func (h *Host) LatestGitHubDiffURL(p Project, e Environment) string {
	var s string
	if h.LatestCommit != e.LatestGitHubCommit {
		s = fmt.Sprintf("%s/compare/%s...%s", p.GitHubURL, h.LatestCommit, e.LatestGitHubCommit)
	}
	return s
}

// Deployable returns true if the latest commit for any of the hosts in an environment
// differs from the latest commit on GitHub, and false if all of the commits match.
func (e *Environment) Deployable() bool {
	for _, h := range e.Hosts {
		if e.LatestGitHubCommit != h.LatestCommit {
			return true
		}
	}
	return false
}

// ShortCommitHash returns a shortened version of the latest commit hash on a host.
func (h *Host) LatestShortCommitHash() string {
	if len(h.LatestCommit) == 0 {
		return ""
	}
	return h.LatestCommit[:7]
}

// config contains the information from config.yml.
type Config struct {
	Projects   []Project
	DeployUser string
	Notify     string
	Pivotal    *PivotalConfiguration
}

type PivotalConfiguration struct {
	Project string
	Token   string
}

type ETCDInterface interface {
	Get(string, bool, bool) (*etcd.Response, error)
}

// ProjectFromName takes a project name as a string and returns
// a Project by that name if it can find one.
func ProjectFromName(projects []Project, projectName string) (*Project, error) {
	for _, project := range projects {
		if project.Name == projectName {
			return &project, nil
		}
	}
	return nil, fmt.Errorf("No project found: %s", projectName)
}

// EnvironmentFromName takes an environment and project name as a string and returns
// an Environment by the given environment name under a project with the given
// project name if it can find one.
func EnvironmentFromName(projects []Project, projectName, environmentName string) (*Environment, error) {
	p, err := ProjectFromName(projects, projectName)
	if err != nil {
		return nil, err
	}
	for _, environment := range p.Environments {
		if environment.Name == environmentName {
			return &environment, nil
		}
	}
	return nil, fmt.Errorf("No environment found: %s", environmentName)
}

// connects to ETCD and returns the appropriate structs and strings.
func ParseETCD(client ETCDInterface) (c Config, err error) {
	baseInfo, err := client.Get("/", false, false)
	if err != nil {
		return c, err
	}
	deployUser := ""
	pivotalProject := ""
	pivitolToken := ""
	notify := ""
	for _, b := range baseInfo.Node.Nodes {
		switch filepath.Base(b.Key) {
		case "deploy_user":
			deployUser = b.Value
		case "pivotal_project":
			pivotalProject = b.Value
		case "pivotal_token":
			pivotalToken = b.Value
		case "notify":
			notify = b.Value
		}
	}

	allProjects := []Project{}
	//  Get Projects //
	projectNodes, err := client.Get("/projects", false, false)
	if err != nil {
		return c, err
	}
	for _, p := range projectNodes.Node.Nodes {
		name := filepath.Base(p.Key)
		projectNode, err := client.Get("/projects/"+name, false, false)
		if err != nil {
			return c, err
		}
		projectInfo := projectNode.Node.Nodes
		repoOwner := ""
		repoName := ""
		for _, k := range projectInfo {
			switch filepath.Base(k.Key) {
			case "repo_owner":
				repoOwner = filepath.Base(k.Value)
			case "repo_name":
				repoName = filepath.Base(k.Value)
			}
		}
		githubURL := fmt.Sprintf("https://github.com/%s/%s", repoOwner, repoName)
		proj := Project{Name: name, GitHubURL: githubURL, RepoName: repoName, RepoOwner: repoOwner}
		environments, err := client.Get("/projects/"+name+"/environments", false, false)
		if err != nil {
			return c, err
		}
		allEnvironments := []Environment{}
		for _, e := range environments.Node.Nodes {
			envSettings, err := client.Get("/projects/"+name+"/environments/"+filepath.Base(e.Key), false, false)
			if err != nil {
				return c, err
			}
			envName := filepath.Base(e.Key)
			revision := "head"
			branch := "master"
			deploy := ""
			repoPath := ""
			for _, n := range envSettings.Node.Nodes {
				switch filepath.Base(n.Key) {
				case "revision":
					revision = n.Value
				case "branch":
					branch = n.Value
				case "deploy":
					deploy = n.Value
				case "repo_path":
					repoPath = n.Value
				}
			}
			//  Get Hosts per Environment.
			hosts, err := client.Get("/projects/"+name+"/environments/"+envName+"/hosts", false, false)
			if err != nil {
				return c, err
			}
			allHosts := []Host{}
			for _, h := range hosts.Node.Nodes {
				host := Host{URI: filepath.Base(h.Key)}
				allHosts = append(allHosts, host)
			}
			env := Environment{Name: envName, Deploy: deploy, RepoPath: repoPath, Branch: branch, Revision: revision}
			env.Hosts = allHosts
			allEnvironments = append(allEnvironments, env)
		}
		if err != nil {
			fmt.Printf("Skipping Project: %s", err)
			continue
		}
		proj.Environments = allEnvironments
		allProjects = append(allProjects, proj)
	}
	piv := new(PivotalConfiguration)
	piv.Project = pivotalProject
	piv.Token = pivotalToken
	c.Projects = allProjects
	c.DeployUser = deployUser
	c.Notify = notify
	c.Pivotal = piv

	return c, err
}
<commit_msg>Fix type in token<commit_after>package goship

import (
	"fmt"
	"path/filepath"

	"github.com/coreos/go-etcd/etcd"
)

// gitHubPaginationLimit is the default pagination limit for requests to the GitHub API that return multiple items.
const (
	gitHubPaginationLimit = 30
	pivotalCommentURL     = "https://www.pivotaltracker.com/services/v5/projects/%s/stories/%s/comments"
	gitHubAPITokenEnvVar  = "GITHUB_API_TOKEN"
)

// Host stores information on a host, such as URI and the latest commit revision.
type Host struct {
	URI             string
	LatestCommit    string
	GitHubCommitURL string
	GitHubDiffURL   string
	ShortCommitHash string
}

// Environment stores information about an individual environment, such as its name and whether it is deployable.
type Environment struct {
	Name               string
	Deploy             string
	RepoPath           string
	Hosts              []Host
	Branch             string
	Revision           string
	LatestGitHubCommit string
	IsDeployable       bool
}

// Project stores information about a GitHub project, such as its GitHub URL and repo name.
type Project struct {
	Name         string
	GitHubURL    string
	RepoName     string
	RepoOwner    string
	Environments []Environment
}

// gitHubCommitURL takes a project and returns the GitHub URL for its latest commit hash.
func (h *Host) LatestGitHubCommitURL(p Project) string {
	return fmt.Sprintf("%s/commit/%s", p.GitHubURL, h.LatestCommit)
}

// gitHubDiffURL takes a project and an environment and returns the GitHub diff URL
// for the latest commit on the host compared to the latest commit on GitHub.
func (h *Host) LatestGitHubDiffURL(p Project, e Environment) string {
	var s string
	if h.LatestCommit != e.LatestGitHubCommit {
		s = fmt.Sprintf("%s/compare/%s...%s", p.GitHubURL, h.LatestCommit, e.LatestGitHubCommit)
	}
	return s
}

// Deployable returns true if the latest commit for any of the hosts in an environment
// differs from the latest commit on GitHub, and false if all of the commits match.
func (e *Environment) Deployable() bool {
	for _, h := range e.Hosts {
		if e.LatestGitHubCommit != h.LatestCommit {
			return true
		}
	}
	return false
}

// ShortCommitHash returns a shortened version of the latest commit hash on a host.
func (h *Host) LatestShortCommitHash() string {
	if len(h.LatestCommit) == 0 {
		return ""
	}
	return h.LatestCommit[:7]
}

// config contains the information from config.yml.
type Config struct {
	Projects   []Project
	DeployUser string
	Notify     string
	Pivotal    *PivotalConfiguration
}

type PivotalConfiguration struct {
	Project string
	Token   string
}

type ETCDInterface interface {
	Get(string, bool, bool) (*etcd.Response, error)
}

// ProjectFromName takes a project name as a string and returns
// a Project by that name if it can find one.
func ProjectFromName(projects []Project, projectName string) (*Project, error) {
	for _, project := range projects {
		if project.Name == projectName {
			return &project, nil
		}
	}
	return nil, fmt.Errorf("No project found: %s", projectName)
}

// EnvironmentFromName takes an environment and project name as a string and returns
// an Environment by the given environment name under a project with the given
// project name if it can find one.
func EnvironmentFromName(projects []Project, projectName, environmentName string) (*Environment, error) {
	p, err := ProjectFromName(projects, projectName)
	if err != nil {
		return nil, err
	}
	for _, environment := range p.Environments {
		if environment.Name == environmentName {
			return &environment, nil
		}
	}
	return nil, fmt.Errorf("No environment found: %s", environmentName)
}

// connects to ETCD and returns the appropriate structs and strings.
func ParseETCD(client ETCDInterface) (c Config, err error) {
	baseInfo, err := client.Get("/", false, false)
	if err != nil {
		return c, err
	}
	deployUser := ""
	pivotalProject := ""
	pivotalToken := ""
	notify := ""
	for _, b := range baseInfo.Node.Nodes {
		switch filepath.Base(b.Key) {
		case "deploy_user":
			deployUser = b.Value
		case "pivotal_project":
			pivotalProject = b.Value
		case "pivotal_token":
			pivotalToken = b.Value
		case "notify":
			notify = b.Value
		}
	}

	allProjects := []Project{}
	//  Get Projects //
	projectNodes, err := client.Get("/projects", false, false)
	if err != nil {
		return c, err
	}
	for _, p := range projectNodes.Node.Nodes {
		name := filepath.Base(p.Key)
		projectNode, err := client.Get("/projects/"+name, false, false)
		if err != nil {
			return c, err
		}
		projectInfo := projectNode.Node.Nodes
		repoOwner := ""
		repoName := ""
		for _, k := range projectInfo {
			switch filepath.Base(k.Key) {
			case "repo_owner":
				repoOwner = filepath.Base(k.Value)
			case "repo_name":
				repoName = filepath.Base(k.Value)
			}
		}
		githubURL := fmt.Sprintf("https://github.com/%s/%s", repoOwner, repoName)
		proj := Project{Name: name, GitHubURL: githubURL, RepoName: repoName, RepoOwner: repoOwner}
		environments, err := client.Get("/projects/"+name+"/environments", false, false)
		if err != nil {
			return c, err
		}
		allEnvironments := []Environment{}
		for _, e := range environments.Node.Nodes {
			envSettings, err := client.Get("/projects/"+name+"/environments/"+filepath.Base(e.Key), false, false)
			if err != nil {
				return c, err
			}
			envName := filepath.Base(e.Key)
			revision := "head"
			branch := "master"
			deploy := ""
			repoPath := ""
			for _, n := range envSettings.Node.Nodes {
				switch filepath.Base(n.Key) {
				case "revision":
					revision = n.Value
				case "branch":
					branch = n.Value
				case "deploy":
					deploy = n.Value
				case "repo_path":
					repoPath = n.Value
				}
			}
			//  Get Hosts per Environment.
			hosts, err := client.Get("/projects/"+name+"/environments/"+envName+"/hosts", false, false)
			if err != nil {
				return c, err
			}
			allHosts := []Host{}
			for _, h := range hosts.Node.Nodes {
				host := Host{URI: filepath.Base(h.Key)}
				allHosts = append(allHosts, host)
			}
			env := Environment{Name: envName, Deploy: deploy, RepoPath: repoPath, Branch: branch, Revision: revision}
			env.Hosts = allHosts
			allEnvironments = append(allEnvironments, env)
		}
		if err != nil {
			fmt.Printf("Skipping Project: %s", err)
			continue
		}
		proj.Environments = allEnvironments
		allProjects = append(allProjects, proj)
	}
	piv := new(PivotalConfiguration)
	piv.Project = pivotalProject
	piv.Token = pivotalToken
	c.Projects = allProjects
	c.DeployUser = deployUser
	c.Notify = notify
	c.Pivotal = piv

	return c, err
}
<|endoftext|>


<commit_before><commit_msg>Fix lint<commit_after><|endoftext|>


<commit_before>package main

import (
	"net/http"
	"time"

	"github.com/drone/drone/router"
	"github.com/drone/drone/router/middleware"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/gin-gonic/contrib/ginrus"
)

var serverCmd = cli.Command{
	Name:  "server",
	Usage: "starts the drone server daemon",
	Action: func(c *cli.Context) {
		if err := server(c); err != nil {
			logrus.Fatal(err)
		}
	},
	Flags: []cli.Flag{
		cli.BoolFlag{
			EnvVar: "DRONE_DEBUG",
			Name:   "debug",
			Usage:  "start the server in debug mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_BROKER_DEBUG",
			Name:   "broker-debug",
			Usage:  "start the broker in debug mode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_ADDR",
			Name:   "server-addr",
			Usage:  "server address",
			Value:  ":8000",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_CERT",
			Name:   "server-cert",
			Usage:  "server ssl cert",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_KEY",
			Name:   "server-key",
			Usage:  "server ssl key",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ADMIN",
			Name:   "admin",
			Usage:  "list of admin users",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ORGS",
			Name:   "orgs",
			Usage:  "list of approved organizations",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_OPEN",
			Name:   "open",
			Usage:  "open user registration",
		},
		cli.StringFlag{
			EnvVar: "DRONE_YAML",
			Name:   "yaml",
			Usage:  "build configuraton file name",
			Value:  ".drone.yml",
		},
		cli.DurationFlag{
			EnvVar: "DRONE_CACHE_TTY",
			Name:   "cache-tty",
			Usage:  "cache duration",
			Value:  time.Minute * 15,
		},
		cli.StringFlag{
			EnvVar: "DRONE_AGENT_SECRET,DRONE_SECRET",
			Name:   "agent-secret",
			Usage:  "agent secret passcode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DRIVER,DATABASE_DRIVER",
			Name:   "driver",
			Usage:  "database driver",
			Value:  "sqlite3",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DATASOURCE,DATABASE_CONFIG",
			Name:   "datasource",
			Usage:  "database driver configuration string",
			Value:  "drone.sqlite",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB",
			Name:   "github",
			Usage:  "github driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_URL",
			Name:   "github-server",
			Usage:  "github server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CONTEXT",
			Name:   "github-context",
			Usage:  "github status context",
			Value:  "continuous-integration/drone",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CLIENT",
			Name:   "github-client",
			Usage:  "github oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_SECRET",
			Name:   "github-secret",
			Usage:  "github oauth2 client secret",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_GITHUB_SCOPE",
			Name:   "github-scope",
			Usage:  "github oauth scope",
			Value: &cli.StringSlice{
				"repo",
				"repo:status",
				"user:email",
				"read:org",
			},
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_GIT_USERNAME",
			Name:   "github-git-username",
			Usage:  "github machine user username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_GIT_PASSWORD",
			Name:   "github-git-password",
			Usage:  "github machine user password",
		},
		cli.BoolTFlag{
			EnvVar: "DRONE_GITHUB_MERGE_REF",
			Name:   "github-merge-ref",
			Usage:  "github pull requests use merge ref",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_PRIVATE_MODE",
			Name:   "github-private-mode",
			Usage:  "github is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_SKIP_VERIFY",
			Name:   "github-skip-verify",
			Usage:  "github skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS",
			Name:   "gogs",
			Usage:  "gogs driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_URL",
			Name:   "gogs-server",
			Usage:  "gogs server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_USERNAME",
			Name:   "gogs-git-username",
			Usage:  "gogs service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_PASSWORD",
			Name:   "gogs-git-password",
			Usage:  "gogs service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_PRIVATE_MODE",
			Name:   "gogs-private-mode",
			Usage:  "gogs private mode enabled",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_SKIP_VERIFY",
			Name:   "gogs-skip-verify",
			Usage:  "gogs skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_BITBUCKET",
			Name:   "bitbucket",
			Usage:  "bitbucket driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_CLIENT",
			Name:   "bitbucket-client",
			Usage:  "bitbucket oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_SECRET",
			Name:   "bitbucket-secret",
			Usage:  "bitbucket oauth2 client secret",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB",
			Name:   "gitlab",
			Usage:  "gitlab driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_URL",
			Name:   "gitlab-server",
			Usage:  "gitlab server address",
			Value:  "https://gitlab.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_CLIENT",
			Name:   "gitlab-client",
			Usage:  "gitlab oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_SECRET",
			Name:   "gitlab-secret",
			Usage:  "gitlab oauth2 client secret",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_USERNAME",
			Name:   "gitlab-git-username",
			Usage:  "gitlab service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_PASSWORD",
			Name:   "gitlab-git-password",
			Usage:  "gitlab service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_SKIP_VERIFY",
			Name:   "gitlab-skip-verify",
			Usage:  "gitlab skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_PRIVATE_MODE",
			Name:   "gitlab-private-mode",
			Usage:  "gitlab is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH",
			Name:   "stash",
			Usage:  "stash driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_URL",
			Name:   "stash-server",
			Usage:  "stash server address",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_KEY",
			Name:   "stash-consumer-key",
			Usage:  "stash oauth1 consumer key",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_RSA",
			Name:   "stash-consumer-rsa",
			Usage:  "stash oauth1 private key file",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_USERNAME",
			Name:   "stash-git-username",
			Usage:  "stash service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_PASSWORD",
			Name:   "stash-git-password",
			Usage:  "stash service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH_SKIP_VERIFY",
			Name:   "stash-skip-verify",
			Usage:  "stash skip ssl verification",
		},
	},
}

func server(c *cli.Context) error {

	// debug level if requested by user
	if c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	} else {
		logrus.SetLevel(logrus.WarnLevel)
	}

	// setup the server and start the listener
	handler := router.Load(
		ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
		middleware.Version,
		middleware.Config(c),
		middleware.Cache(c),
		middleware.Store(c),
		middleware.Remote(c),
		middleware.Agents(c),
		middleware.Broker(c),
	)

	// start the server with tls enabled
	if c.String("server-cert") != "" {
		return http.ListenAndServeTLS(
			c.String("server-addr"),
			c.String("server-cert"),
			c.String("server-key"),
			handler,
		)
	}

	// start the server without tls enabled
	return http.ListenAndServe(
		c.String("server-addr"),
		handler,
	)
}
<commit_msg>Update server.go<commit_after>package main

import (
	"net/http"
	"time"

	"github.com/drone/drone/router"
	"github.com/drone/drone/router/middleware"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/gin-gonic/contrib/ginrus"
)

var serverCmd = cli.Command{
	Name:  "server",
	Usage: "starts the drone server daemon",
	Action: func(c *cli.Context) {
		if err := server(c); err != nil {
			logrus.Fatal(err)
		}
	},
	Flags: []cli.Flag{
		cli.BoolFlag{
			EnvVar: "DRONE_DEBUG",
			Name:   "debug",
			Usage:  "start the server in debug mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_BROKER_DEBUG",
			Name:   "broker-debug",
			Usage:  "start the broker in debug mode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_ADDR",
			Name:   "server-addr",
			Usage:  "server address",
			Value:  ":8000",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_CERT",
			Name:   "server-cert",
			Usage:  "server ssl cert",
		},
		cli.StringFlag{
			EnvVar: "DRONE_SERVER_KEY",
			Name:   "server-key",
			Usage:  "server ssl key",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ADMIN",
			Name:   "admin",
			Usage:  "list of admin users",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_ORGS",
			Name:   "orgs",
			Usage:  "list of approved organizations",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_OPEN",
			Name:   "open",
			Usage:  "open user registration",
		},
		cli.StringFlag{
			EnvVar: "DRONE_YAML",
			Name:   "yaml",
			Usage:  "build configuraton file name",
			Value:  ".drone.yml",
		},
		cli.DurationFlag{
			EnvVar: "DRONE_CACHE_TTL",
			Name:   "cache-ttl",
			Usage:  "cache duration",
			Value:  time.Minute * 15,
		},
		cli.StringFlag{
			EnvVar: "DRONE_AGENT_SECRET,DRONE_SECRET",
			Name:   "agent-secret",
			Usage:  "agent secret passcode",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DRIVER,DATABASE_DRIVER",
			Name:   "driver",
			Usage:  "database driver",
			Value:  "sqlite3",
		},
		cli.StringFlag{
			EnvVar: "DRONE_DATABASE_DATASOURCE,DATABASE_CONFIG",
			Name:   "datasource",
			Usage:  "database driver configuration string",
			Value:  "drone.sqlite",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB",
			Name:   "github",
			Usage:  "github driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_URL",
			Name:   "github-server",
			Usage:  "github server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CONTEXT",
			Name:   "github-context",
			Usage:  "github status context",
			Value:  "continuous-integration/drone",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_CLIENT",
			Name:   "github-client",
			Usage:  "github oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_SECRET",
			Name:   "github-secret",
			Usage:  "github oauth2 client secret",
		},
		cli.StringSliceFlag{
			EnvVar: "DRONE_GITHUB_SCOPE",
			Name:   "github-scope",
			Usage:  "github oauth scope",
			Value: &cli.StringSlice{
				"repo",
				"repo:status",
				"user:email",
				"read:org",
			},
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_GIT_USERNAME",
			Name:   "github-git-username",
			Usage:  "github machine user username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITHUB_GIT_PASSWORD",
			Name:   "github-git-password",
			Usage:  "github machine user password",
		},
		cli.BoolTFlag{
			EnvVar: "DRONE_GITHUB_MERGE_REF",
			Name:   "github-merge-ref",
			Usage:  "github pull requests use merge ref",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_PRIVATE_MODE",
			Name:   "github-private-mode",
			Usage:  "github is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITHUB_SKIP_VERIFY",
			Name:   "github-skip-verify",
			Usage:  "github skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS",
			Name:   "gogs",
			Usage:  "gogs driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_URL",
			Name:   "gogs-server",
			Usage:  "gogs server address",
			Value:  "https://github.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_USERNAME",
			Name:   "gogs-git-username",
			Usage:  "gogs service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GOGS_GIT_PASSWORD",
			Name:   "gogs-git-password",
			Usage:  "gogs service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_PRIVATE_MODE",
			Name:   "gogs-private-mode",
			Usage:  "gogs private mode enabled",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GOGS_SKIP_VERIFY",
			Name:   "gogs-skip-verify",
			Usage:  "gogs skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_BITBUCKET",
			Name:   "bitbucket",
			Usage:  "bitbucket driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_CLIENT",
			Name:   "bitbucket-client",
			Usage:  "bitbucket oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_BITBUCKET_SECRET",
			Name:   "bitbucket-secret",
			Usage:  "bitbucket oauth2 client secret",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB",
			Name:   "gitlab",
			Usage:  "gitlab driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_URL",
			Name:   "gitlab-server",
			Usage:  "gitlab server address",
			Value:  "https://gitlab.com",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_CLIENT",
			Name:   "gitlab-client",
			Usage:  "gitlab oauth2 client id",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_SECRET",
			Name:   "gitlab-secret",
			Usage:  "gitlab oauth2 client secret",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_USERNAME",
			Name:   "gitlab-git-username",
			Usage:  "gitlab service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_GITLAB_GIT_PASSWORD",
			Name:   "gitlab-git-password",
			Usage:  "gitlab service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_SKIP_VERIFY",
			Name:   "gitlab-skip-verify",
			Usage:  "gitlab skip ssl verification",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_GITLAB_PRIVATE_MODE",
			Name:   "gitlab-private-mode",
			Usage:  "gitlab is running in private mode",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH",
			Name:   "stash",
			Usage:  "stash driver is enabled",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_URL",
			Name:   "stash-server",
			Usage:  "stash server address",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_KEY",
			Name:   "stash-consumer-key",
			Usage:  "stash oauth1 consumer key",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_CONSUMER_RSA",
			Name:   "stash-consumer-rsa",
			Usage:  "stash oauth1 private key file",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_USERNAME",
			Name:   "stash-git-username",
			Usage:  "stash service account username",
		},
		cli.StringFlag{
			EnvVar: "DRONE_STASH_GIT_PASSWORD",
			Name:   "stash-git-password",
			Usage:  "stash service account password",
		},
		cli.BoolFlag{
			EnvVar: "DRONE_STASH_SKIP_VERIFY",
			Name:   "stash-skip-verify",
			Usage:  "stash skip ssl verification",
		},
	},
}

func server(c *cli.Context) error {

	// debug level if requested by user
	if c.Bool("debug") {
		logrus.SetLevel(logrus.DebugLevel)
	} else {
		logrus.SetLevel(logrus.WarnLevel)
	}

	// setup the server and start the listener
	handler := router.Load(
		ginrus.Ginrus(logrus.StandardLogger(), time.RFC3339, true),
		middleware.Version,
		middleware.Config(c),
		middleware.Cache(c),
		middleware.Store(c),
		middleware.Remote(c),
		middleware.Agents(c),
		middleware.Broker(c),
	)

	// start the server with tls enabled
	if c.String("server-cert") != "" {
		return http.ListenAndServeTLS(
			c.String("server-addr"),
			c.String("server-cert"),
			c.String("server-key"),
			handler,
		)
	}

	// start the server without tls enabled
	return http.ListenAndServe(
		c.String("server-addr"),
		handler,
	)
}
<|endoftext|>


<commit_before>package drum

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"
)

// DecodeFile decodes the drum machine file found at the provided path
// and returns a pointer to a parsed pattern which is the entry point to the
// rest of the data.
func DecodeFile(path string) (*Pattern, error) {
	// fileContents, err := ioutil.ReadFile(path)
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	r := io.Reader(file)

	// decode
	p := &Pattern{}
	*p, err = parseSpliceToPattern(r)
	if err != nil {
		fmt.Println("Error parseSpliceToPattern: ", err)
	}
	fmt.Println(p)

	return p, nil
}

// parse the given `.splice` files and store
// relevant information in the struct
func parseSpliceToPattern(r io.Reader) (Pattern, error) {

	newTrack := &Pattern{}

	// Decode SPLICE from header to ensure correct file type
	var spliceHeader [6]byte // 6
	err := binary.Read(r, binary.BigEndian, &spliceHeader)
	if err != nil {
		return *newTrack, errors.New("unable to decode splice header: " + err.Error())
	}

	// Decode trackSize from pattern Header
	var trackSize int64 // 8
	err = binary.Read(r, binary.BigEndian, &trackSize)
	if err != nil {
		return *newTrack, errors.New("unable to decode trackSize: " + err.Error())
	}

	// Decode versionString and store in struct
	var versionString [32]byte // 32
	err = binary.Read(r, binary.BigEndian, &versionString)
	if err != nil {
		return *newTrack, errors.New("unable to decode versionString: " + err.Error())
	}
	newTrack.versionString = versionString

	// Decode tempo and store in struct
	// NOTE: tempo is little Endian
	var tempo float32 // 4
	err = binary.Read(r, binary.LittleEndian, &tempo)
	if err != nil {
		return *newTrack, errors.New("unable to decode tempo: " + err.Error())
	}
	newTrack.tempo = tempo

	// LimitedReader needs to take `-36` = versionString(32) + tempo(4)
	// into account since we've already read in versionString and tempo
	lr := io.LimitReader(r, trackSize-36)
	for {
		// decode instrument information from the remaining information
		done, err := readInstrumentsFromTrack(lr, newTrack)
		if done {
			break
		} else if err != nil {
			return *newTrack, err
		}
	}

	return *newTrack, nil
}

func readInstrumentsFromTrack(lr io.Reader, newTrack *Pattern) (bool, error) {
	curInstrument := Instrument{}

	// Decode instrumentID (unique id) of instrument and store in Instrument struct
	var instrumentID uint8
	err := binary.Read(lr, binary.BigEndian, &instrumentID)
	if err == io.EOF {
		// we've read all the information
		return true, nil
	} else if err != nil {
		return false, errors.New("unable to decode instrumentID: " + err.Error())
	}
	curInstrument.instrumentID = instrumentID

	// Decode namLen (byte size of the human readable name) of instrument name
	var nameLen int32
	err = binary.Read(lr, binary.BigEndian, &nameLen)
	if err != nil {
		return false, errors.New("unable to decode instrument nameLen: " + err.Error())
	}

	// Decode human readable name of instrument and store in Instrument struct
	nameBuf := make([]byte, nameLen)
	err = binary.Read(lr, binary.LittleEndian, &nameBuf)
	if err != nil {
		return false, errors.New("unable to decode instrument nameBuf: " + err.Error())
	}
	curInstrument.instrumentName = nameBuf

	// steps were stored on HW as bytes but,
	// we can store them as bools instead since we're only concerned with binary state
	var stepArr [numSteps]byte
	err = binary.Read(lr, binary.LittleEndian, &stepArr)
	if err != nil {
		return false, errors.New("unable to decode instrument steps: " + err.Error())
	}

	// convert from bytes to bool and store in Instrument struct
	for i := range stepArr {
		if stepArr[i] == 0x0001 {
			curInstrument.steps[i] = true
		} else {
			curInstrument.steps[i] = false
		}
	}

	newTrack.instruments = append(newTrack.instruments, curInstrument)
	return false, nil
}
<commit_msg>minor change in decoding bytes to bool<commit_after>package drum

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"
)

// DecodeFile decodes the drum machine file found at the provided path
// and returns a pointer to a parsed pattern which is the entry point to the
// rest of the data.
func DecodeFile(path string) (*Pattern, error) {
	// fileContents, err := ioutil.ReadFile(path)
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	r := io.Reader(file)

	// decode
	p := &Pattern{}
	*p, err = parseSpliceToPattern(r)
	if err != nil {
		fmt.Println("Error parseSpliceToPattern: ", err)
	}
	fmt.Println(p)

	return p, nil
}

// parse the given `.splice` files and store
// relevant information in the struct
func parseSpliceToPattern(r io.Reader) (Pattern, error) {

	newTrack := &Pattern{}

	// Decode SPLICE from header to ensure correct file type
	var spliceHeader [6]byte // 6
	err := binary.Read(r, binary.BigEndian, &spliceHeader)
	if err != nil {
		return *newTrack, errors.New("unable to decode splice header: " + err.Error())
	}

	// Decode trackSize from pattern Header
	var trackSize int64 // 8
	err = binary.Read(r, binary.BigEndian, &trackSize)
	if err != nil {
		return *newTrack, errors.New("unable to decode trackSize: " + err.Error())
	}

	// Decode versionString and store in struct
	var versionString [32]byte // 32
	err = binary.Read(r, binary.BigEndian, &versionString)
	if err != nil {
		return *newTrack, errors.New("unable to decode versionString: " + err.Error())
	}
	newTrack.versionString = versionString

	// Decode tempo and store in struct
	// NOTE: tempo is little Endian
	var tempo float32 // 4
	err = binary.Read(r, binary.LittleEndian, &tempo)
	if err != nil {
		return *newTrack, errors.New("unable to decode tempo: " + err.Error())
	}
	newTrack.tempo = tempo

	// LimitedReader needs to take `-36` = versionString(32) + tempo(4)
	// into account since we've already read in versionString and tempo
	lr := io.LimitReader(r, trackSize-36)
	for {
		// decode instrument information from the remaining information
		done, err := readInstrumentsFromTrack(lr, newTrack)
		if done {
			break
		} else if err != nil {
			return *newTrack, err
		}
	}

	return *newTrack, nil
}

func readInstrumentsFromTrack(lr io.Reader, newTrack *Pattern) (bool, error) {
	curInstrument := Instrument{}

	// Decode instrumentID (unique id) of instrument and store in Instrument struct
	var instrumentID uint8
	err := binary.Read(lr, binary.BigEndian, &instrumentID)
	if err == io.EOF {
		// we've read all the information
		return true, nil
	} else if err != nil {
		return false, errors.New("unable to decode instrumentID: " + err.Error())
	}
	curInstrument.instrumentID = instrumentID

	// Decode namLen (byte size of the human readable name) of instrument name
	var nameLen int32
	err = binary.Read(lr, binary.BigEndian, &nameLen)
	if err != nil {
		return false, errors.New("unable to decode instrument nameLen: " + err.Error())
	}

	// Decode human readable name of instrument and store in Instrument struct
	nameBuf := make([]byte, nameLen)
	err = binary.Read(lr, binary.LittleEndian, &nameBuf)
	if err != nil {
		return false, errors.New("unable to decode instrument nameBuf: " + err.Error())
	}
	curInstrument.instrumentName = nameBuf

	// steps were stored on HW as bytes but,
	// we can store them as bools instead since we're only concerned with binary state
	var stepArr [numSteps]byte
	err = binary.Read(lr, binary.LittleEndian, &stepArr)
	if err != nil {
		return false, errors.New("unable to decode instrument steps: " + err.Error())
	}

	// convert from bytes to bool and store in Instrument struct
	for i := range stepArr {
		if stepArr[i] == 0x01 {
			curInstrument.steps[i] = true
		} else {
			curInstrument.steps[i] = false
		}
	}

	newTrack.instruments = append(newTrack.instruments, curInstrument)
	return false, nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	log "github.com/Sirupsen/logrus"
	sdk "github.com/dysolution/espsdk"
)

type Serializable interface {
	Marshal() ([]byte, error)
}

// A Bullet represents a single HTTP request that performs an operation
// against a single API endpoint. Each Bomb can contain one or multiple
// Bullets.
type Bullet struct {
	client  *sdk.Client
	Name    string         `json:"name"`
	Method  string         `json:"method"`
	URL     string         `json:"url"`
	Payload sdk.RESTObject `json:"payload,omitempty"`
}

// Deploy sets the Bullet in motion.
func (b *Bullet) Deploy() (sdk.DeserializedObject, error) {
	switch b.Method {
	case "GET", "get":
		return b.client.Get(b.URL), nil
	case "POST", "post":
		return b.client.Create(b.Payload), nil
	case "PUT", "put":
		return b.client.Update(b.Payload), nil
	case "DELETE", "delete":
		return b.client.DeleteFromObject(b.Payload), nil
	}
	return sdk.DeserializedObject{}, errors.New("undefined method")
}

func (b *Bullet) String() string {
	out, err := json.MarshalIndent(b, "", "  ")
	check(err)
	return fmt.Sprintf("%s", out)
}

// A Bomb is a collection of Bullets. It represents a list of tasks that
// compose a workflow.
//
// For example, a common workflow would be:
//   1. list all batches
//   2. get the metadata for a batch
//   3. upload a contribution to the batch
type Bomb struct {
	Name      string    `json:"name"`
	Bullets   []Bullet  `json:"bullets"`
	StartTime time.Time `json:"-"`
}

// Drop iterates through the Bullets within a bomb, fires all of them, and
// returns a summary of the results.
func Drop(bomb Bomb) []sdk.DeserializedObject {
	var summary []sdk.DeserializedObject
	for _, bullet := range bomb.Bullets {
		obj, _ := bullet.Deploy()
		summary = append(summary, obj)
	}
	return summary
}

// A Raid is a collection of bombs capable of reporting summary statistics.
type Raid struct {
	StartTime time.Time `json:"-"`
	Bombs     []Bomb    `json:"bombs"`
}

// Conduct iterates through the Bombs in a Raid's Payload, dropping each of
// them, and then returns a summary of the results.
func (r *Raid) Conduct() []byte {
	var raidSummary []byte
	for _, bomb := range r.Bombs {
		response, err := json.MarshalIndent(Drop(bomb), "", "    ")
		check(err)
		log.Debugf("%s", response)
		raidSummary = append(raidSummary, response...)
	}
	return raidSummary
}

// Duration reports how much time has elapsed since the start of the Raid.
func (r *Raid) Duration() time.Duration {
	return time.Now().Sub(r.StartTime)
}

func (r *Raid) String() string {
	out, err := json.MarshalIndent(r, "", "  ")
	check(err)
	return string(out)
}

// NewRaid initializes and returns a Raid, . It should be used in lieu of Raid literals.
func NewRaid(bombs ...Bomb) Raid {
	var payload []Bomb
	for _, bomb := range bombs {
		payload = append(payload, bomb)
	}
	return Raid{time.Now(), payload}
}

type SimpleBullet struct {
	Name string `json:"name"`
}

type SimpleBomb struct {
	Name    string         `json:"name"`
	Bullets []SimpleBullet `json:"bullets"`
}

type SimpleRaid struct {
	StartTime time.Time    `json:"start_time"`
	Bombs     []SimpleBomb `json:"bombs"`
}
<commit_msg>add logging<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	log "github.com/Sirupsen/logrus"
	sdk "github.com/dysolution/espsdk"
)

type Serializable interface {
	Marshal() ([]byte, error)
}

// A Bullet represents a single HTTP request that performs an operation
// against a single API endpoint. Each Bomb can contain one or multiple
// Bullets.
type Bullet struct {
	client  *sdk.Client
	Name    string         `json:"name"`
	Method  string         `json:"method"`
	URL     string         `json:"url"`
	Payload sdk.RESTObject `json:"payload,omitempty"`
}

// Deploy sets the Bullet in motion.
func (b *Bullet) Deploy() (sdk.DeserializedObject, error) {
	log.Debugf("%s was deployed", b.Name)
	switch b.Method {
	case "GET", "get":
		return b.client.Get(b.URL), nil
	case "POST", "post":
		return b.client.Create(b.Payload), nil
	case "PUT", "put":
		return b.client.Update(b.Payload), nil
	case "DELETE", "delete":
		return b.client.DeleteFromObject(b.Payload), nil
	}
	return sdk.DeserializedObject{}, errors.New("undefined method")
}

func (b *Bullet) String() string {
	out, err := json.MarshalIndent(b, "", "  ")
	check(err)
	return fmt.Sprintf("%s", out)
}

// A Bomb is a collection of Bullets. It represents a list of tasks that
// compose a workflow.
//
// For example, a common workflow would be:
//   1. list all batches
//   2. get the metadata for a batch
//   3. upload a contribution to the batch
type Bomb struct {
	Name      string    `json:"name"`
	Bullets   []Bullet  `json:"bullets"`
	StartTime time.Time `json:"-"`
}

// Drop iterates through the Bullets within a bomb, fires all of them, and
// returns a summary of the results.
func Drop(bomb Bomb) []sdk.DeserializedObject {
	var summary []sdk.DeserializedObject
	for _, bullet := range bomb.Bullets {
		obj, _ := bullet.Deploy()
		summary = append(summary, obj)
	}
	return summary
}

// A Raid is a collection of bombs capable of reporting summary statistics.
type Raid struct {
	StartTime time.Time `json:"-"`
	Bombs     []Bomb    `json:"bombs"`
}

// Conduct iterates through the Bombs in a Raid's Payload, dropping each of
// them, and then returns a summary of the results.
func (r *Raid) Conduct() []byte {
	var raidSummary []byte
	for _, bomb := range r.Bombs {
		response, err := json.MarshalIndent(Drop(bomb), "", "    ")
		check(err)
		log.Debugf("%s", response)
		raidSummary = append(raidSummary, response...)
	}
	return raidSummary
}

// Duration reports how much time has elapsed since the start of the Raid.
func (r *Raid) Duration() time.Duration {
	return time.Now().Sub(r.StartTime)
}

func (r *Raid) String() string {
	out, err := json.MarshalIndent(r, "", "  ")
	check(err)
	return string(out)
}

// NewRaid initializes and returns a Raid, . It should be used in lieu of Raid literals.
func NewRaid(bombs ...Bomb) Raid {
	var payload []Bomb
	for _, bomb := range bombs {
		payload = append(payload, bomb)
	}
	return Raid{time.Now(), payload}
}

type SimpleBullet struct {
	Name string `json:"name"`
}

type SimpleBomb struct {
	Name    string         `json:"name"`
	Bullets []SimpleBullet `json:"bullets"`
}

type SimpleRaid struct {
	StartTime time.Time    `json:"start_time"`
	Bombs     []SimpleBomb `json:"bombs"`
}
<|endoftext|>


<commit_before>package monico

import (
	"os"
	"time"
)

type Moniter struct {
	path        string
	lastModTime time.Time
}

func NewMoniter(path string) (*Moniter, error) {
	info, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	return &Moniter{
		path:        path,
		lastModTime: info.ModTime(),
	}, nil
}

func NewMoniterWithWD() (*Moniter, error) {
	wd, err := os.Getwd()
	if err != nil {
		return nil, err
	}
	return NewMoniter(wd)
}

func (m *Moniter) Modified() (bool, error) {
	info, err := os.Stat(m.path)
	if err != nil {
		return false, err
	}
	return !m.lastModTime.Equal(info.ModTime()), nil
}

func (m *Moniter) LastModTime() time.Time {
	return m.lastModTime
}

func (m *Moniter) UpdateModTime() error {
	info, err := os.Stat(m.path)
	if err != nil {
		return err
	}
	m.lastModTime = info.ModTime()
	return nil
}
<commit_msg>Remove LastModTime<commit_after>package monico

import (
	"os"
	"time"
)

type Moniter struct {
	path        string
	lastModTime time.Time
}

func NewMoniter(path string) (*Moniter, error) {
	info, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	return &Moniter{
		path:        path,
		lastModTime: info.ModTime(),
	}, nil
}

func NewMoniterWithWD() (*Moniter, error) {
	wd, err := os.Getwd()
	if err != nil {
		return nil, err
	}
	return NewMoniter(wd)
}

func (m *Moniter) Modified() (bool, error) {
	info, err := os.Stat(m.path)
	if err != nil {
		return false, err
	}
	return !m.lastModTime.Equal(info.ModTime()), nil
}

func (m *Moniter) UpdateModTime() error {
	info, err := os.Stat(m.path)
	if err != nil {
		return err
	}
	m.lastModTime = info.ModTime()
	return nil
}
<|endoftext|>


<commit_before>package std

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"

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

// Read reads a string from stdin or a file.
var Read = core.NewLazyFunction(
	core.NewSignature(
		nil, []core.OptionalArgument{core.NewOptionalArgument("file", core.Nil)}, "",
		nil, nil, "",
	),
	func(ts ...*core.Thunk) core.Value {
		v := ts[0].Eval()
		file := os.Stdin

		if s, ok := v.(core.StringType); ok {
			var err error
			file, err = os.Open(string(s))

			if err != nil {
				return core.OutputError(err.Error())
			}
		} else if _, ok := v.(core.NilType); !ok {
			return core.ValueError("file optional argument's value must be nil or a filename. Got %s.", core.DumpOrFail(v))
		}

		s, err := ioutil.ReadAll(file)

		if err != nil {
			return core.OutputError(err.Error())
		}

		return core.NewString(string(s))
	})

// Write writes string representation of arguments to stdout.
var Write = core.NewStrictFunction(
	core.NewSignature(
		nil, nil, "args",
		nil, []core.OptionalArgument{
			core.NewOptionalArgument("sep", core.NewString(" ")),
			core.NewOptionalArgument("end", core.NewString("\n")),
			core.NewOptionalArgument("file", core.NewNumber(1)),
			core.NewOptionalArgument("mode", core.NewNumber(0664)),
		}, "",
	),
	func(ts ...*core.Thunk) core.Value {
		v := ts[0].Eval()
		l, ok := v.(core.ListType)

		if !ok {
			return core.NotListError(v)
		}

		elems, err := l.ToValues()

		if err != nil {
			return err
		}

		ss := make([]string, 0, len(elems))

		for _, t := range elems {
			v := core.PApp(core.ToString, t).Eval()
			s, ok := v.(core.StringType)

			if !ok {
				return core.NotStringError(v)
			}

			ss = append(ss, string(s))
		}

		var options [2]string

		for i, t := range ts[1:3] {
			v := t.Eval()
			s, ok := v.(core.StringType)

			if !ok {
				return core.NotStringError(v)
			}

			options[i] = string(s)
		}

		file := os.Stdout

		fileArg := ts[3].Eval()
		if s, ok := fileArg.(core.StringType); ok {
			v := ts[4].Eval()
			mode, ok := v.(core.NumberType)
			if !ok {
				return core.NotNumberError(v)
			}

			var err error
			file, err = os.OpenFile(
				string(s),
				os.O_CREATE|os.O_TRUNC|os.O_WRONLY,
				os.FileMode(mode))

			if err != nil {
				return core.OutputError(err.Error())
			}
		} else if n, ok := fileArg.(core.NumberType); ok && n == 2 {
			file = os.Stderr
		} else if !(ok && n == 1) {
			return core.ValueError("file optional argument's value must be 1 or 2, or a string filename. Got %s.", core.DumpOrFail(fileArg))
		}

		fmt.Fprint(file, strings.Join(ss, options[0])+options[1])

		return core.NewOutput(core.Nil)
	})
<commit_msg>Expand lines<commit_after>package std

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"

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

// Read reads a string from stdin or a file.
var Read = core.NewLazyFunction(
	core.NewSignature(
		nil, []core.OptionalArgument{core.NewOptionalArgument("file", core.Nil)}, "",
		nil, nil, "",
	),
	func(ts ...*core.Thunk) core.Value {
		v := ts[0].Eval()
		file := os.Stdin

		if s, ok := v.(core.StringType); ok {
			var err error
			file, err = os.Open(string(s))

			if err != nil {
				return core.OutputError(err.Error())
			}
		} else if _, ok := v.(core.NilType); !ok {
			return core.ValueError(
				"file optional argument's value must be nil or a filename. Got %s.",
				core.DumpOrFail(v))
		}

		s, err := ioutil.ReadAll(file)

		if err != nil {
			return core.OutputError(err.Error())
		}

		return core.NewString(string(s))
	})

// Write writes string representation of arguments to stdout.
var Write = core.NewStrictFunction(
	core.NewSignature(
		nil, nil, "args",
		nil, []core.OptionalArgument{
			core.NewOptionalArgument("sep", core.NewString(" ")),
			core.NewOptionalArgument("end", core.NewString("\n")),
			core.NewOptionalArgument("file", core.NewNumber(1)),
			core.NewOptionalArgument("mode", core.NewNumber(0664)),
		}, "",
	),
	func(ts ...*core.Thunk) core.Value {
		v := ts[0].Eval()
		l, ok := v.(core.ListType)

		if !ok {
			return core.NotListError(v)
		}

		elems, err := l.ToValues()

		if err != nil {
			return err
		}

		ss := make([]string, 0, len(elems))

		for _, t := range elems {
			v := core.PApp(core.ToString, t).Eval()
			s, ok := v.(core.StringType)

			if !ok {
				return core.NotStringError(v)
			}

			ss = append(ss, string(s))
		}

		var options [2]string

		for i, t := range ts[1:3] {
			v := t.Eval()
			s, ok := v.(core.StringType)

			if !ok {
				return core.NotStringError(v)
			}

			options[i] = string(s)
		}

		file := os.Stdout

		fileArg := ts[3].Eval()
		if s, ok := fileArg.(core.StringType); ok {
			v := ts[4].Eval()
			mode, ok := v.(core.NumberType)
			if !ok {
				return core.NotNumberError(v)
			}

			var err error
			file, err = os.OpenFile(
				string(s),
				os.O_CREATE|os.O_TRUNC|os.O_WRONLY,
				os.FileMode(mode))

			if err != nil {
				return core.OutputError(err.Error())
			}
		} else if n, ok := fileArg.(core.NumberType); ok && n == 2 {
			file = os.Stderr
		} else if !(ok && n == 1) {
			return core.ValueError(
				"file optional argument's value must be 1 or 2, or a string filename. Got %s.",
				core.DumpOrFail(fileArg))
		}

		fmt.Fprint(file, strings.Join(ss, options[0])+options[1])

		return core.NewOutput(core.Nil)
	})
<|endoftext|>


<commit_before>package urlvalues

import "testing"

type S1 struct {
	F01 int     `url:"f01"`
	F02 int     `url:"-"`
	F03 string  `url:"f03"`
	F04 string  `url:"f04,omitempty"`
	F05 bool    `url:"f05"`
	F06 bool    `url:"f06"`
	F07 *string `url:"f07"`
	F08 *int8   `url:"f08"`
}

func TestFilled(t *testing.T) {
	f07 := "seven"
	var f08 int8 = 8
	s := &S1{
		F01: 1,
		F02: 2,
		F03: "three",
		F04: "four",
		F05: true,
		F06: false,
		F07: &f07,
		F08: &f08,
	}

	vals := make(map[string][]string)
	_ = NewEncoder().Encode(s, vals)

	if val, ok := vals["f01"]; ok {
		if val[0] != "1" {
			t.Error("expected '1' got ", val[0])
		}
	}
	if val, ok := vals["f02"]; ok {
		t.Error("Expected 'f02' to be omitted, got ", val[0])
	}
	if val, ok := vals["f03"]; ok {
		if val[0] != "three" {
			t.Error("expected 'three' got ", val[0])
		}
	}
	if val, ok := vals["f05"]; ok {
		if val[0] != "1" {
			t.Error("expected '1' got ", val[0])
		}
	}
	if val, ok := vals["f06"]; ok {
		if val[0] != "0" {
			t.Error("expected '0' got ", val[0])
		}
	}
	if val, ok := vals["f07"]; ok {
		if val[0] != "seven" {
			t.Error("expected 'seven' got ", val[0])
		}
	}
	if val, ok := vals["f08"]; ok {
		if val[0] != "8" {
			t.Error("expected '8' got ", val[0])
		}
	}
}

func TestEmpty(t *testing.T) {
	s := &S1{
		F01: 1,
		F02: 2,
		F03: "three",
	}

	vals := make(map[string][]string)
	_ = NewEncoder().Encode(s, vals)

	if _, ok := vals["f03"]; !ok {
		t.Error("omitempty expected not empty, got empty")
	}
	if val, ok := vals["f04"]; ok {
		t.Error("omitempty expected empty, got ", val)
	}
}
<commit_msg>Make tests less ugly<commit_after>package urlvalues

import "testing"

type S1 struct {
	F01 int     `url:"f01"`
	F02 int     `url:"-"`
	F03 string  `url:"f03"`
	F04 string  `url:"f04,omitempty"`
	F05 bool    `url:"f05"`
	F06 bool    `url:"f06"`
	F07 *string `url:"f07"`
	F08 *int8   `url:"f08"`
}

func TestFilled(t *testing.T) {
	f07 := "seven"
	var f08 int8 = 8
	s := &S1{
		F01: 1,
		F02: 2,
		F03: "three",
		F04: "four",
		F05: true,
		F06: false,
		F07: &f07,
		F08: &f08,
	}

	vals := make(map[string][]string)
	_ = NewEncoder().Encode(s, vals)

	valExists(t, "f01", "1", vals)
	valNotExists(t, "f02", vals)
	valExists(t, "f03", "three", vals)
	valExists(t, "f05", "1", vals)
	valExists(t, "f06", "0", vals)
	valExists(t, "f07", "seven", vals)
	valExists(t, "f08", "8", vals)
}

func TestEmpty(t *testing.T) {
	s := &S1{
		F01: 1,
		F02: 2,
		F03: "three",
	}

	vals := make(map[string][]string)
	_ = NewEncoder().Encode(s, vals)

	valExists(t, "f03", "three", vals)
	valNotExists(t, "f04", vals)
}

func valExists(t *testing.T, key string, expect string, result map[string][]string) {
	if val, ok := result[key]; !ok {
		t.Error("Key not found. Expected: " + expect)
	} else if val[0] != expect {
		t.Error("Unexpected value. Expected: " + expect + "; got: " + val[0] + ".")
	}
}

func valNotExists(t *testing.T, key string, result map[string][]string) {
	if val, ok := result[key]; ok {
		t.Error("Key not ommited. Expected: empty; got: " + val[0] + ".")
	}
}
<|endoftext|>


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

// Package encoding contains subpackages to convert CUE to and from byte-level
// and textual representations.
package encoding
<commit_msg>encoding: adopt naming convention for conversions<commit_after>// Copyright 2019 CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package encoding contains subpackages to convert CUE to and from byte-level
// and textual representations.
//
// For some packages, CUE can be mapped to both concrete values and higher-level
// definitions. For instance, a Go value can be mapped based on its concrete
// values or on its underlying type. Similarly, the protobuf package can extract
// CUE definitions from .proto definitions files, but also convert proto
// messages to concrete values.
//
// To clarify between these cases, we adopt the following naming convention:
//
//    Name        Direction   Level    Example
//    Decode      x -> CUE    Value    Convert an incoming proto message to CUE
//    Encode      CUE -> x    Value    Convert CUE to JSON
//    Extract     x -> CUE    Type     Extract CUE definition from .proto file
//    Generate    CUE -> x    Type     Generate OpenAPI definition from CUE
//
// To be more precise, Decoders and Encoders deal with concrete values only.
//
// Unmarshal and Marshal are used if the respective Decoder and Encoder decode
// and encode from and to a stream of bytes.
package encoding
<|endoftext|>


<commit_before>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"math"

	"github.com/go-gl/mathgl/mgl32"
	"github.com/thinkofdeath/steven/entitysys"
	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/type/direction"
)

func (ce *clientEntities) registerModels() {
	ce.container.AddSystem(entitysys.Add, esPlayerModelAdd)
	ce.container.AddSystem(entitysys.Tick, esPlayerModelTick)

	// Generic removal
	ce.container.AddSystem(entitysys.Remove, esModelRemove)
}

func appendBox(verts []*render.StaticVertex, x, y, z, w, h, d float32, textures [6]*render.TextureInfo) []*render.StaticVertex {
	for i, face := range faceVertices {
		tex := textures[i]
		if tex == nil {
			continue
		}
		for _, v := range face.verts {
			vert := &render.StaticVertex{
				X:        float32(v.X)*w + x,
				Y:        float32(v.Y)*h + y,
				Z:        float32(v.Z)*d + z,
				TOffsetX: v.TOffsetX * 16 * int16(tex.Width),
				TOffsetY: v.TOffsetY * 16 * int16(tex.Height),
				R:        255,
				G:        255,
				B:        255,
				A:        255,
				TX:       uint16(tex.X),
				TY:       uint16(tex.Y),
				TW:       uint16(tex.Width),
				TH:       uint16(tex.Height),
				TAtlas:   int16(tex.Atlas),
			}
			verts = append(verts, vert)
		}
	}
	return verts
}

// Player

type playerModelComponent struct {
	model *render.StaticModel

	dir  float64
	time float64
}

func (p *playerModelComponent) SetModel(m *render.StaticModel) { p.model = m }
func (p *playerModelComponent) Model() *render.StaticModel     { return p.model }
func (p *playerModelComponent) SetDir(d float64)               { p.dir = d }
func (p *playerModelComponent) Dir() float64                   { return p.dir }
func (p *playerModelComponent) SetTime(t float64)              { p.time = t }
func (p *playerModelComponent) Time() float64                  { return p.time }

// Marker method
func (*playerModelComponent) playerModel() {}

type PlayerModelComponent interface {
	SetModel(m *render.StaticModel)
	Model() *render.StaticModel

	SetDir(d float64)
	Dir() float64
	SetTime(t float64)
	Time() float64

	playerModel()
}

const (
	playerModelHead = iota
	playerModelBody
	playerModelLegLeft
	playerModelLegRight
	playerModelArmLeft
	playerModelArmRight
)

func esPlayerModelAdd(p PlayerModelComponent, pl PlayerComponent) {

	uuid := pl.UUID()
	info := Client.playerList.info[uuid]
	if info == nil {
		panic("missing player info")
	}
	skin := info.skin

	hverts := appendBox(nil, -4/16.0, 0, -4/16.0, 8/16.0, 8/16.0, 8/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8, 8, 8, 8),
		direction.South: skin.Sub(24, 8, 8, 8),
		direction.West:  skin.Sub(0, 8, 8, 8),
		direction.East:  skin.Sub(16, 8, 8, 8),
		direction.Up:    skin.Sub(8, 0, 8, 8),
		direction.Down:  skin.Sub(16, 0, 8, 8),
	})
	hverts = appendBox(hverts, -4.2/16.0, -.2/16.0, -4.2/16.0, 8.4/16.0, 8.4/16.0, 8.4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8+32, 8, 8, 8),
		direction.South: skin.Sub(24+32, 8, 8, 8),
		direction.West:  skin.Sub(0+32, 8, 8, 8),
		direction.East:  skin.Sub(16+32, 8, 8, 8),
		direction.Up:    skin.Sub(8+32, 0, 8, 8),
		direction.Down:  skin.Sub(16+32, 0, 8, 8),
	})

	bverts := appendBox(nil, -4/16.0, -6/16.0, -2/16.0, 8/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20, 8, 12),
		direction.South: skin.Sub(32, 20, 8, 12),
		direction.West:  skin.Sub(16, 20, 4, 12),
		direction.East:  skin.Sub(28, 20, 4, 12),
		direction.Up:    skin.Sub(20, 16, 8, 4),
		direction.Down:  skin.Sub(28, 16, 8, 4),
	})
	bverts = appendBox(bverts, -4.2/16.0, -6.2/16.0, -2.2/16.0, 8.4/16.0, 12.4/16.0, 4.4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20+16, 8, 12),
		direction.South: skin.Sub(32, 20+16, 8, 12),
		direction.West:  skin.Sub(16, 20+16, 4, 12),
		direction.East:  skin.Sub(28, 20+16, 4, 12),
		direction.Up:    skin.Sub(20, 16+16, 8, 4),
		direction.Down:  skin.Sub(28, 16+16, 8, 4),
	})

	var lverts [4][]*render.StaticVertex

	for i, off := range [][4]int{
		{0, 16, 0, 32},
		{16, 48, 0, 48},
		{32, 48, 48, 48},
		{40, 16, 40, 32},
	} {
		ox, oy := off[0], off[1]
		lverts[i] = appendBox(nil, -2/16.0, -12/16.0, -2/16.0, 4/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
		ox, oy = off[2], off[3]
		lverts[i] = appendBox(lverts[i], -2.2/16.0, -12.2/16.0, -2.2/16.0, 4.4/16.0, 12.4/16.0, 4.4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
	}

	model := render.NewStaticModel([][]*render.StaticVertex{
		playerModelHead:     hverts,
		playerModelBody:     bverts,
		playerModelLegLeft:  lverts[0],
		playerModelLegRight: lverts[1],
		playerModelArmLeft:  lverts[2],
		playerModelArmRight: lverts[3],
	})
	p.SetModel(model)
}

func esModelRemove(p interface {
	Model() *render.StaticModel
}) {
	p.Model().Free()
}

func esPlayerModelTick(p PlayerModelComponent,
	pos PositionComponent, t TargetPositionComponent, r RotationComponent) {
	x, y, z := pos.Position()
	offMat := mgl32.Translate3D(float32(x), -float32(y), float32(z)).
		Mul4(mgl32.Rotate3DY(math.Pi - float32(r.Yaw())).Mat4())

	model := p.Model()
	model.Matrix[playerModelHead] = offMat.Mul4(mgl32.Translate3D(0, -12/16.0-12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(float32(r.Pitch())).Mat4())
	model.Matrix[playerModelBody] = offMat.Mul4(mgl32.Translate3D(0, -12/16.0-6/16.0, 0))

	time := p.Time()
	dir := p.Dir()
	if dir == 0 {
		dir = 1
		time = 15
	}
	ang := ((time / 15) - 1) * (math.Pi / 4)

	model.Matrix[playerModelLegLeft] = offMat.Mul4(mgl32.Translate3D(2/16.0, -12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(float32(ang)).Mat4())
	model.Matrix[playerModelLegRight] = offMat.Mul4(mgl32.Translate3D(-2/16.0, -12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(-float32(ang)).Mat4())

	model.Matrix[playerModelArmLeft] = offMat.Mul4(mgl32.Translate3D(6/16.0, -12/16.0-12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(-float32(ang * 0.75)).Mat4())
	model.Matrix[playerModelArmRight] = offMat.Mul4(mgl32.Translate3D(-6/16.0, -12/16.0-12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(float32(ang * 0.75)).Mat4())

	tx, _, tz := t.TargetPosition()
	update := true
	d := (tx-x)*(tx-x) + (tz-z)*(tz-z)
	if d < 0.0001 {
		if math.Abs(time-15) < 0.1 {
			time = 15
			update = false
		}
		dir = math.Copysign(1, 15-time)
	}

	if update {
		time += Client.delta * 1.5 * dir
		if time > 30 {
			time = 30
			dir = -1
		} else if time < 0 {
			time = 0
			dir = 1
		}
	}
	p.SetDir(dir)
	p.SetTime(time)
}
<commit_msg>steven: add a basic idle animation<commit_after>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"math"

	"github.com/go-gl/mathgl/mgl32"
	"github.com/thinkofdeath/steven/entitysys"
	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/type/direction"
)

func (ce *clientEntities) registerModels() {
	ce.container.AddSystem(entitysys.Add, esPlayerModelAdd)
	ce.container.AddSystem(entitysys.Tick, esPlayerModelTick)

	// Generic removal
	ce.container.AddSystem(entitysys.Remove, esModelRemove)
}

func appendBox(verts []*render.StaticVertex, x, y, z, w, h, d float32, textures [6]*render.TextureInfo) []*render.StaticVertex {
	for i, face := range faceVertices {
		tex := textures[i]
		if tex == nil {
			continue
		}
		for _, v := range face.verts {
			vert := &render.StaticVertex{
				X:        float32(v.X)*w + x,
				Y:        float32(v.Y)*h + y,
				Z:        float32(v.Z)*d + z,
				TOffsetX: v.TOffsetX * 16 * int16(tex.Width),
				TOffsetY: v.TOffsetY * 16 * int16(tex.Height),
				R:        255,
				G:        255,
				B:        255,
				A:        255,
				TX:       uint16(tex.X),
				TY:       uint16(tex.Y),
				TW:       uint16(tex.Width),
				TH:       uint16(tex.Height),
				TAtlas:   int16(tex.Atlas),
			}
			verts = append(verts, vert)
		}
	}
	return verts
}

// Player

type playerModelComponent struct {
	model *render.StaticModel

	dir      float64
	time     float64
	idleTime float64
}

func (p *playerModelComponent) SetModel(m *render.StaticModel) { p.model = m }
func (p *playerModelComponent) Model() *render.StaticModel     { return p.model }
func (p *playerModelComponent) SetDir(d float64)               { p.dir = d }
func (p *playerModelComponent) Dir() float64                   { return p.dir }
func (p *playerModelComponent) SetTime(t float64)              { p.time = t }
func (p *playerModelComponent) Time() float64                  { return p.time }
func (p *playerModelComponent) SetIdleTime(t float64)          { p.idleTime = t }
func (p *playerModelComponent) IdleTime() float64              { return p.idleTime }

// Marker method
func (*playerModelComponent) playerModel() {}

type PlayerModelComponent interface {
	SetModel(m *render.StaticModel)
	Model() *render.StaticModel

	SetDir(d float64)
	Dir() float64
	SetTime(t float64)
	Time() float64
	SetIdleTime(t float64)
	IdleTime() float64

	playerModel()
}

const (
	playerModelHead = iota
	playerModelBody
	playerModelLegLeft
	playerModelLegRight
	playerModelArmLeft
	playerModelArmRight
)

func esPlayerModelAdd(p PlayerModelComponent, pl PlayerComponent) {

	uuid := pl.UUID()
	info := Client.playerList.info[uuid]
	if info == nil {
		panic("missing player info")
	}
	skin := info.skin

	hverts := appendBox(nil, -4/16.0, 0, -4/16.0, 8/16.0, 8/16.0, 8/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8, 8, 8, 8),
		direction.South: skin.Sub(24, 8, 8, 8),
		direction.West:  skin.Sub(0, 8, 8, 8),
		direction.East:  skin.Sub(16, 8, 8, 8),
		direction.Up:    skin.Sub(8, 0, 8, 8),
		direction.Down:  skin.Sub(16, 0, 8, 8),
	})
	hverts = appendBox(hverts, -4.2/16.0, -.2/16.0, -4.2/16.0, 8.4/16.0, 8.4/16.0, 8.4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8+32, 8, 8, 8),
		direction.South: skin.Sub(24+32, 8, 8, 8),
		direction.West:  skin.Sub(0+32, 8, 8, 8),
		direction.East:  skin.Sub(16+32, 8, 8, 8),
		direction.Up:    skin.Sub(8+32, 0, 8, 8),
		direction.Down:  skin.Sub(16+32, 0, 8, 8),
	})

	bverts := appendBox(nil, -4/16.0, -6/16.0, -2/16.0, 8/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20, 8, 12),
		direction.South: skin.Sub(32, 20, 8, 12),
		direction.West:  skin.Sub(16, 20, 4, 12),
		direction.East:  skin.Sub(28, 20, 4, 12),
		direction.Up:    skin.Sub(20, 16, 8, 4),
		direction.Down:  skin.Sub(28, 16, 8, 4),
	})
	bverts = appendBox(bverts, -4.2/16.0, -6.2/16.0, -2.2/16.0, 8.4/16.0, 12.4/16.0, 4.4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20+16, 8, 12),
		direction.South: skin.Sub(32, 20+16, 8, 12),
		direction.West:  skin.Sub(16, 20+16, 4, 12),
		direction.East:  skin.Sub(28, 20+16, 4, 12),
		direction.Up:    skin.Sub(20, 16+16, 8, 4),
		direction.Down:  skin.Sub(28, 16+16, 8, 4),
	})

	var lverts [4][]*render.StaticVertex

	for i, off := range [][4]int{
		{0, 16, 0, 32},
		{16, 48, 0, 48},
		{32, 48, 48, 48},
		{40, 16, 40, 32},
	} {
		ox, oy := off[0], off[1]
		lverts[i] = appendBox(nil, -2/16.0, -12/16.0, -2/16.0, 4/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
		ox, oy = off[2], off[3]
		lverts[i] = appendBox(lverts[i], -2.2/16.0, -12.2/16.0, -2.2/16.0, 4.4/16.0, 12.4/16.0, 4.4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
	}

	model := render.NewStaticModel([][]*render.StaticVertex{
		playerModelHead:     hverts,
		playerModelBody:     bverts,
		playerModelLegLeft:  lverts[0],
		playerModelLegRight: lverts[1],
		playerModelArmLeft:  lverts[2],
		playerModelArmRight: lverts[3],
	})
	p.SetModel(model)
}

func esModelRemove(p interface {
	Model() *render.StaticModel
}) {
	p.Model().Free()
}

func esPlayerModelTick(p PlayerModelComponent,
	pos PositionComponent, t TargetPositionComponent, r RotationComponent) {
	x, y, z := pos.Position()
	offMat := mgl32.Translate3D(float32(x), -float32(y), float32(z)).
		Mul4(mgl32.Rotate3DY(math.Pi - float32(r.Yaw())).Mat4())

	model := p.Model()
	model.Matrix[playerModelHead] = offMat.Mul4(mgl32.Translate3D(0, -12/16.0-12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(float32(r.Pitch())).Mat4())
	model.Matrix[playerModelBody] = offMat.Mul4(mgl32.Translate3D(0, -12/16.0-6/16.0, 0))

	time := p.Time()
	dir := p.Dir()
	if dir == 0 {
		dir = 1
		time = 15
	}
	ang := ((time / 15) - 1) * (math.Pi / 4)

	model.Matrix[playerModelLegLeft] = offMat.Mul4(mgl32.Translate3D(2/16.0, -12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(float32(ang)).Mat4())
	model.Matrix[playerModelLegRight] = offMat.Mul4(mgl32.Translate3D(-2/16.0, -12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(-float32(ang)).Mat4())

	iTime := p.IdleTime()
	iTime += Client.delta * 0.02
	p.SetIdleTime(iTime)

	model.Matrix[playerModelArmLeft] = offMat.Mul4(mgl32.Translate3D(6/16.0, -12/16.0-12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(-float32(ang * 0.75)).Mat4()).
		Mul4(mgl32.Rotate3DZ(float32(math.Cos(iTime)*0.06) - 0.06).Mat4()).
		Mul4(mgl32.Rotate3DX(float32(math.Sin(iTime) * 0.06)).Mat4())
	model.Matrix[playerModelArmRight] = offMat.Mul4(mgl32.Translate3D(-6/16.0, -12/16.0-12/16.0, 0)).
		Mul4(mgl32.Rotate3DX(float32(ang * 0.75)).Mat4()).
		Mul4(mgl32.Rotate3DZ(-float32(math.Cos(iTime)*0.06) + 0.06).Mat4()).
		Mul4(mgl32.Rotate3DX(-float32(math.Sin(iTime) * 0.06)).Mat4())

	tx, _, tz := t.TargetPosition()
	update := true
	d := (tx-x)*(tx-x) + (tz-z)*(tz-z)
	if d < 0.0001 {
		if math.Abs(time-15) < 0.1 {
			time = 15
			update = false
		}
		dir = math.Copysign(1, 15-time)
	}

	if update {
		time += Client.delta * 1.5 * dir
		if time > 30 {
			time = 30
			dir = -1
		} else if time < 0 {
			time = 0
			dir = 1
		}
	}
	p.SetDir(dir)
	p.SetTime(time)
}
<|endoftext|>


<commit_before>package honeybadger

import (
	"code.google.com/p/go-uuid/uuid"
	"encoding/json"
	"runtime"
	"strconv"
)

const MaxFrames = 20

type Frame struct {
	Number string `json:"number"`
	File   string `json:"file"`
	Method string `json:"method"`
}

type hash map[string]interface{}

type Notice struct {
	APIKey       string
	Error        error
	Token        string
	ErrorMessage string
	Hostname     string
	Env          string
	Backtrace    []*Frame
}

func (n *Notice) asJSON() *hash {
	return &hash{
		"api_key": n.APIKey,
		"notifier": &hash{
			"name":    "honeybadger",
			"url":     "https://github.com/honeybadger-io/honeybadger-go",
			"version": "0.0.0",
		},
		"error": &hash{
			"token":     n.Token,
			"message":   n.ErrorMessage,
			"backtrace": n.Backtrace,
		},
		"server": &hash{
			"environment_name": n.Env,
			"hostname":         n.Hostname,
		},
	}
}

func (n *Notice) toJSON() []byte {
	if out, err := json.Marshal(n.asJSON()); err == nil {
		return out
	} else {
		panic(err)
	}
}

func generateStack() (frames []*Frame) {
	stack := make([]uintptr, MaxFrames)
	length := runtime.Callers(4, stack[:])
	for _, pc := range stack[:length] {
		f := runtime.FuncForPC(pc)
		if f == nil {
			continue
		}
		file, line := f.FileLine(pc)
		frame := &Frame{
			File:   file,
			Number: strconv.Itoa(line),
			Method: f.Name(),
		}
		frames = append(frames, frame)
	}

	return
}

func newNotice(config *Config, err error) *Notice {
	notice := Notice{
		APIKey:       config.APIKey,
		Error:        err,
		Token:        uuid.NewRandom().String(),
		ErrorMessage: err.Error(),
		Env:          config.Env,
		Hostname:     config.Hostname,
		Backtrace:    generateStack(),
	}

	return &notice
}
<commit_msg>Add class name.<commit_after>package honeybadger

import (
	"code.google.com/p/go-uuid/uuid"
	"encoding/json"
	"reflect"
	"runtime"
	"strconv"
)

const MaxFrames = 20

type Frame struct {
	Number string `json:"number"`
	File   string `json:"file"`
	Method string `json:"method"`
}

type hash map[string]interface{}

type Notice struct {
	APIKey       string
	Error        error
	Token        string
	ErrorMessage string
	ErrorClass   string
	Hostname     string
	Env          string
	Backtrace    []*Frame
}

func (n *Notice) asJSON() *hash {
	return &hash{
		"api_key": n.APIKey,
		"notifier": &hash{
			"name":    "honeybadger",
			"url":     "https://github.com/honeybadger-io/honeybadger-go",
			"version": "0.0.0",
		},
		"error": &hash{
			"token":     n.Token,
			"message":   n.ErrorMessage,
			"class":     n.ErrorClass,
			"backtrace": n.Backtrace,
		},
		"server": &hash{
			"environment_name": n.Env,
			"hostname":         n.Hostname,
		},
	}
}

func (n *Notice) toJSON() []byte {
	if out, err := json.Marshal(n.asJSON()); err == nil {
		return out
	} else {
		panic(err)
	}
}

func generateStack() (frames []*Frame) {
	stack := make([]uintptr, MaxFrames)
	length := runtime.Callers(4, stack[:])
	for _, pc := range stack[:length] {
		f := runtime.FuncForPC(pc)
		if f == nil {
			continue
		}
		file, line := f.FileLine(pc)
		frame := &Frame{
			File:   file,
			Number: strconv.Itoa(line),
			Method: f.Name(),
		}
		frames = append(frames, frame)
	}

	return
}

func newNotice(config *Config, err error) *Notice {
	notice := Notice{
		APIKey:       config.APIKey,
		Error:        err,
		Token:        uuid.NewRandom().String(),
		ErrorMessage: err.Error(),
		ErrorClass:   reflect.TypeOf(err).String(),
		Env:          config.Env,
		Hostname:     config.Hostname,
		Backtrace:    generateStack(),
	}

	return &notice
}
<|endoftext|>


<commit_before>package main

import "fmt"
import "os"
import "io"
import "os/exec"
import "strings"

import "github.com/shiena/ansicolor"

import "./alias"
import "./builtincmd"
import "./completion"
import "./conio"
import "./history"
import "./interpreter"
import "./prompt"

func commandHooks(cmd *exec.Cmd, IsBackground bool) (interpreter.WhatToDoAfterCmd, error) {
	status, _ := alias.Hook(cmd, IsBackground)
	if status != interpreter.THROUGH {
		return status, nil
	}
	return builtincmd.Exec(cmd, IsBackground)
}

func main() {
	// KeyBind += completion Module
	conio.KeyMap['\t'] = completion.KeyFuncCompletion
	conio.ZeroMap[conio.K_UP] = history.KeyFuncHistoryUp
	conio.ZeroMap[conio.K_DOWN] = history.KeyFuncHistoryDown
	conio.KeyMap['P'&0x1F] = history.KeyFuncHistoryUp
	conio.KeyMap['N'&0x1F] = history.KeyFuncHistoryDown

	// ANSI Escape Sequence Support
	ansiOut := ansicolor.NewAnsiColorWriter(os.Stdout)

	// Parameter Parsing
	for i := 1; i < len(os.Args); i++ {
		if os.Args[i][0] == '-' {
			if os.Args[i][1] == 'a' {
				equation := ""
				if i+1 < len(os.Args) {
					i++
					equation = os.Args[i]
					equationArray := strings.SplitN(equation, "=", 2)
					if len(equationArray) >= 2 {
						alias.Table[strings.ToLower(equationArray[0])] = equationArray[1]
					} else {
						delete(alias.Table, strings.ToLower(equationArray[0]))
					}
				}
			}
		}
	}

	for {
		io.WriteString(ansiOut, prompt.Format2Prompt(os.Getenv("PROMPT")))
		line, cont := conio.ReadLine()
		if cont == conio.ABORT {
			break
		}
		history.Push(line)
		whatToDo, err := interpreter.Interpret(line, commandHooks, nil)
		if err != nil {
			fmt.Println(err)
		}
		if whatToDo == interpreter.SHUTDOWN {
			break
		}
	}
}
<commit_msg>-c ,-k オプションを追加<commit_after>package main

import "fmt"
import "os"
import "io"
import "os/exec"
import "strings"

import "github.com/shiena/ansicolor"

import "./alias"
import "./builtincmd"
import "./completion"
import "./conio"
import "./history"
import "./interpreter"
import "./prompt"

func commandHooks(cmd *exec.Cmd, IsBackground bool) (interpreter.WhatToDoAfterCmd, error) {
	status, _ := alias.Hook(cmd, IsBackground)
	if status != interpreter.THROUGH {
		return status, nil
	}
	return builtincmd.Exec(cmd, IsBackground)
}

func main() {
	// KeyBind += completion Module
	conio.KeyMap['\t'] = completion.KeyFuncCompletion
	conio.ZeroMap[conio.K_UP] = history.KeyFuncHistoryUp
	conio.ZeroMap[conio.K_DOWN] = history.KeyFuncHistoryDown
	conio.KeyMap['P'&0x1F] = history.KeyFuncHistoryUp
	conio.KeyMap['N'&0x1F] = history.KeyFuncHistoryDown

	// ANSI Escape Sequence Support
	ansiOut := ansicolor.NewAnsiColorWriter(os.Stdout)

	// Parameter Parsing
	for i := 1; i < len(os.Args); i++ {
		if os.Args[i][0] == '-' {
			for _, o := range os.Args[i][1:] {
				switch o {
				case 'a':
					i++
					if i < len(os.Args) {
						equation := os.Args[i]
						equationArray := strings.SplitN(equation, "=", 2)
						if len(equationArray) >= 2 {
							alias.Table[strings.ToLower(equationArray[0])] =
								equationArray[1]
						} else {
							delete(alias.Table, strings.ToLower(
								equationArray[0]))
						}
					}
				case 'c', 'k':
					i++
					if i < len(os.Args) {
						interpreter.Interpret(os.Args[i], commandHooks, nil)
					}
					if o == 'c' {
						return
					}
				}
			}
		}
	}

	for {
		io.WriteString(ansiOut, prompt.Format2Prompt(os.Getenv("PROMPT")))
		line, cont := conio.ReadLine()
		if cont == conio.ABORT {
			break
		}
		history.Push(line)
		whatToDo, err := interpreter.Interpret(line, commandHooks, nil)
		if err != nil {
			fmt.Println(err)
		}
		if whatToDo == interpreter.SHUTDOWN {
			break
		}
	}
}
<|endoftext|>


<commit_before>package lib

import (
	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"code.google.com/p/goauth2/oauth"
	drive "code.google.com/p/google-api-go-client/drive/v2"
	"log"
	"time"
)

// DriveFs is a struct which holds the FUSE filesystem
type Server struct {
	Config *oauth.Config
	conn   *fuse.Conn
}

// initialize and return a new DriveFS
func NewServer(config *oauth.Config, code string) (*Server, error) {
	d := &Server{Config: config}
	// Set up a Transport using the config.
	transport := &oauth.Transport{Config: config}

	// Try to pull the token from the cache; if this fails, we need to get one.
	token, err := config.TokenCache.Token()
	if err != nil {
		if d.Config.ClientId == "" || d.Config.ClientSecret == "" {
			log.Fatal("Both Client Id and Client Secret must be given")
		}
		if code == "" {
			// Get an authorization code from the data provider.
			// ("Please ask the user if I can access this resource.")
			url := d.Config.AuthCodeURL("")
			log.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE\n")
			log.Fatalln(url)
		}
		// Exchange the authorization code for an access token.
		// ("Here's the code you gave the user, now give me a token!")
		token, err = transport.Exchange(code)
		if err != nil {
			log.Fatal("Exchange:", err)
		}
		// (The Exchange method will automatically cache the token.)
		log.Printf("Token is cached in %v\n", d.Config.TokenCache)
	}
	transport.Token = token

	// initialize global vars
	client = transport.Client()
	nameToDir = make(map[string]DriveDir)
	nameToFile = make(map[string]DriveFile)
	idToDir = make(map[string]DriveDir)
	idToFile = make(map[string]DriveFile)
	service, err = drive.New(client)
	return d, err
}

// Mount attmpts to mount the filesystem
func (s *Server) Mount(mountPoint string) (err error) {
	s.conn, err = fuse.Mount(mountPoint)
	return
}

// Serve attempts to serve the filesystem
func (s *Server) Serve(refreshRate int) {
	refreshFileIndex()
	refreshChildIndex()
	refreshNameToFile()
	refreshNameToDir()
	// refresh the fileIndex and DirIndex every ten seconds
	go func() {
		for {
			<-time.After(time.Duration(refreshRate) * time.Second)
			log.Println("Refreshing indexes.")
			refreshFileIndex()
			go refreshChildIndex()
			go refreshNameToFile()
			go refreshNameToDir()

		}
	}()
	if err := fs.Serve(s.conn, Root{}); err != nil {
		log.Fatalf("Could not serve drivefs %s", err.Error())
	}

}

// Unmount attempts to unmount the filesystem
func (s *Server) Unmount(mountPoint string, timeout int) (err error) {
	for i := 0; i < timeout; i++ {
		err = fuse.Unmount(mountPoint)
		if err == nil {
			err = s.conn.Close()
			if err != nil {
				log.Fatalln(err)
			}
			return nil
		}
		log.Println(err)
	}
	err = s.conn.Close()
	return err

}
<commit_msg>reads and mkdir now workign<commit_after>package lib

import (
	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"code.google.com/p/goauth2/oauth"
	drive "code.google.com/p/google-api-go-client/drive/v2"
	"log"
	"time"
)

// DriveFs is a struct which holds the FUSE filesystem
type Server struct {
	Config *oauth.Config
	conn   *fuse.Conn
}

// initialize and return a new DriveFS
func NewServer(config *oauth.Config, code string) (*Server, error) {
	d := &Server{Config: config}
	// Set up a Transport using the config.
	transport := &oauth.Transport{Config: config}

	// Try to pull the token from the cache; if this fails, we need to get one.
	token, err := config.TokenCache.Token()
	if err != nil {
		if d.Config.ClientId == "" || d.Config.ClientSecret == "" {
			log.Fatal("Both Client Id and Client Secret must be given")
		}
		if code == "" {
			// Get an authorization code from the data provider.
			// ("Please ask the user if I can access this resource.")
			url := d.Config.AuthCodeURL("")
			log.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE\n")
			log.Fatalln(url)
		}
		// Exchange the authorization code for an access token.
		// ("Here's the code you gave the user, now give me a token!")
		token, err = transport.Exchange(code)
		if err != nil {
			log.Fatal("Exchange:", err)
		}
		// (The Exchange method will automatically cache the token.)
		log.Printf("Token is cached in %v\n", d.Config.TokenCache)
	}
	transport.Token = token

	// initialize global vars
	client = transport.Client()
	nameToDir = make(map[string]DriveDir)
	nameToFile = make(map[string]DriveFile)
	idToDir = make(map[string]DriveDir)
	idToFile = make(map[string]DriveFile)
	service, err = drive.New(client)
	return d, err
}

// Mount attmpts to mount the filesystem
func (s *Server) Mount(mountPoint string) (err error) {
	s.conn, err = fuse.Mount(mountPoint)
	return
}

// Serve attempts to serve the filesystem
func (s *Server) Serve(refreshRate int) {
	refreshFileIndex()
	refreshChildIndex()
	refreshNameToFile()
	refreshNameToDir()
	// refresh the fileIndex and DirIndex every ten seconds
	go func() {
		for {
			<-time.After(time.Duration(refreshRate) * time.Second)
			log.Println("Refreshing indexes.")
			refreshFileIndex()
			go refreshChildIndex()
			go refreshNameToFile()
			go refreshNameToDir()
		}
	}()
	if err := fs.Serve(s.conn, Root{}); err != nil {
		log.Fatalf("Could not serve drivefs %s", err.Error())
	}
}

// Unmount attempts to unmount the filesystem
func (s *Server) Unmount(mountPoint string, timeout int) (err error) {
	for i := 0; i < timeout; i++ {
		err = fuse.Unmount(mountPoint)
		if err == nil {
			err = s.conn.Close()
			if err != nil {
				log.Fatalln(err)
			}
			return nil
		}
		log.Println(err)
	}
	err = s.conn.Close()
	return err

}
<|endoftext|>


<commit_before>package library

import (
	"io/ioutil"
	"os"
	"path/filepath"

	"github.com/anaminus/rbxmk"
	"github.com/yuin/gopher-lua"
)

func OS(s rbxmk.State) {
	lib, ok := s.L.GetGlobal("os").(*lua.LTable)
	if !ok {
		lib = s.L.CreateTable(0, 5)
		s.L.SetGlobal("os", lib)
	}
	lib.RawSetString("split", s.WrapFunc(osSplit))
	lib.RawSetString("join", s.WrapFunc(osJoin))
	lib.RawSetString("expand", s.WrapFunc(osExpand))
	lib.RawSetString("getenv", s.WrapFunc(osGetenv))
	lib.RawSetString("dir", s.WrapFunc(osDir))
}

func osSplit(s rbxmk.State) int {
	path := s.L.CheckString(1)
	for i := 2; i <= s.L.GetTop(); i++ {
		var result string
		switch typ := s.L.CheckString(i); typ {
		case "dir":
			result = filepath.Dir(path)
		case "base":
			result = filepath.Base(path)
		case "ext":
			result = filepath.Ext(path)
		case "stem":
			result = filepath.Base(path)
			result = result[:len(result)-len(filepath.Ext(path))]
		case "fext":
			// result = scheme.GuessFileExtension(ctx.Options, "", path)
			// if result != "" && result != "." {
			// 	result = "." + result
			// }
		case "fstem":
			// ext := scheme.GuessFileExtension(ctx.Options, "", path)
			// if ext != "" && ext != "." {
			// 	ext = "." + ext
			// }
			// result = filepath.Base(path)
			// result = result[:len(result)-len(ext)]
		default:
			s.L.RaiseError("unknown argument %q", typ)
			return 0
		}
		s.L.Push(lua.LString(result))
	}
	return s.L.GetTop() - 1
}

func osJoin(s rbxmk.State) int {
	j := make([]string, s.L.GetTop())
	for i := 1; i <= s.L.GetTop(); i++ {
		j[i-1] = s.L.CheckString(i)
	}
	filename := filepath.Join(j...)
	s.L.Push(lua.LString(filename))
	return 1
}

func osExpand(s rbxmk.State) int {
	expanded := os.Expand(s.L.CheckString(1), func(v string) string {
		switch v {
		case "script_name", "sn":
			if fi, ok := s.PeekFile(); ok {
				path, _ := filepath.Abs(fi.Path)
				return filepath.Base(path)
			}
		case "script_directory", "script_dir", "sd":
			if fi, ok := s.PeekFile(); ok {
				path, _ := filepath.Abs(fi.Path)
				return filepath.Dir(path)
			}
		case "working_directory", "working_dir", "wd":
			wd, _ := os.Getwd()
			return wd
		case "temp_directory", "temp_dir", "tmp":
			return os.TempDir()
		}
		return ""
	})
	s.L.Push(lua.LString(expanded))
	return 1
}

func osGetenv(s rbxmk.State) int {
	value, ok := os.LookupEnv(s.L.CheckString(1))
	if ok {
		s.L.Push(lua.LString(value))
	} else {
		s.L.Push(lua.LNil)
	}
	return 1
}

func osDir(s rbxmk.State) int {
	dirname := s.L.CheckString(1)
	files, err := ioutil.ReadDir(dirname)
	if err != nil {
		s.L.RaiseError(err.Error())
		return 0
	}
	tfiles := s.L.CreateTable(len(files), 0)
	for _, info := range files {
		tinfo := s.L.CreateTable(0, 4)
		tinfo.RawSetString("name", lua.LString(info.Name()))
		tinfo.RawSetString("isdir", lua.LBool(info.IsDir()))
		tinfo.RawSetString("size", lua.LNumber(info.Size()))
		tinfo.RawSetString("modtime", lua.LNumber(info.ModTime().Unix()))
		tfiles.Append(tinfo)
	}
	s.L.Push(tfiles)
	return 1
}
<commit_msg>Fix os.split.<commit_after>package library

import (
	"io/ioutil"
	"os"
	"path/filepath"

	"github.com/anaminus/rbxmk"
	"github.com/yuin/gopher-lua"
)

func OS(s rbxmk.State) {
	lib, ok := s.L.GetGlobal("os").(*lua.LTable)
	if !ok {
		lib = s.L.CreateTable(0, 5)
		s.L.SetGlobal("os", lib)
	}
	lib.RawSetString("split", s.WrapFunc(osSplit))
	lib.RawSetString("join", s.WrapFunc(osJoin))
	lib.RawSetString("expand", s.WrapFunc(osExpand))
	lib.RawSetString("getenv", s.WrapFunc(osGetenv))
	lib.RawSetString("dir", s.WrapFunc(osDir))
}

func guessExt(s rbxmk.State, filename string) (ext string) {
	i := len(filename) - 1
	for ; i >= 0 && !os.IsPathSeparator(filename[i]); i-- {
	}
	filename = filename[i+1:]
	for {
		for i := 0; i < len(filename); i++ {
			if filename[i] == '.' {
				filename = filename[i+1:]
				goto check
			}
		}
		return ""
	check:
		if s.Format(filename).Name != "" {
			return filename
		}
	}
}

func osSplit(s rbxmk.State) int {
	path := s.L.CheckString(1)
	n := s.L.GetTop()
	for i := 2; i <= n; i++ {
		var result string
		switch typ := s.L.CheckString(i); typ {
		case "dir":
			result = filepath.Dir(path)
		case "base":
			result = filepath.Base(path)
		case "ext":
			result = filepath.Ext(path)
		case "stem":
			result = filepath.Base(path)
			result = result[:len(result)-len(filepath.Ext(path))]
		case "fext":
			result = guessExt(s, path)
			if result != "" && result != "." {
				result = "." + result
			}
		case "fstem":
			ext := guessExt(s, path)
			if ext != "" && ext != "." {
				ext = "." + ext
			}
			result = filepath.Base(path)
			result = result[:len(result)-len(ext)]
		default:
			s.L.RaiseError("unknown argument %q", typ)
			return 0
		}
		s.L.Push(lua.LString(result))
	}
	return n - 1
}

func osJoin(s rbxmk.State) int {
	j := make([]string, s.L.GetTop())
	for i := 1; i <= s.L.GetTop(); i++ {
		j[i-1] = s.L.CheckString(i)
	}
	filename := filepath.Join(j...)
	s.L.Push(lua.LString(filename))
	return 1
}

func osExpand(s rbxmk.State) int {
	expanded := os.Expand(s.L.CheckString(1), func(v string) string {
		switch v {
		case "script_name", "sn":
			if fi, ok := s.PeekFile(); ok {
				path, _ := filepath.Abs(fi.Path)
				return filepath.Base(path)
			}
		case "script_directory", "script_dir", "sd":
			if fi, ok := s.PeekFile(); ok {
				path, _ := filepath.Abs(fi.Path)
				return filepath.Dir(path)
			}
		case "working_directory", "working_dir", "wd":
			wd, _ := os.Getwd()
			return wd
		case "temp_directory", "temp_dir", "tmp":
			return os.TempDir()
		}
		return ""
	})
	s.L.Push(lua.LString(expanded))
	return 1
}

func osGetenv(s rbxmk.State) int {
	value, ok := os.LookupEnv(s.L.CheckString(1))
	if ok {
		s.L.Push(lua.LString(value))
	} else {
		s.L.Push(lua.LNil)
	}
	return 1
}

func osDir(s rbxmk.State) int {
	dirname := s.L.CheckString(1)
	files, err := ioutil.ReadDir(dirname)
	if err != nil {
		s.L.RaiseError(err.Error())
		return 0
	}
	tfiles := s.L.CreateTable(len(files), 0)
	for _, info := range files {
		tinfo := s.L.CreateTable(0, 4)
		tinfo.RawSetString("name", lua.LString(info.Name()))
		tinfo.RawSetString("isdir", lua.LBool(info.IsDir()))
		tinfo.RawSetString("size", lua.LNumber(info.Size()))
		tinfo.RawSetString("modtime", lua.LNumber(info.ModTime().Unix()))
		tfiles.Append(tinfo)
	}
	s.L.Push(tfiles)
	return 1
}
<|endoftext|>