<commit_before>package main

import (
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"time"

	"github.com/restic/restic"
	"github.com/restic/restic/backend"
)

const (
	minute = 60
	hour   = 60 * minute
	day    = 24 * hour
	week   = 7 * day
)

type Table struct {
	Header string
	Rows   [][]interface{}

	RowFormat string
}

func NewTable() Table {
	return Table{
		Rows: [][]interface{}{},
	}
}

func (t Table) Write(w io.Writer) error {
	_, err := fmt.Fprintln(w, t.Header)
	if err != nil {
		return err
	}
	_, err = fmt.Fprintln(w, strings.Repeat("-", 70))
	if err != nil {
		return err
	}

	for _, row := range t.Rows {
		_, err = fmt.Fprintf(w, t.RowFormat+"\n", row...)
		if err != nil {
			return err
		}
	}

	return nil
}

const TimeFormat = "2006-01-02 15:04:05"

func reltime(t time.Time) string {
	sec := uint64(time.Since(t).Seconds())

	switch {
	case sec > week:
		return t.Format(TimeFormat)
	case sec > day:
		return fmt.Sprintf("%d days ago", sec/day)
	case sec > hour:
		return fmt.Sprintf("%d hours ago", sec/hour)
	case sec > minute:
		return fmt.Sprintf("%d minutes ago", sec/minute)
	default:
		return fmt.Sprintf("%d seconds ago", sec)
	}
}

type CmdSnapshots struct {
	global *GlobalOptions
}

func init() {
	_, err := parser.AddCommand("snapshots",
		"show snapshots",
		"The snapshots command lists all snapshots stored in a repository",
		&CmdSnapshots{global: &globalOpts})
	if err != nil {
		panic(err)
	}
}

func (cmd CmdSnapshots) Usage() string {
	return ""
}

func (cmd CmdSnapshots) Execute(args []string) error {
	if len(args) != 0 {
		return fmt.Errorf("wrong number of arguments, usage: %s", cmd.Usage())
	}

	repo, err := cmd.global.OpenRepository()
	if err != nil {
		return err
	}

	lock, err := lockRepo(repo)
	defer unlockRepo(lock)
	if err != nil {
		return err
	}

	tab := NewTable()
	tab.Header = fmt.Sprintf("%-8s  %-19s  %-10s  %s", "ID", "Date", "Source", "Directory")
	tab.RowFormat = "%-8s  %-19s  %-10s  %s"

	done := make(chan struct{})
	defer close(done)

	list := []*restic.Snapshot{}
	for id := range repo.List(backend.Snapshot, done) {
		sn, err := restic.LoadSnapshot(repo, id)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error loading snapshot %s: %v\n", id, err)
			continue
		}

		pos := sort.Search(len(list), func(i int) bool {
			return list[i].Time.After(sn.Time)
		})

		if pos < len(list) {
			list = append(list, nil)
			copy(list[pos+1:], list[pos:])
			list[pos] = sn
		} else {
			list = append(list, sn)
		}
	}

	plen, err := repo.PrefixLength(backend.Snapshot)
	if err != nil {
		return err
	}

	for _, sn := range list {
		if len(sn.Paths) == 0 {
			continue
		}
		tab.Rows = append(tab.Rows, []interface{}{sn.ID()[:plen/2], sn.Time.Format(TimeFormat), sn.Hostname, sn.Paths[0]})

		if len(sn.Paths) > 1 {
			for _, path := range sn.Paths {
				tab.Rows = append(tab.Rows, []interface{}{"", "", "", path})
			}
		}
	}

	tab.Write(os.Stdout)

	return nil
}
<commit_msg>Command `snapshots`: do not list first dir twice<commit_after>package main

import (
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"time"

	"github.com/restic/restic"
	"github.com/restic/restic/backend"
)

const (
	minute = 60
	hour   = 60 * minute
	day    = 24 * hour
	week   = 7 * day
)

type Table struct {
	Header string
	Rows   [][]interface{}

	RowFormat string
}

func NewTable() Table {
	return Table{
		Rows: [][]interface{}{},
	}
}

func (t Table) Write(w io.Writer) error {
	_, err := fmt.Fprintln(w, t.Header)
	if err != nil {
		return err
	}
	_, err = fmt.Fprintln(w, strings.Repeat("-", 70))
	if err != nil {
		return err
	}

	for _, row := range t.Rows {
		_, err = fmt.Fprintf(w, t.RowFormat+"\n", row...)
		if err != nil {
			return err
		}
	}

	return nil
}

const TimeFormat = "2006-01-02 15:04:05"

func reltime(t time.Time) string {
	sec := uint64(time.Since(t).Seconds())

	switch {
	case sec > week:
		return t.Format(TimeFormat)
	case sec > day:
		return fmt.Sprintf("%d days ago", sec/day)
	case sec > hour:
		return fmt.Sprintf("%d hours ago", sec/hour)
	case sec > minute:
		return fmt.Sprintf("%d minutes ago", sec/minute)
	default:
		return fmt.Sprintf("%d seconds ago", sec)
	}
}

type CmdSnapshots struct {
	global *GlobalOptions
}

func init() {
	_, err := parser.AddCommand("snapshots",
		"show snapshots",
		"The snapshots command lists all snapshots stored in a repository",
		&CmdSnapshots{global: &globalOpts})
	if err != nil {
		panic(err)
	}
}

func (cmd CmdSnapshots) Usage() string {
	return ""
}

func (cmd CmdSnapshots) Execute(args []string) error {
	if len(args) != 0 {
		return fmt.Errorf("wrong number of arguments, usage: %s", cmd.Usage())
	}

	repo, err := cmd.global.OpenRepository()
	if err != nil {
		return err
	}

	lock, err := lockRepo(repo)
	defer unlockRepo(lock)
	if err != nil {
		return err
	}

	tab := NewTable()
	tab.Header = fmt.Sprintf("%-8s  %-19s  %-10s  %s", "ID", "Date", "Source", "Directory")
	tab.RowFormat = "%-8s  %-19s  %-10s  %s"

	done := make(chan struct{})
	defer close(done)

	list := []*restic.Snapshot{}
	for id := range repo.List(backend.Snapshot, done) {
		sn, err := restic.LoadSnapshot(repo, id)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error loading snapshot %s: %v\n", id, err)
			continue
		}

		pos := sort.Search(len(list), func(i int) bool {
			return list[i].Time.After(sn.Time)
		})

		if pos < len(list) {
			list = append(list, nil)
			copy(list[pos+1:], list[pos:])
			list[pos] = sn
		} else {
			list = append(list, sn)
		}
	}

	plen, err := repo.PrefixLength(backend.Snapshot)
	if err != nil {
		return err
	}

	for _, sn := range list {
		if len(sn.Paths) == 0 {
			continue
		}
		tab.Rows = append(tab.Rows, []interface{}{sn.ID()[:plen/2], sn.Time.Format(TimeFormat), sn.Hostname, sn.Paths[0]})

		if len(sn.Paths) > 1 {
			for _, path := range sn.Paths[1:] {
				tab.Rows = append(tab.Rows, []interface{}{"", "", "", path})
			}
		}
	}

	tab.Write(os.Stdout)

	return nil
}
<|endoftext|>


<commit_before>package sentry

import (
	"errors"
	"log"
	"strings"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/jianyuan/go-sentry/sentry"
)

func resourceSentryProject() *schema.Resource {
	return &schema.Resource{
		Create: resourceSentryProjectCreate,
		Read:   resourceSentryProjectRead,
		Update: resourceSentryProjectUpdate,
		Delete: resourceSentryProjectDelete,
		Importer: &schema.ResourceImporter{
			State: resourceSentryProjectImporter,
		},

		Schema: map[string]*schema.Schema{
			"organization": {
				Type:        schema.TypeString,
				Required:    true,
				Description: "The slug of the organization the project belongs to",
			},
			"team": {
				Type:        schema.TypeString,
				Required:    true,
				Description: "The slug of the team to create the project for",
			},
			"name": {
				Type:        schema.TypeString,
				Required:    true,
				Description: "The name for the project",
			},
			"slug": {
				Type:        schema.TypeString,
				Optional:    true,
				Description: "The optional slug for this project",
				Computed:    true,
			},
			"project_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"is_public": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"is_bookmarked": {
				Type:       schema.TypeBool,
				Computed:   true,
				Deprecated: "is_bookmarked is no longer used",
			},
			"call_sign": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"color": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"features": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			},
			"status": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"digests_min_delay": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"digests_max_delay": {
				Type:     schema.TypeInt,
				Computed: true,
			},

			// TODO: Project options
		},
	}
}

func resourceSentryProjectCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	org := d.Get("organization").(string)
	team := d.Get("team").(string)
	params := &sentry.CreateProjectParams{
		Name: d.Get("name").(string),
		Slug: d.Get("slug").(string),
	}

	proj, _, err := client.Projects.Create(org, team, params)
	if err != nil {
		return err
	}

	d.SetId(proj.Slug)
	return resourceSentryProjectRead(d, meta)
}

func resourceSentryProjectRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	slug := d.Id()
	org := d.Get("organization").(string)

	proj, _, err := client.Projects.Get(org, slug)
	if err != nil {
		d.SetId("")
		return nil
	}

	d.SetId(proj.Slug)
	d.Set("organization", proj.Organization.Slug)
	d.Set("team", proj.Team.Slug)
	d.Set("name", proj.Name)
	d.Set("slug", proj.Slug)
	d.Set("project_id", proj.ID)
	d.Set("is_public", proj.IsPublic)
	d.Set("call_sign", proj.CallSign)
	d.Set("color", proj.Color)
	d.Set("features", proj.Features)
	d.Set("status", proj.Status)
	d.Set("digests_min_delay", proj.DigestsMinDelay)
	d.Set("digests_max_delay", proj.DigestsMaxDelay)

	// TODO: Project options

	return nil
}

func resourceSentryProjectUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	slug := d.Id()
	org := d.Get("organization").(string)
	params := &sentry.UpdateProjectParams{
		Name: d.Get("name").(string),
		Slug: d.Get("slug").(string),
	}

	if v, ok := d.GetOk("digests_min_delay"); ok {
		params.DigestsMinDelay = Int(v.(int))
	}

	if v, ok := d.GetOk("digests_max_delay"); ok {
		params.DigestsMaxDelay = Int(v.(int))
	}

	proj, _, err := client.Projects.Update(org, slug, params)
	if err != nil {
		return err
	}

	d.SetId(proj.Slug)
	return resourceSentryProjectRead(d, meta)
}

func resourceSentryProjectDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	slug := d.Id()
	org := d.Get("organization").(string)

	_, err := client.Projects.Delete(org, slug)
	return err
}

func resourceSentryProjectImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	addrID := d.Id()

	log.Printf("[DEBUG] Importing key using ADDR ID %s", addrID)

	parts := strings.Split(addrID, "/")

	if len(parts) != 2 {
		return nil, errors.New("Project import requires an ADDR ID of the following schema org-slug/team-slug")
	}

	d.Set("organization", parts[0])
	d.SetId(parts[1])

	return []*schema.ResourceData{d}, nil
}
<commit_msg>Remove project call sign<commit_after>package sentry

import (
	"errors"
	"log"
	"strings"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/jianyuan/go-sentry/sentry"
)

func resourceSentryProject() *schema.Resource {
	return &schema.Resource{
		Create: resourceSentryProjectCreate,
		Read:   resourceSentryProjectRead,
		Update: resourceSentryProjectUpdate,
		Delete: resourceSentryProjectDelete,
		Importer: &schema.ResourceImporter{
			State: resourceSentryProjectImporter,
		},

		Schema: map[string]*schema.Schema{
			"organization": {
				Type:        schema.TypeString,
				Required:    true,
				Description: "The slug of the organization the project belongs to",
			},
			"team": {
				Type:        schema.TypeString,
				Required:    true,
				Description: "The slug of the team to create the project for",
			},
			"name": {
				Type:        schema.TypeString,
				Required:    true,
				Description: "The name for the project",
			},
			"slug": {
				Type:        schema.TypeString,
				Optional:    true,
				Description: "The optional slug for this project",
				Computed:    true,
			},
			"project_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"is_public": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"is_bookmarked": {
				Type:       schema.TypeBool,
				Computed:   true,
				Deprecated: "is_bookmarked is no longer used",
			},
			"color": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"features": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			},
			"status": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"digests_min_delay": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"digests_max_delay": {
				Type:     schema.TypeInt,
				Computed: true,
			},

			// TODO: Project options
		},
	}
}

func resourceSentryProjectCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	org := d.Get("organization").(string)
	team := d.Get("team").(string)
	params := &sentry.CreateProjectParams{
		Name: d.Get("name").(string),
		Slug: d.Get("slug").(string),
	}

	proj, _, err := client.Projects.Create(org, team, params)
	if err != nil {
		return err
	}

	d.SetId(proj.Slug)
	return resourceSentryProjectRead(d, meta)
}

func resourceSentryProjectRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	slug := d.Id()
	org := d.Get("organization").(string)

	proj, _, err := client.Projects.Get(org, slug)
	if err != nil {
		d.SetId("")
		return nil
	}

	d.SetId(proj.Slug)
	d.Set("organization", proj.Organization.Slug)
	d.Set("team", proj.Team.Slug)
	d.Set("name", proj.Name)
	d.Set("slug", proj.Slug)
	d.Set("project_id", proj.ID)
	d.Set("is_public", proj.IsPublic)
	d.Set("color", proj.Color)
	d.Set("features", proj.Features)
	d.Set("status", proj.Status)
	d.Set("digests_min_delay", proj.DigestsMinDelay)
	d.Set("digests_max_delay", proj.DigestsMaxDelay)

	// TODO: Project options

	return nil
}

func resourceSentryProjectUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	slug := d.Id()
	org := d.Get("organization").(string)
	params := &sentry.UpdateProjectParams{
		Name: d.Get("name").(string),
		Slug: d.Get("slug").(string),
	}

	if v, ok := d.GetOk("digests_min_delay"); ok {
		params.DigestsMinDelay = Int(v.(int))
	}

	if v, ok := d.GetOk("digests_max_delay"); ok {
		params.DigestsMaxDelay = Int(v.(int))
	}

	proj, _, err := client.Projects.Update(org, slug, params)
	if err != nil {
		return err
	}

	d.SetId(proj.Slug)
	return resourceSentryProjectRead(d, meta)
}

func resourceSentryProjectDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*sentry.Client)

	slug := d.Id()
	org := d.Get("organization").(string)

	_, err := client.Projects.Delete(org, slug)
	return err
}

func resourceSentryProjectImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	addrID := d.Id()

	log.Printf("[DEBUG] Importing key using ADDR ID %s", addrID)

	parts := strings.Split(addrID, "/")

	if len(parts) != 2 {
		return nil, errors.New("Project import requires an ADDR ID of the following schema org-slug/team-slug")
	}

	d.Set("organization", parts[0])
	d.SetId(parts[1])

	return []*schema.ResourceData{d}, nil
}
<|endoftext|>


<commit_before>package ts3sqlib

import (
	"strconv"
	"strings"
)

//Client hold all information for a client from the clientlist command.
type Client struct {
	Cid              int    `json:"-"`
	Clid             int    `json:"clid"`
	ClientDatabaseID int    `json:"-"`
	ClientNickname   string `json:"client_nickname"`
	ClientType       int    `json:"client_type"`
}

//NewClient creates a Client datastructure from a map of strings
func NewClient(cmap map[string]string) Client {
	var newC Client

	newC.Cid, _ = strconv.Atoi(cmap["cid"])
	newC.Clid, _ = strconv.Atoi(cmap["clid"])
	newC.ClientDatabaseID, _ = strconv.Atoi(cmap["client_database_id"])
	newC.ClientNickname = cmap["client_nickname"]
	newC.ClientType, _ = strconv.Atoi(cmap["client_type"])

	return newC
}

//ClientmapsToClients converts an array of string maps to an array of Client's.
func ClientmapsToClients(clientmaps []map[string]string) (clients []Client, err error) {
	clients = make([]Client, len(clientmaps))

	for i, clientmap := range clientmaps {
		clients[i] = NewClient(clientmap)
	}

	return
}

//ClientlistToClients gets the clientlist from the ts3 server and returns it as
//a slice of Client's.
//The params are described in the TS3 ServerQuery Manual.
func (c *SqConn) ClientlistToClients(params string) (clients []Client, err error) {
	clientmaps, err := c.ClientlistToMaps(params)
	if err != nil {
		return
	}

	clients, err = ClientmapsToClients(clientmaps)
	return
}

//ClientlistToMaps gets the clientlist from the ts3 server and returns it as
//a slice of maps.
//The params are described in the TS3 ServerQuery Manual.
func (c *SqConn) ClientlistToMaps(params string) (clients []map[string]string, err error) {
	answer, err := c.Send("clientlist " + params + "\n")
	if err != nil {
		return
	}

	clients, err = MsgToMaps(answer)
	return
}

//MsgToMaps converts a given ts3 serverquery answer into a slice of maps,
//with key-value-pairs seperated by a '='.
func MsgToMaps(msg string) (parts []map[string]string, err error) {
	lines := strings.Split(msg, "|")
	parts = make([]map[string]string, len(lines))

	for i := range lines {
		parts[i], err = MsgToMap(lines[i])
		if err != nil {
			return
		}
	}

	return
}

//MsgToMap converts a given ts3 serverquery answer into a map of
//key-value-pairs seperated by a '='.
func MsgToMap(msg string) (part map[string]string, err error) {
	part = make(map[string]string)

	msg = strings.Replace(msg, "\n", "", -1)
	pairs := strings.Split(msg, " ")

	for j := range pairs {
		pair := strings.Split(pairs[j], "=")
		if len(pair) != 2 {
			continue
		}
		part[pair[0]] = Unescape(pair[1])
	}

	return
}

//SendToMap combines a Send and a MsgToMap.
func (c *SqConn) SendToMap(msg string) (pairs map[string]string, err error) {
	answer, err := c.Send(msg)
	if err != nil {
		return
	}

	pairs, err = MsgToMap(answer)

	return
}

//SendToMaps combines a Send and a MsgToMaps.
func (c *SqConn) SendToMaps(msg string) (parts []map[string]string, err error) {
	answer, err := c.Send(msg)
	if err != nil {
		return
	}

	parts, err = MsgToMaps(answer)

	return
}
<commit_msg>adding ConnectionConnectedTime<commit_after>package ts3sqlib

import (
	"fmt"
	"strconv"
	"strings"
)

//Client hold all information for a client from the clientlist command.
type Client struct {
	Cid                     int    `json:"-"`
	Clid                    int    `json:"clid"`
	ClientDatabaseID        int    `json:"-"`
	ClientNickname          string `json:"client_nickname"`
	ClientType              int    `json:"client_type"`
	ConnectionConnectedTime int    `json:"connection_connected_time"`
}

//NewClient creates a Client datastructure from a map of strings
func NewClient(cmap map[string]string) Client {
	var newC Client

	newC.Cid, _ = strconv.Atoi(cmap["cid"])
	newC.Clid, _ = strconv.Atoi(cmap["clid"])
	newC.ClientDatabaseID, _ = strconv.Atoi(cmap["client_database_id"])
	newC.ClientNickname = cmap["client_nickname"]
	newC.ClientType, _ = strconv.Atoi(cmap["client_type"])

	newC.ConnectionConnectedTime = 0

	return newC
}

//ClientmapsToClients converts an array of string maps to an array of Client's.
func ClientmapsToClients(clientmaps []map[string]string) (clients []Client, err error) {
	clients = make([]Client, len(clientmaps))

	for i, clientmap := range clientmaps {
		clients[i] = NewClient(clientmap)
	}

	return
}

//ClientlistToClients gets the clientlist from the ts3 server and returns it as
//a slice of Client's.
//The params are described in the TS3 ServerQuery Manual.
func (c *SqConn) ClientlistToClients(params string) (clients []Client, err error) {
	clientmaps, err := c.ClientlistToMaps(params)
	if err != nil {
		return
	}

	clients, err = ClientmapsToClients(clientmaps)
	return
}

//ClientlistToMaps gets the clientlist from the ts3 server and returns it as
//a slice of maps.
//The params are described in the TS3 ServerQuery Manual.
func (c *SqConn) ClientlistToMaps(params string) (clients []map[string]string, err error) {
	answer, err := c.Send("clientlist " + params + "\n")
	if err != nil {
		return
	}

	clients, err = MsgToMaps(answer)
	return
}

//MsgToMaps converts a given ts3 serverquery answer into a slice of maps,
//with key-value-pairs seperated by a '='.
func MsgToMaps(msg string) (parts []map[string]string, err error) {
	lines := strings.Split(msg, "|")
	parts = make([]map[string]string, len(lines))

	for i := range lines {
		parts[i], err = MsgToMap(lines[i])
		if err != nil {
			return
		}
	}

	return
}

//MsgToMap converts a given ts3 serverquery answer into a map of
//key-value-pairs seperated by a '='.
func MsgToMap(msg string) (part map[string]string, err error) {
	part = make(map[string]string)

	msg = strings.Replace(msg, "\n", "", -1)
	pairs := strings.Split(msg, " ")

	for j := range pairs {
		pair := strings.Split(pairs[j], "=")
		if len(pair) != 2 {
			continue
		}
		part[pair[0]] = Unescape(pair[1])
	}

	return
}

//SendToMap combines a Send and a MsgToMap.
func (c *SqConn) SendToMap(msg string) (pairs map[string]string, err error) {
	answer, err := c.Send(msg)
	if err != nil {
		return
	}

	pairs, err = MsgToMap(answer)

	return
}

//SendToMaps combines a Send and a MsgToMaps.
func (c *SqConn) SendToMaps(msg string) (parts []map[string]string, err error) {
	answer, err := c.Send(msg)
	if err != nil {
		return
	}

	parts, err = MsgToMaps(answer)

	return
}

func (c *SqConn) GetConnectionTimeForCL(clientlist []Client) (clients []Client, err error) {
	for i := range clientlist {
		msg := fmt.Sprint("clientinfo clid=", clients[i].Clid)
		answer, err := c.SendToMap(msg)
		if err != nil {
			break
		}
		fmt.Println(msg)
		s := answer["connection_connected_time"]
		clients[i].ConnectionConnectedTime, _ = strconv.Atoi(s)
	}
	return clientlist, err
}
<|endoftext|>


<commit_before>package gitsync

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/checkr/codeflow/server/agent"
	"github.com/checkr/codeflow/server/plugins"
	log "github.com/codeamp/logger"
	"github.com/spf13/viper"
)

type GitSync struct {
	events chan agent.Event
	idRsa  string
}

func init() {
	agent.RegisterPlugin("gitsync", func() agent.Plugin {
		return &GitSync{}
	})
}

func (x *GitSync) Description() string {
	return "Sync Git repositories and create new features"
}

func (x *GitSync) SampleConfig() string {
	return ` `
}

func (x *GitSync) Start(e chan agent.Event) error {
	x.events = e
	log.Info("Started GitSync")

	return nil
}

func (x *GitSync) Stop() {
	log.Println("Stopping GitSync")
}

func (x *GitSync) Subscribe() []string {
	return []string{
		"plugins.GitPing",
		"plugins.GitSync:update",
	}
}

func (x *GitSync) git(args ...string) ([]byte, error) {
	cmd := exec.Command("git", args...)
	env := os.Environ()
	env = append(env, x.idRsa)
	cmd.Env = env

	log.InfoWithFields("executing command", log.Fields{
		"path": cmd.Path,
		"args": strings.Join(cmd.Args, " "),
	})

	out, err := cmd.CombinedOutput()

	if err != nil {
		if ee, ok := err.(*exec.Error); ok {
			if ee.Err == exec.ErrNotFound {
				return nil, errors.New("Git executable not found in $PATH")
			}
		}

		return nil, errors.New(string(bytes.TrimSpace(out)))
	}

	return out, nil
}

func (x *GitSync) toGitCommit(entry string) (plugins.GitCommit, error) {
	items := strings.Split(entry, "#@#")
	commiterDate, err := time.Parse("2006-01-02T15:04:05-07:00", items[4])

	if err != nil {
		return plugins.GitCommit{}, err
	}

	return plugins.GitCommit{
		Hash:       items[0],
		ParentHash: items[1],
		Message:    items[2],
		User:       items[3],
		Created:    commiterDate,
	}, nil
}

func (x *GitSync) commits(project plugins.Project, git plugins.Git) ([]plugins.GitCommit, error) {
	var err error
	var output []byte

	idRsaPath := fmt.Sprintf("%s/%s_id_rsa", viper.GetString("plugins.gitsync.workdir"), project.Repository)
	x.idRsa = fmt.Sprintf("GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=no -i %s -F /dev/null", idRsaPath)
	repoPath := fmt.Sprintf("%s/%s_%s", viper.GetString("plugins.gitsync.workdir"), project.Repository, git.Branch)

	output, err = exec.Command("mkdir", "-p", filepath.Dir(repoPath)).CombinedOutput()
	if err != nil {
		return nil, err
	}
	log.Info(string(output))

	if _, err = os.Stat(idRsaPath); err != nil {
		if os.IsNotExist(err) {
			err = ioutil.WriteFile(idRsaPath, []byte(git.RsaPrivateKey), 0600)
			if err != nil {
				return nil, err
			}
		}
	}

	if _, err = os.Stat(fmt.Sprintf("%s", repoPath)); err != nil {
		if os.IsNotExist(err) {
			output, err = x.git("clone", git.Url, repoPath)
			if err != nil {
				return nil, err
			}
			log.Info(string(output))
		}
		return nil, err
	} else {
		output, err = x.git("-C", repoPath, "pull", "origin", git.Branch)
		if err != nil {
			return nil, err
		}
		log.Info(string(output))
	}

	output, err = x.git("-C", repoPath, "checkout", git.Branch)
	if err != nil {
		return nil, err
	}
	log.Info(string(output))

	output, err = x.git("-C", repoPath, "log", "--first-parent", "--date=iso-strict", "-n", "50", "--pretty=format:%H#@#%P#@#%s#@#%cN#@#%cd", git.Branch)

	if err != nil {
		return nil, err
	}

	var commits []plugins.GitCommit

	for _, line := range strings.Split(strings.TrimSuffix(string(output), "\n"), "\n") {
		commit, err := x.toGitCommit(line)
		if err != nil {
			return nil, err
		}

		commits = append(commits, commit)
	}

	return commits, nil
}

func (x *GitSync) Process(e agent.Event) error {
	log.InfoWithFields("Process GitSync event", log.Fields{
		"event": e.Name,
	})

	var err error

	gitSyncEvent := e.Payload.(plugins.GitSync)
	gitSyncEvent.Action = plugins.Status
	gitSyncEvent.State = plugins.Fetching
	gitSyncEvent.StateMessage = ""
	x.events <- e.NewEvent(gitSyncEvent, nil)

	commits, err := x.commits(gitSyncEvent.Project, gitSyncEvent.Git)
	if err != nil {
		log.Error(err)
		gitSyncEvent.State = plugins.Failed
		gitSyncEvent.StateMessage = fmt.Sprintf("%v (Action: %v)", err.Error(), gitSyncEvent.State)
		event := e.NewEvent(gitSyncEvent, err)
		x.events <- event
		return err
	}

	for i := range commits {
		c := commits[i]
		c.Repository = gitSyncEvent.Project.Repository
		c.Ref = fmt.Sprintf("refs/heads/%s", gitSyncEvent.Git.Branch)

		if c.Hash == gitSyncEvent.From {
			break
		}

		x.events <- e.NewEvent(c, nil)
	}

	gitSyncEvent.State = plugins.Complete
	gitSyncEvent.StateMessage = ""
	x.events <- e.NewEvent(gitSyncEvent, nil)

	return nil
}
<commit_msg>small GitSync refactor (#174)<commit_after>package gitsync

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/checkr/codeflow/server/agent"
	"github.com/checkr/codeflow/server/plugins"
	log "github.com/codeamp/logger"
	"github.com/spf13/viper"
)

type GitSync struct {
	events chan agent.Event
	idRsa  string
}

func init() {
	agent.RegisterPlugin("gitsync", func() agent.Plugin {
		return &GitSync{}
	})
}

func (x *GitSync) Description() string {
	return "Sync Git repositories and create new features"
}

func (x *GitSync) SampleConfig() string {
	return ` `
}

func (x *GitSync) Start(e chan agent.Event) error {
	x.events = e
	log.Info("Started GitSync")

	return nil
}

func (x *GitSync) Stop() {
	log.Println("Stopping GitSync")
}

func (x *GitSync) Subscribe() []string {
	return []string{
		"plugins.GitPing",
		"plugins.GitSync:update",
	}
}

func (x *GitSync) git(args ...string) ([]byte, error) {
	cmd := exec.Command("git", args...)
	env := os.Environ()
	env = append(env, x.idRsa)
	cmd.Env = env

	log.InfoWithFields("executing command", log.Fields{
		"path": cmd.Path,
		"args": strings.Join(cmd.Args, " "),
	})

	out, err := cmd.CombinedOutput()

	if err != nil {
		if ee, ok := err.(*exec.Error); ok {
			if ee.Err == exec.ErrNotFound {
				return nil, errors.New("Git executable not found in $PATH")
			}
		}

		return nil, errors.New(string(bytes.TrimSpace(out)))
	}

	return out, nil
}

func (x *GitSync) toGitCommit(entry string) (plugins.GitCommit, error) {
	items := strings.Split(entry, "#@#")
	commiterDate, err := time.Parse("2006-01-02T15:04:05-07:00", items[4])

	if err != nil {
		return plugins.GitCommit{}, err
	}

	return plugins.GitCommit{
		Hash:       items[0],
		ParentHash: items[1],
		Message:    items[2],
		User:       items[3],
		Created:    commiterDate,
	}, nil
}

func (x *GitSync) commits(project plugins.Project, git plugins.Git) ([]plugins.GitCommit, error) {
	var err error
	var output []byte

	idRsaPath := fmt.Sprintf("%s/%s_id_rsa", viper.GetString("plugins.gitsync.workdir"), project.Repository)
	x.idRsa = fmt.Sprintf("GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=no -i %s -F /dev/null", idRsaPath)
	repoPath := fmt.Sprintf("%s/%s_%s", viper.GetString("plugins.gitsync.workdir"), project.Repository, git.Branch)

	_, err = exec.Command("mkdir", "-p", filepath.Dir(repoPath)).CombinedOutput()
	if err != nil {
		return nil, err
	}

	if _, err := os.Stat(idRsaPath); os.IsNotExist(err) {
		log.InfoWithFields("creating repository id_rsa", log.Fields{
			"path": idRsaPath,
		})

		err := ioutil.WriteFile(idRsaPath, []byte(git.RsaPrivateKey), 0600)
		if err != nil {
			log.Debug(err)
			return nil, err
		}
	}

	if _, err := os.Stat(repoPath); os.IsNotExist(err) {
		log.InfoWithFields("cloning repository", log.Fields{
			"path": repoPath,
		})

		output, err := x.git("clone", git.Url, repoPath)
		if err != nil {
			log.Debug(err)
			return nil, err
		}
		log.Info(string(output))
	}

	output, err = x.git("-C", repoPath, "pull", "origin", git.Branch)
	if err != nil {
		log.Debug(err)
		return nil, err
	}
	log.Info(string(output))

	output, err = x.git("-C", repoPath, "checkout", git.Branch)
	if err != nil {
		log.Debug(err)
		return nil, err
	}
	log.Info(string(output))

	output, err = x.git("-C", repoPath, "log", "--first-parent", "--date=iso-strict", "-n", "50", "--pretty=format:%H#@#%P#@#%s#@#%cN#@#%cd", git.Branch)

	if err != nil {
		log.Debug(err)
		return nil, err
	}

	var commits []plugins.GitCommit

	for _, line := range strings.Split(strings.TrimSuffix(string(output), "\n"), "\n") {
		commit, err := x.toGitCommit(line)
		if err != nil {
			log.Debug(err)
			return nil, err
		}

		commits = append(commits, commit)
	}

	return commits, nil
}

func (x *GitSync) Process(e agent.Event) error {
	log.InfoWithFields("Process GitSync event", log.Fields{
		"event": e.Name,
	})

	var err error

	gitSyncEvent := e.Payload.(plugins.GitSync)
	gitSyncEvent.Action = plugins.Status
	gitSyncEvent.State = plugins.Fetching
	gitSyncEvent.StateMessage = ""
	x.events <- e.NewEvent(gitSyncEvent, nil)

	commits, err := x.commits(gitSyncEvent.Project, gitSyncEvent.Git)
	if err != nil {
		log.Error(err)
		gitSyncEvent.State = plugins.Failed
		gitSyncEvent.StateMessage = fmt.Sprintf("%v (Action: %v)", err.Error(), gitSyncEvent.State)
		event := e.NewEvent(gitSyncEvent, err)
		x.events <- event
		return err
	}

	for i := range commits {
		c := commits[i]
		c.Repository = gitSyncEvent.Project.Repository
		c.Ref = fmt.Sprintf("refs/heads/%s", gitSyncEvent.Git.Branch)

		if c.Hash == gitSyncEvent.From {
			break
		}

		x.events <- e.NewEvent(c, nil)
	}

	gitSyncEvent.State = plugins.Complete
	gitSyncEvent.StateMessage = ""
	x.events <- e.NewEvent(gitSyncEvent, nil)

	return nil
}
<|endoftext|>


<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 ledger

import (
	"bytes"
	"reflect"
	"testing"

	"github.com/openblockchain/obc-peer/openchain/db"
	"github.com/openblockchain/obc-peer/openchain/util"
	"github.com/tecbot/gorocksdb"
)

func TestStateDeltaMarshalling(t *testing.T) {
	stateDelta := createTestStateDelta()
	by := stateDelta.marshal()
	t.Logf("length of marshalled bytes = [%d]", len(by))
	stateDelta1 := newStateDelta()
	stateDelta1.unmarshal(by)

	if !reflect.DeepEqual(stateDelta, stateDelta1) {
		t.Fatalf("Delta state not same. Found=[%s], Expected=[%s]", stateDelta1, stateDelta)
	}
}

func TestStateDeltaPersistence(t *testing.T) {
	initTestDB(t)
	historyStateDeltaSize = 2
	state := getState()
	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key1", []byte("value1"))
	state.set("chaincode2", "key2", []byte("value2"))
	state.txFinish("txUuid", true)
	commitTestState(t, 0)

	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key3", []byte("value3"))
	state.set("chaincode2", "key4", []byte("value4"))
	state.txFinish("txUuid", true)
	commitTestState(t, 1)

	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key5", []byte("value5"))
	state.set("chaincode2", "key6", []byte("value6"))
	state.txFinish("txUuid", true)
	commitTestState(t, 2)

	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key7", []byte("value7"))
	state.set("chaincode2", "key8", []byte("value8"))
	state.txFinish("txUuid", true)
	commitTestState(t, 3)

	// state delta for block# 3
	stateDelta := fetchTestStateDeltaFromDB(t, 3)
	if bytes.Compare(stateDelta.get("chaincode1", "key7").value, []byte("value7")) != 0 {
		t.Fatalf("wrong value found in state delta = [%s]", string(stateDelta.get("chaincode1", "key7").value))
	}

	if stateDelta.get("chaincode1", "key5") != nil {
		t.Fatalf("wrong value found in state delta = [%s]", string(stateDelta.get("chaincode1", "key5").value))
	}

	// state delta for block# 2
	stateDelta = fetchTestStateDeltaFromDB(t, 2)
	if bytes.Compare(stateDelta.get("chaincode1", "key5").value, []byte("value5")) != 0 {
		t.Fatalf("wrong value found in state delta = [%s]", string(stateDelta.get("chaincode1", "key5").value))
	}

	// state delta for block# 1
	stateDelta = fetchTestStateDeltaFromDB(t, 1)
	if stateDelta != nil {
		t.Fatalf("state delta should be nil because historyStateDeltaSize is set to 2")
	}

	// state delta for block# 0
	stateDelta = fetchTestStateDeltaFromDB(t, 0)
	if stateDelta != nil {
		t.Fatalf("state delta should be nil because historyStateDeltaSize is set to 2")
	}
}

func TestStateDeltaCryptoHash(t *testing.T) {
	stateDelta := newStateDelta()

	stateDelta.set("chaincodeID1", "key2", []byte("value2"))
	stateDelta.set("chaincodeID1", "key1", []byte("value1"))
	stateDelta.set("chaincodeID2", "key2", []byte("value2"))
	stateDelta.set("chaincodeID2", "key1", []byte("value1"))
	checkStateDeltaHash(t, "chaincodeID1key1value1key2value2chaincodeID2key1value1key2value2", stateDelta.computeCryptoHash())

	stateDelta.delete("chaincodeID2", "key1")
	checkStateDeltaHash(t, "chaincodeID1key1value1key2value2chaincodeID2key1key2value2", stateDelta.computeCryptoHash())
}

func checkStateDeltaHash(t *testing.T, expectedContent string, actualHash []byte) {
	if expectedContent == "" && actualHash == nil {
		return
	}
	expectedHash := util.ComputeCryptoHash([]byte(expectedContent))
	if !bytes.Equal(actualHash, expectedHash) {
		t.Fatalf("stateDelta hashes not same. Expected content = %#v", expectedContent)
	}
}

func commitTestState(t *testing.T, blockNumber uint64) {
	writeBatch := gorocksdb.NewWriteBatch()
	opts := gorocksdb.NewDefaultWriteOptions()

	_, err := getState().getHash()
	if err != nil {
		t.Fatalf("error: %s", err)
	}

	getState().addChangesForPersistence(blockNumber, writeBatch)

	err = db.GetDBHandle().DB.Write(opts, writeBatch)
	if err != nil {
		t.Fatalf("error: %s", err)
	}
}

func fetchTestStateDeltaFromDB(t *testing.T, blockNumber uint64) *stateDelta {
	stateDelta, err := fetchStateDeltaFromDB(blockNumber)
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	return stateDelta
}

func createTestStateDelta() *stateDelta {
	stateDelta := newStateDelta()
	stateDelta.set("chaincode1", "key1", []byte("value1"))
	stateDelta.set("chaincode2", "key2", []byte("value2"))
	stateDelta.delete("chaincode3", "key3")
	return stateDelta
}
<commit_msg>Fix state delta test case<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 ledger

import (
	"bytes"
	"reflect"
	"testing"

	"github.com/openblockchain/obc-peer/openchain/db"
	"github.com/openblockchain/obc-peer/openchain/util"
	"github.com/tecbot/gorocksdb"
)

func TestStateDeltaMarshalling(t *testing.T) {
	stateDelta := createTestStateDelta()
	by := stateDelta.Marshal()
	t.Logf("length of marshalled bytes = [%d]", len(by))
	stateDelta1 := newStateDelta()
	stateDelta1.Unmarshal(by)

	if !reflect.DeepEqual(stateDelta, stateDelta1) {
		t.Fatalf("Delta state not same. Found=[%s], Expected=[%s]", stateDelta1, stateDelta)
	}
}

func TestStateDeltaPersistence(t *testing.T) {
	initTestDB(t)
	historyStateDeltaSize = 2
	state := getState()
	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key1", []byte("value1"))
	state.set("chaincode2", "key2", []byte("value2"))
	state.txFinish("txUuid", true)
	commitTestState(t, 0)

	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key3", []byte("value3"))
	state.set("chaincode2", "key4", []byte("value4"))
	state.txFinish("txUuid", true)
	commitTestState(t, 1)

	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key5", []byte("value5"))
	state.set("chaincode2", "key6", []byte("value6"))
	state.txFinish("txUuid", true)
	commitTestState(t, 2)

	state.clearInMemoryChanges()
	state.txBegin("txUuid")
	state.set("chaincode1", "key7", []byte("value7"))
	state.set("chaincode2", "key8", []byte("value8"))
	state.txFinish("txUuid", true)
	commitTestState(t, 3)

	// state delta for block# 3
	stateDelta := fetchTestStateDeltaFromDB(t, 3)
	if bytes.Compare(stateDelta.get("chaincode1", "key7").value, []byte("value7")) != 0 {
		t.Fatalf("wrong value found in state delta = [%s]", string(stateDelta.get("chaincode1", "key7").value))
	}

	if stateDelta.get("chaincode1", "key5") != nil {
		t.Fatalf("wrong value found in state delta = [%s]", string(stateDelta.get("chaincode1", "key5").value))
	}

	// state delta for block# 2
	stateDelta = fetchTestStateDeltaFromDB(t, 2)
	if bytes.Compare(stateDelta.get("chaincode1", "key5").value, []byte("value5")) != 0 {
		t.Fatalf("wrong value found in state delta = [%s]", string(stateDelta.get("chaincode1", "key5").value))
	}

	// state delta for block# 1
	stateDelta = fetchTestStateDeltaFromDB(t, 1)
	if stateDelta != nil {
		t.Fatalf("state delta should be nil because historyStateDeltaSize is set to 2")
	}

	// state delta for block# 0
	stateDelta = fetchTestStateDeltaFromDB(t, 0)
	if stateDelta != nil {
		t.Fatalf("state delta should be nil because historyStateDeltaSize is set to 2")
	}
}

func TestStateDeltaCryptoHash(t *testing.T) {
	stateDelta := newStateDelta()

	stateDelta.set("chaincodeID1", "key2", []byte("value2"))
	stateDelta.set("chaincodeID1", "key1", []byte("value1"))
	stateDelta.set("chaincodeID2", "key2", []byte("value2"))
	stateDelta.set("chaincodeID2", "key1", []byte("value1"))
	checkStateDeltaHash(t, "chaincodeID1key1value1key2value2chaincodeID2key1value1key2value2", stateDelta.computeCryptoHash())

	stateDelta.delete("chaincodeID2", "key1")
	checkStateDeltaHash(t, "chaincodeID1key1value1key2value2chaincodeID2key1key2value2", stateDelta.computeCryptoHash())
}

func checkStateDeltaHash(t *testing.T, expectedContent string, actualHash []byte) {
	if expectedContent == "" && actualHash == nil {
		return
	}
	expectedHash := util.ComputeCryptoHash([]byte(expectedContent))
	if !bytes.Equal(actualHash, expectedHash) {
		t.Fatalf("stateDelta hashes not same. Expected content = %#v", expectedContent)
	}
}

func commitTestState(t *testing.T, blockNumber uint64) {
	writeBatch := gorocksdb.NewWriteBatch()
	opts := gorocksdb.NewDefaultWriteOptions()

	_, err := getState().getHash()
	if err != nil {
		t.Fatalf("error: %s", err)
	}

	getState().addChangesForPersistence(blockNumber, writeBatch)

	err = db.GetDBHandle().DB.Write(opts, writeBatch)
	if err != nil {
		t.Fatalf("error: %s", err)
	}
}

func fetchTestStateDeltaFromDB(t *testing.T, blockNumber uint64) *stateDelta {
	stateDelta, err := fetchStateDeltaFromDB(blockNumber)
	if err != nil {
		t.Fatalf("error: %s", err)
	}
	return stateDelta
}

func createTestStateDelta() *stateDelta {
	stateDelta := newStateDelta()
	stateDelta.set("chaincode1", "key1", []byte("value1"))
	stateDelta.set("chaincode2", "key2", []byte("value2"))
	stateDelta.delete("chaincode3", "key3")
	return stateDelta
}
<|endoftext|>


<commit_before>// 在这里写你的事件

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/ying32/govcl/vcl/types"

	"github.com/ying32/govcl/pkgs/bass"
	"github.com/ying32/govcl/vcl"
)

//::private::
type TForm1Fields struct {
	bassPlayer *bass.TBass
	playCtl    *TPlayControl
	progress   *TImageTrackBar
	volbar     *TImageTrackBar
}

func (f *TForm1) OnFormCreate(sender vcl.IObject) {
	f.SetDoubleBuffered(true)
	f.EnabledMaximize(false)
	//f.SetColor(0x39302c)

	f.playCtl = NewPlayControl(f)
	f.playCtl.SetParent(f.Panel2)
	f.playCtl.SetAlign(types.AlClient)
	f.playCtl.OnSelect = f.OnPlayListSelect
	f.playCtl.SingerPic = vcl.AsBitmap(f.ImgSinger.Picture().Graphic())

	f.progress = NewImageTrackBar(f)
	f.progress.SetParent(f)
	f.progress.SetImages(f.ImgThumb, f.ImgBk, f.ImgFore)
	f.progress.SetLeft(58)
	f.progress.SetTop(288)
	f.progress.SetWidth(200)
	f.progress.SetPosition(0)

	f.volbar = NewImageTrackBar(f)
	f.volbar.SetParent(f)
	f.volbar.SetImages(f.ImgThumb, f.ImgBk, f.ImgFore)
	f.volbar.SetLeft(82)
	f.volbar.SetTop(318)
	f.volbar.SetWidth(80)
	f.volbar.SetPosition(60)
	f.volbar.OnTrackChange = f.OnVolChange

	f.bassPlayer = bass.NewBass()
	// 我的测试
	switch runtime.GOOS {
	case "windows":
		f.addFoler("F:\\KuGou")
	case "darwin":
		usrHome := os.Getenv("HOME")
		f.addFoler(usrHome + "/Music/网易云音乐")
		f.addFoler(usrHome + "/Music/iTunes/iTunes Media/Music")
	case "linux":
		f.addFoler("/home/ying32/音乐")
	}
}

func (f *TForm1) OnFormDestroy(sender vcl.IObject) {

	f.bassPlayer.Close()
	bass.BassFree()
}

func (f *TForm1) OnMIAddFileClick(sender vcl.IObject) {
	if f.OpenDialog1.Execute() {
		f.addFile(f.OpenDialog1.FileName())
	}
}

func (f *TForm1) OnMIAddFolderClick(sender vcl.IObject) {
	if ok, str := vcl.SelectDirectory2("选择目录", "", types.NewSet(types.SdNewUI, types.SdShowEdit), nil); ok {
		f.addFoler(str)
	}
}

func (f *TForm1) addFile(fileName string) {
	name := filepath.Base(fileName)
	if len(name) < 5 {
		return
	}
	nameArr := strings.Split(name[:len(name)-4], "-")
	if len(nameArr) >= 2 {
		lenVal := int32(bass.GetFileLength(fileName))
		f.playCtl.Add(TPlayListItem{strings.TrimSpace(nameArr[1]), strings.TrimSpace(nameArr[0]), lenVal, "", fileName})
	}
}

func (f *TForm1) addFoler(rootPath string) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("addFoler: ", err)
		}
	}()
	_, err := os.Stat(rootPath)
	if os.IsNotExist(err) {
		return
	}
	filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
		ext := filepath.Ext(info.Name())
		if ext == ".mp3" || ext == ".m4a" {
			f.addFile(path)
		}
		return nil
	})
}

func (f *TForm1) OnPlayListSelect(sender vcl.IObject, item TPlayListItem) {
	f.stopPlay()
	f.bassPlayer.Close()
	f.bassPlayer.OpenFile(item.FileName)
	f.bassPlayer.SetVolume(f.volbar.Position())
	f.play()
	str := item.Caption + " - " + item.Singer
	f.SetCaption(str)

}

func (f *TForm1) OnBtnPlayClick(sender vcl.IObject) {
	f.play()
}

func (f *TForm1) OnTimer1Timer(sender vcl.IObject) {
	if f.bassPlayer.IsValid() && f.bassPlayer.State == bass.PsPlaying {

		f.LblTime.SetCaption(f.bassPlayer.TimeStrLabel())
		pos, _ := f.bassPlayer.GetPosition()
		mLen, _ := f.bassPlayer.GetLength()

		if pos >= mLen {
			if f.playCtl.CanNext() {
				f.playCtl.Next()
			} else {
				f.stopPlay()
				f.playCtl.Stop()
			}
		}

		f.progress.SetPosition(int(float32(pos) / float32(mLen) * 100))

		caption := []rune(f.Caption())
		if len(caption) > 0 {
			temp := caption
			c := temp[:1]
			temp = temp[1:]
			f.SetCaption(string(temp) + string(c))
		}
	}
}

func (f *TForm1) OnVolChange(sender vcl.IObject) {
	f.bassPlayer.SetVolume(f.volbar.Position())
}

func (f *TForm1) OnBtnPauseClick(sender vcl.IObject) {
	f.pause()
}

func (f *TForm1) OnBtnMinClick(sender vcl.IObject) {
	vcl.Application.Minimize()
}

func (f *TForm1) OnBtnCloseClick(sender vcl.IObject) {
	vcl.Application.Terminate()
}

func (f *TForm1) stopPlay() {
	f.Timer1.SetEnabled(false)

	f.bassPlayer.Stop()

	f.bassPlayer.SetPosition(0)
	f.progress.SetPosition(0)

	f.BtnPause.Hide()
	f.BtnPlay.Show()

	f.SetCaption("Mp3Player")
}

func (f *TForm1) play() {
	f.bassPlayer.Play(false)

	f.BtnPlay.Hide()
	f.BtnPause.Show()
	f.Timer1.SetEnabled(true)

}

func (f *TForm1) pause() {
	f.bassPlayer.Pause()
	f.BtnPause.Hide()
	f.BtnPlay.Show()
	f.Timer1.SetEnabled(false)

}

func (f *TForm1) OnPanel1MouseDown(sender vcl.IObject, button types.TMouseButton, shift types.TShiftState, x, y int32) {
	if button == types.MbLeft {
		//f.Perform(messages.WM_SYSCOMMAND, message)
	}
}

func (f *TForm1) OnBtnPrevClick(sender vcl.IObject) {
	f.playCtl.Prev()
}

func (f *TForm1) OnBtnNextClick(sender vcl.IObject) {
	f.playCtl.Next()
}
<commit_msg>Fix addFile method of mp3Player example.<commit_after>// 在这里写你的事件

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/ying32/govcl/vcl/types"

	"github.com/ying32/govcl/pkgs/bass"
	"github.com/ying32/govcl/vcl"
)

//::private::
type TForm1Fields struct {
	bassPlayer *bass.TBass
	playCtl    *TPlayControl
	progress   *TImageTrackBar
	volbar     *TImageTrackBar
}

func (f *TForm1) OnFormCreate(sender vcl.IObject) {
	f.SetDoubleBuffered(true)
	f.EnabledMaximize(false)
	//f.SetColor(0x39302c)

	f.playCtl = NewPlayControl(f)
	f.playCtl.SetParent(f.Panel2)
	f.playCtl.SetAlign(types.AlClient)
	f.playCtl.OnSelect = f.OnPlayListSelect
	f.playCtl.SingerPic = vcl.AsBitmap(f.ImgSinger.Picture().Graphic())

	f.progress = NewImageTrackBar(f)
	f.progress.SetParent(f)
	f.progress.SetImages(f.ImgThumb, f.ImgBk, f.ImgFore)
	f.progress.SetLeft(58)
	f.progress.SetTop(288)
	f.progress.SetWidth(200)
	f.progress.SetPosition(0)

	f.volbar = NewImageTrackBar(f)
	f.volbar.SetParent(f)
	f.volbar.SetImages(f.ImgThumb, f.ImgBk, f.ImgFore)
	f.volbar.SetLeft(82)
	f.volbar.SetTop(318)
	f.volbar.SetWidth(80)
	f.volbar.SetPosition(60)
	f.volbar.OnTrackChange = f.OnVolChange

	f.bassPlayer = bass.NewBass()
	// 我的测试
	switch runtime.GOOS {
	case "windows":
		f.addFoler("F:\\KuGou")
	case "darwin":
		usrHome := os.Getenv("HOME")
		f.addFoler(usrHome + "/Music/网易云音乐")
		f.addFoler(usrHome + "/Music/iTunes/iTunes Media/Music")
	case "linux":
		f.addFoler("/home/ying32/音乐")
	}
}

func (f *TForm1) OnFormDestroy(sender vcl.IObject) {

	f.bassPlayer.Close()
	bass.BassFree()
}

func (f *TForm1) OnMIAddFileClick(sender vcl.IObject) {
	if f.OpenDialog1.Execute() {
		f.addFile(f.OpenDialog1.FileName())
	}
}

func (f *TForm1) OnMIAddFolderClick(sender vcl.IObject) {
	if ok, str := vcl.SelectDirectory2("选择目录", "", types.NewSet(types.SdNewUI, types.SdShowEdit), nil); ok {
		f.addFoler(str)
	}
}

func (f *TForm1) addFile(fileName string) {
	name := filepath.Base(fileName)
	ext := strings.ToLower(filepath.Ext(name))
	if ext != ".mp3" && ext != ".m4a" {
		return
	}
	name = name[:len(name)-len(ext)]
	nameArr := strings.Split(name, "-")
	caption := ""
	singer := ""
	if len(nameArr) >= 2 {
		caption = strings.TrimSpace(nameArr[1])
		singer = strings.TrimSpace(nameArr[0])
	} else {
		caption = strings.TrimSpace(name)
		singer = caption
	}

	lenVal := int32(bass.GetFileLength(fileName))
	f.playCtl.Add(TPlayListItem{caption, singer, lenVal, "", fileName})

}

func (f *TForm1) addFoler(rootPath string) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("addFoler: ", err)
		}
	}()
	_, err := os.Stat(rootPath)
	if os.IsNotExist(err) {
		return
	}
	filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
		ext := filepath.Ext(info.Name())
		if ext == ".mp3" || ext == ".m4a" {
			f.addFile(path)
		}
		return nil
	})
}

func (f *TForm1) OnPlayListSelect(sender vcl.IObject, item TPlayListItem) {
	f.stopPlay()
	f.bassPlayer.Close()
	f.bassPlayer.OpenFile(item.FileName)
	f.bassPlayer.SetVolume(f.volbar.Position())
	f.play()
	str := item.Caption + " - " + item.Singer
	f.SetCaption(str)

}

func (f *TForm1) OnBtnPlayClick(sender vcl.IObject) {
	f.play()
}

func (f *TForm1) OnTimer1Timer(sender vcl.IObject) {
	if f.bassPlayer.IsValid() && f.bassPlayer.State == bass.PsPlaying {

		f.LblTime.SetCaption(f.bassPlayer.TimeStrLabel())
		pos, _ := f.bassPlayer.GetPosition()
		mLen, _ := f.bassPlayer.GetLength()

		if pos >= mLen {
			if f.playCtl.CanNext() {
				f.playCtl.Next()
			} else {
				f.stopPlay()
				f.playCtl.Stop()
			}
		}

		f.progress.SetPosition(int(float32(pos) / float32(mLen) * 100))

		caption := []rune(f.Caption())
		if len(caption) > 0 {
			temp := caption
			c := temp[:1]
			temp = temp[1:]
			f.SetCaption(string(temp) + string(c))
		}
	}
}

func (f *TForm1) OnVolChange(sender vcl.IObject) {
	f.bassPlayer.SetVolume(f.volbar.Position())
}

func (f *TForm1) OnBtnPauseClick(sender vcl.IObject) {
	f.pause()
}

func (f *TForm1) OnBtnMinClick(sender vcl.IObject) {
	vcl.Application.Minimize()
}

func (f *TForm1) OnBtnCloseClick(sender vcl.IObject) {
	vcl.Application.Terminate()
}

func (f *TForm1) stopPlay() {
	f.Timer1.SetEnabled(false)

	f.bassPlayer.Stop()

	f.bassPlayer.SetPosition(0)
	f.progress.SetPosition(0)

	f.BtnPause.Hide()
	f.BtnPlay.Show()

	f.SetCaption("Mp3Player")
}

func (f *TForm1) play() {
	f.bassPlayer.Play(false)

	f.BtnPlay.Hide()
	f.BtnPause.Show()
	f.Timer1.SetEnabled(true)

}

func (f *TForm1) pause() {
	f.bassPlayer.Pause()
	f.BtnPause.Hide()
	f.BtnPlay.Show()
	f.Timer1.SetEnabled(false)

}

func (f *TForm1) OnPanel1MouseDown(sender vcl.IObject, button types.TMouseButton, shift types.TShiftState, x, y int32) {
	if button == types.MbLeft {
		//f.Perform(messages.WM_SYSCOMMAND, message)
	}
}

func (f *TForm1) OnBtnPrevClick(sender vcl.IObject) {
	f.playCtl.Prev()
}

func (f *TForm1) OnBtnNextClick(sender vcl.IObject) {
	f.playCtl.Next()
}
<|endoftext|>


<commit_before>package command

import (
	"strings"
	"testing"
)

type testData struct {
	Region string
	ID     string
	Name   string
}

const expectJSON = `{
    "Region": "global",
    "ID": "1",
    "Name": "example"
}`

var (
	tData        = testData{"global", "1", "example"}
	testFormat   = map[string]string{"json": "", "template": "{{.Region}}"}
	expectOutput = map[string]string{"json": expectJSON, "template": "global"}
)

func TestDataFormat(t *testing.T) {
	for k, v := range testFormat {
		fm, err := DataFormat(k, v)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		result, err := fm.TransformData(tData)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if result != expectOutput[k] {
			t.Fatalf("expected output: %s, actual: %s", expectOutput[k], result)
		}
	}
}

func TestInvalidJSONTemplate(t *testing.T) {
	// Invalid template {{.foo}}
	fm, err := DataFormat("template", "{{.foo}}")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	_, err = fm.TransformData(tData)
	if !strings.Contains(err.Error(), "foo is not a field of struct type command.testData") {
		t.Fatalf("expected invalid template error, got: %s", err.Error())
	}

	// No template is specified
	fm, err = DataFormat("template", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	_, err = fm.TransformData(tData)
	if !strings.Contains(err.Error(), "template needs to be specified the golang templates.") {
		t.Fatalf("expected not specified template error, got: %s", err.Error())
	}
}
<commit_msg>fix data format test<commit_after>package command

import (
	"strings"
	"testing"
)

type testData struct {
	Region string
	ID     string
	Name   string
}

const expectJSON = `{
    "Region": "global",
    "ID": "1",
    "Name": "example"
}`

var (
	tData        = testData{"global", "1", "example"}
	testFormat   = map[string]string{"json": "", "template": "{{.Region}}"}
	expectOutput = map[string]string{"json": expectJSON, "template": "global"}
)

func TestDataFormat(t *testing.T) {
	for k, v := range testFormat {
		fm, err := DataFormat(k, v)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		result, err := fm.TransformData(tData)
		if err != nil {
			t.Fatalf("err: %v", err)
		}

		if result != expectOutput[k] {
			t.Fatalf("expected output: %s, actual: %s", expectOutput[k], result)
		}
	}
}

func TestInvalidJSONTemplate(t *testing.T) {
	// Invalid template {{.foo}}
	fm, err := DataFormat("template", "{{.foo}}")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	_, err = fm.TransformData(tData)
	if !strings.Contains(err.Error(), "can't evaluate field foo") {
		t.Fatalf("expected invalid template error, got: %s", err.Error())
	}

	// No template is specified
	fm, err = DataFormat("template", "")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	_, err = fm.TransformData(tData)
	if !strings.Contains(err.Error(), "template needs to be specified the golang templates.") {
		t.Fatalf("expected not specified template error, got: %s", err.Error())
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/git-lfs/git-lfs/errors"
	"github.com/git-lfs/git-lfs/git"
	"github.com/git-lfs/git-lfs/git/githistory"
	"github.com/git-lfs/git-lfs/git/odb"
	"github.com/git-lfs/git-lfs/tasklog"
	"github.com/spf13/cobra"
)

var (
	// migrateIncludeRefs is a set of Git references to explicitly include
	// in the migration.
	migrateIncludeRefs []string
	// migrateExcludeRefs is a set of Git references to explicitly exclude
	// in the migration.
	migrateExcludeRefs []string

	// migrateSkipFetch assumes that the client has the latest copy of
	// remote references, and thus should not contact the remote for a set
	// of updated references.
	migrateSkipFetch bool

	// migrateEverything indicates the presence of the --everything flag,
	// and instructs 'git lfs migrate' to migrate all local references.
	migrateEverything bool

	// migrateVerbose enables verbose logging
	migrateVerbose bool

	// objectMapFile is the path to the map of old sha1 to new sha1
	// commits
	objectMapFilePath string
)

// migrate takes the given command and arguments, *odb.ObjectDatabase, as well
// as a BlobRewriteFn to apply, and performs a migration.
func migrate(args []string, r *githistory.Rewriter, l *tasklog.Logger, opts *githistory.RewriteOptions) {
	requireInRepo()

	opts, err := rewriteOptions(args, opts, l)
	if err != nil {
		ExitWithError(err)
	}

	_, err = r.Rewrite(opts)
	if err != nil {
		ExitWithError(err)
	}
}

// getObjectDatabase creates a *git.ObjectDatabase from the filesystem pointed
// at the .git directory of the currently checked-out repository.
func getObjectDatabase() (*odb.ObjectDatabase, error) {
	dir, err := git.GitDir()
	if err != nil {
		return nil, errors.Wrap(err, "cannot open root")
	}
	return odb.FromFilesystem(filepath.Join(dir, "objects"), cfg.TempDir())
}

// rewriteOptions returns *githistory.RewriteOptions able to be passed to a
// *githistory.Rewriter that reflect the current arguments and flags passed to
// an invocation of git-lfs-migrate(1).
//
// It is merged with the given "opts". In other words, an identical "opts" is
// returned, where the Include and Exclude fields have been filled based on the
// following rules:
//
// The included and excluded references are determined based on the output of
// includeExcludeRefs (see below for documentation and detail).
//
// If any of the above could not be determined without error, that error will be
// returned immediately.
func rewriteOptions(args []string, opts *githistory.RewriteOptions, l *tasklog.Logger) (*githistory.RewriteOptions, error) {
	include, exclude, err := includeExcludeRefs(l, args)
	if err != nil {
		return nil, err
	}

	return &githistory.RewriteOptions{
		Include: include,
		Exclude: exclude,

		UpdateRefs:        opts.UpdateRefs,
		Verbose:           opts.Verbose,
		ObjectMapFilePath: opts.ObjectMapFilePath,

		BlobFn:         opts.BlobFn,
		TreeCallbackFn: opts.TreeCallbackFn,
	}, nil
}

// includeExcludeRefs returns fully-qualified sets of references to include, and
// exclude, or an error if those could not be determined.
//
// They are determined based on the following rules:
//
//   - Include all local refs/heads/<branch> references for each branch
//     specified as an argument.
//   - Include the currently checked out branch if no branches are given as
//     arguments and the --include-ref= or --exclude-ref= flag(s) aren't given.
//   - Include all references given in --include-ref=<ref>.
//   - Exclude all references given in --exclude-ref=<ref>.
func includeExcludeRefs(l *tasklog.Logger, args []string) (include, exclude []string, err error) {
	hardcore := len(migrateIncludeRefs) > 0 || len(migrateExcludeRefs) > 0

	if len(args) == 0 && !hardcore && !migrateEverything {
		// If no branches were given explicitly AND neither
		// --include-ref or --exclude-ref flags were given, then add the
		// currently checked out reference.
		current, err := currentRefToMigrate()
		if err != nil {
			return nil, nil, err
		}
		args = append(args, current.Name)
	}

	if migrateEverything && len(args) > 0 {
		return nil, nil, errors.New("fatal: cannot use --everything with explicit reference arguments")
	}

	for _, name := range args {
		var excluded bool
		if strings.HasPrefix("^", name) {
			name = name[1:]
			excluded = true
		}

		// Then, loop through each branch given, resolve that reference,
		// and include it.
		ref, err := git.ResolveRef(name)
		if err != nil {
			return nil, nil, err
		}

		if excluded {
			exclude = append(exclude, ref.Refspec())
		} else {
			include = append(include, ref.Refspec())
		}
	}

	if hardcore {
		if migrateEverything {
			return nil, nil, errors.New("fatal: cannot use --everything with --include-ref or --exclude-ref")
		}

		// If either --include-ref=<ref> or --exclude-ref=<ref> were
		// given, append those to the include and excluded reference
		// set, respectively.
		include = append(include, migrateIncludeRefs...)
		exclude = append(exclude, migrateExcludeRefs...)
	} else if migrateEverything {
		localRefs, err := git.LocalRefs()
		if err != nil {
			return nil, nil, err
		}

		for _, ref := range localRefs {
			include = append(include, ref.Refspec())
		}
	} else {
		bare, err := git.IsBare()
		if err != nil {
			return nil, nil, errors.Wrap(err, "fatal: unable to determine bareness")
		}

		if !bare {
			// Otherwise, if neither --include-ref=<ref> or
			// --exclude-ref=<ref> were given, include no additional
			// references, and exclude all remote references that
			// are remote branches or remote tags.
			remoteRefs, err := getRemoteRefs(l)
			if err != nil {
				return nil, nil, err
			}

			for _, rr := range remoteRefs {
				exclude = append(exclude, rr.Refspec())
			}
		}
	}

	return include, exclude, nil
}

// getRemoteRefs returns a fully qualified set of references belonging to all
// remotes known by the currently checked-out repository, or an error if those
// references could not be determined.
func getRemoteRefs(l *tasklog.Logger) ([]*git.Ref, error) {
	var refs []*git.Ref

	remotes, err := git.RemoteList()
	if err != nil {
		return nil, err
	}

	if !migrateSkipFetch {
		w := l.Waiter("migrate: Fetching remote refs")
		if err := git.Fetch(remotes...); err != nil {
			return nil, err
		}
		w.Complete()
	}

	for _, remote := range remotes {
		var refsForRemote []*git.Ref
		if migrateSkipFetch {
			refsForRemote, err = git.CachedRemoteRefs(remote)
		} else {
			refsForRemote, err = git.RemoteRefs(remote)
		}

		if err != nil {
			return nil, err
		}

		for _, rr := range refsForRemote {
			// HACK(@ttaylorr): add remote name to fully-qualify
			// references:
			rr.Name = fmt.Sprintf("%s/%s", remote, rr.Name)

			refs = append(refs, rr)
		}
	}

	return refs, nil
}

// formatRefName returns the fully-qualified name for the given Git reference
// "ref".
func formatRefName(ref *git.Ref, remote string) string {
	var name []string

	switch ref.Type {
	case git.RefTypeRemoteBranch:
		name = []string{"refs", "remotes", remote, ref.Name}
	case git.RefTypeRemoteTag:
		name = []string{"refs", "tags", ref.Name}
	default:
		return ref.Name
	}
	return strings.Join(name, "/")

}

// currentRefToMigrate returns the fully-qualified name of the currently
// checked-out reference, or an error if the reference's type was not a local
// branch.
func currentRefToMigrate() (*git.Ref, error) {
	current, err := git.CurrentRef()
	if err != nil {
		return nil, err
	}

	if current.Type == git.RefTypeOther ||
		current.Type == git.RefTypeRemoteBranch ||
		current.Type == git.RefTypeRemoteTag {

		return nil, errors.Errorf("fatal: cannot migrate non-local ref: %s", current.Name)
	}
	return current, nil
}

// getHistoryRewriter returns a history rewriter that includes the filepath
// filter given by the --include and --exclude arguments.
func getHistoryRewriter(cmd *cobra.Command, db *odb.ObjectDatabase, l *tasklog.Logger) *githistory.Rewriter {
	include, exclude := getIncludeExcludeArgs(cmd)
	filter := buildFilepathFilter(cfg, include, exclude)

	return githistory.NewRewriter(db,
		githistory.WithFilter(filter), githistory.WithLogger(l))
}

func init() {
	info := NewCommand("info", migrateInfoCommand)
	info.Flags().IntVar(&migrateInfoTopN, "top", 5, "--top=<n>")
	info.Flags().StringVar(&migrateInfoAboveFmt, "above", "", "--above=<n>")
	info.Flags().StringVar(&migrateInfoUnitFmt, "unit", "", "--unit=<unit>")

	importCmd := NewCommand("import", migrateImportCommand)
	importCmd.Flags().BoolVar(&migrateVerbose, "verbose", false, "Verbose logging")
	importCmd.Flags().StringVar(&objectMapFilePath, "object-map", "", "Object map file")

	RegisterCommand("migrate", nil, func(cmd *cobra.Command) {
		cmd.PersistentFlags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths")
		cmd.PersistentFlags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths")

		cmd.PersistentFlags().StringSliceVar(&migrateIncludeRefs, "include-ref", nil, "An explicit list of refs to include")
		cmd.PersistentFlags().StringSliceVar(&migrateExcludeRefs, "exclude-ref", nil, "An explicit list of refs to exclude")
		cmd.PersistentFlags().BoolVar(&migrateEverything, "everything", false, "Migrate all local references")
		cmd.PersistentFlags().BoolVar(&migrateSkipFetch, "skip-fetch", false, "Assume up-to-date remote references.")

		cmd.AddCommand(importCmd, info)
	})
}
<commit_msg>commands: teach --no-rewrite flag to 'migrate-import'<commit_after>package commands

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/git-lfs/git-lfs/errors"
	"github.com/git-lfs/git-lfs/git"
	"github.com/git-lfs/git-lfs/git/githistory"
	"github.com/git-lfs/git-lfs/git/odb"
	"github.com/git-lfs/git-lfs/tasklog"
	"github.com/spf13/cobra"
)

var (
	// migrateIncludeRefs is a set of Git references to explicitly include
	// in the migration.
	migrateIncludeRefs []string
	// migrateExcludeRefs is a set of Git references to explicitly exclude
	// in the migration.
	migrateExcludeRefs []string

	// migrateSkipFetch assumes that the client has the latest copy of
	// remote references, and thus should not contact the remote for a set
	// of updated references.
	migrateSkipFetch bool

	// migrateEverything indicates the presence of the --everything flag,
	// and instructs 'git lfs migrate' to migrate all local references.
	migrateEverything bool

	// migrateVerbose enables verbose logging
	migrateVerbose bool

	// objectMapFile is the path to the map of old sha1 to new sha1
	// commits
	objectMapFilePath string

	// migrateNoRewrite is the flag indicating whether or not the
	// command should rewrite git history
	migrateNoRewrite bool
)

// migrate takes the given command and arguments, *odb.ObjectDatabase, as well
// as a BlobRewriteFn to apply, and performs a migration.
func migrate(args []string, r *githistory.Rewriter, l *tasklog.Logger, opts *githistory.RewriteOptions) {
	requireInRepo()

	opts, err := rewriteOptions(args, opts, l)
	if err != nil {
		ExitWithError(err)
	}

	_, err = r.Rewrite(opts)
	if err != nil {
		ExitWithError(err)
	}
}

// getObjectDatabase creates a *git.ObjectDatabase from the filesystem pointed
// at the .git directory of the currently checked-out repository.
func getObjectDatabase() (*odb.ObjectDatabase, error) {
	dir, err := git.GitDir()
	if err != nil {
		return nil, errors.Wrap(err, "cannot open root")
	}
	return odb.FromFilesystem(filepath.Join(dir, "objects"), cfg.TempDir())
}

// rewriteOptions returns *githistory.RewriteOptions able to be passed to a
// *githistory.Rewriter that reflect the current arguments and flags passed to
// an invocation of git-lfs-migrate(1).
//
// It is merged with the given "opts". In other words, an identical "opts" is
// returned, where the Include and Exclude fields have been filled based on the
// following rules:
//
// The included and excluded references are determined based on the output of
// includeExcludeRefs (see below for documentation and detail).
//
// If any of the above could not be determined without error, that error will be
// returned immediately.
func rewriteOptions(args []string, opts *githistory.RewriteOptions, l *tasklog.Logger) (*githistory.RewriteOptions, error) {
	include, exclude, err := includeExcludeRefs(l, args)
	if err != nil {
		return nil, err
	}

	return &githistory.RewriteOptions{
		Include: include,
		Exclude: exclude,

		UpdateRefs:        opts.UpdateRefs,
		Verbose:           opts.Verbose,
		ObjectMapFilePath: opts.ObjectMapFilePath,

		BlobFn:         opts.BlobFn,
		TreeCallbackFn: opts.TreeCallbackFn,
	}, nil
}

// includeExcludeRefs returns fully-qualified sets of references to include, and
// exclude, or an error if those could not be determined.
//
// They are determined based on the following rules:
//
//   - Include all local refs/heads/<branch> references for each branch
//     specified as an argument.
//   - Include the currently checked out branch if no branches are given as
//     arguments and the --include-ref= or --exclude-ref= flag(s) aren't given.
//   - Include all references given in --include-ref=<ref>.
//   - Exclude all references given in --exclude-ref=<ref>.
func includeExcludeRefs(l *tasklog.Logger, args []string) (include, exclude []string, err error) {
	hardcore := len(migrateIncludeRefs) > 0 || len(migrateExcludeRefs) > 0

	if len(args) == 0 && !hardcore && !migrateEverything {
		// If no branches were given explicitly AND neither
		// --include-ref or --exclude-ref flags were given, then add the
		// currently checked out reference.
		current, err := currentRefToMigrate()
		if err != nil {
			return nil, nil, err
		}
		args = append(args, current.Name)
	}

	if migrateEverything && len(args) > 0 {
		return nil, nil, errors.New("fatal: cannot use --everything with explicit reference arguments")
	}

	for _, name := range args {
		var excluded bool
		if strings.HasPrefix("^", name) {
			name = name[1:]
			excluded = true
		}

		// Then, loop through each branch given, resolve that reference,
		// and include it.
		ref, err := git.ResolveRef(name)
		if err != nil {
			return nil, nil, err
		}

		if excluded {
			exclude = append(exclude, ref.Refspec())
		} else {
			include = append(include, ref.Refspec())
		}
	}

	if hardcore {
		if migrateEverything {
			return nil, nil, errors.New("fatal: cannot use --everything with --include-ref or --exclude-ref")
		}

		// If either --include-ref=<ref> or --exclude-ref=<ref> were
		// given, append those to the include and excluded reference
		// set, respectively.
		include = append(include, migrateIncludeRefs...)
		exclude = append(exclude, migrateExcludeRefs...)
	} else if migrateEverything {
		localRefs, err := git.LocalRefs()
		if err != nil {
			return nil, nil, err
		}

		for _, ref := range localRefs {
			include = append(include, ref.Refspec())
		}
	} else {
		bare, err := git.IsBare()
		if err != nil {
			return nil, nil, errors.Wrap(err, "fatal: unable to determine bareness")
		}

		if !bare {
			// Otherwise, if neither --include-ref=<ref> or
			// --exclude-ref=<ref> were given, include no additional
			// references, and exclude all remote references that
			// are remote branches or remote tags.
			remoteRefs, err := getRemoteRefs(l)
			if err != nil {
				return nil, nil, err
			}

			for _, rr := range remoteRefs {
				exclude = append(exclude, rr.Refspec())
			}
		}
	}

	return include, exclude, nil
}

// getRemoteRefs returns a fully qualified set of references belonging to all
// remotes known by the currently checked-out repository, or an error if those
// references could not be determined.
func getRemoteRefs(l *tasklog.Logger) ([]*git.Ref, error) {
	var refs []*git.Ref

	remotes, err := git.RemoteList()
	if err != nil {
		return nil, err
	}

	if !migrateSkipFetch {
		w := l.Waiter("migrate: Fetching remote refs")
		if err := git.Fetch(remotes...); err != nil {
			return nil, err
		}
		w.Complete()
	}

	for _, remote := range remotes {
		var refsForRemote []*git.Ref
		if migrateSkipFetch {
			refsForRemote, err = git.CachedRemoteRefs(remote)
		} else {
			refsForRemote, err = git.RemoteRefs(remote)
		}

		if err != nil {
			return nil, err
		}

		for _, rr := range refsForRemote {
			// HACK(@ttaylorr): add remote name to fully-qualify
			// references:
			rr.Name = fmt.Sprintf("%s/%s", remote, rr.Name)

			refs = append(refs, rr)
		}
	}

	return refs, nil
}

// formatRefName returns the fully-qualified name for the given Git reference
// "ref".
func formatRefName(ref *git.Ref, remote string) string {
	var name []string

	switch ref.Type {
	case git.RefTypeRemoteBranch:
		name = []string{"refs", "remotes", remote, ref.Name}
	case git.RefTypeRemoteTag:
		name = []string{"refs", "tags", ref.Name}
	default:
		return ref.Name
	}
	return strings.Join(name, "/")

}

// currentRefToMigrate returns the fully-qualified name of the currently
// checked-out reference, or an error if the reference's type was not a local
// branch.
func currentRefToMigrate() (*git.Ref, error) {
	current, err := git.CurrentRef()
	if err != nil {
		return nil, err
	}

	if current.Type == git.RefTypeOther ||
		current.Type == git.RefTypeRemoteBranch ||
		current.Type == git.RefTypeRemoteTag {

		return nil, errors.Errorf("fatal: cannot migrate non-local ref: %s", current.Name)
	}
	return current, nil
}

// getHistoryRewriter returns a history rewriter that includes the filepath
// filter given by the --include and --exclude arguments.
func getHistoryRewriter(cmd *cobra.Command, db *odb.ObjectDatabase, l *tasklog.Logger) *githistory.Rewriter {
	include, exclude := getIncludeExcludeArgs(cmd)
	filter := buildFilepathFilter(cfg, include, exclude)

	return githistory.NewRewriter(db,
		githistory.WithFilter(filter), githistory.WithLogger(l))
}

func init() {
	info := NewCommand("info", migrateInfoCommand)
	info.Flags().IntVar(&migrateInfoTopN, "top", 5, "--top=<n>")
	info.Flags().StringVar(&migrateInfoAboveFmt, "above", "", "--above=<n>")
	info.Flags().StringVar(&migrateInfoUnitFmt, "unit", "", "--unit=<unit>")

	importCmd := NewCommand("import", migrateImportCommand)
	importCmd.Flags().BoolVar(&migrateVerbose, "verbose", false, "Verbose logging")
	importCmd.Flags().StringVar(&objectMapFilePath, "object-map", "", "Object map file")
	importCmd.Flags().BoolVar(&migrateNoRewrite, "no-rewrite", false, "Add new history without rewriting previous")

	RegisterCommand("migrate", nil, func(cmd *cobra.Command) {
		cmd.PersistentFlags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths")
		cmd.PersistentFlags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths")

		cmd.PersistentFlags().StringSliceVar(&migrateIncludeRefs, "include-ref", nil, "An explicit list of refs to include")
		cmd.PersistentFlags().StringSliceVar(&migrateExcludeRefs, "exclude-ref", nil, "An explicit list of refs to exclude")
		cmd.PersistentFlags().BoolVar(&migrateEverything, "everything", false, "Migrate all local references")
		cmd.PersistentFlags().BoolVar(&migrateSkipFetch, "skip-fetch", false, "Assume up-to-date remote references.")

		cmd.AddCommand(importCmd, info)
	})
}
<|endoftext|>


<commit_before>package alloc

import (
	"testing"

	v2testing "github.com/v2ray/v2ray-core/testing"
	"github.com/v2ray/v2ray-core/testing/assert"
)

func TestBufferClear(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer().Clear()
	defer buffer.Release()

	payload := "Bytes"
	buffer.Append([]byte(payload))
	assert.Int(buffer.Len()).Equals(len(payload))

	buffer.Clear()
	assert.Int(buffer.Len()).Equals(0)
}

func TestBufferIsFull(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer()
	defer buffer.Release()

	assert.Bool(buffer.IsFull()).IsTrue()

	buffer.Clear()
	assert.Bool(buffer.IsFull()).IsFalse()
}

func TestBufferPrepend(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer().Clear()
	defer buffer.Release()

	buffer.Append([]byte{'a', 'b', 'c'})
	buffer.Prepend([]byte{'x', 'y', 'z'})

	assert.Int(buffer.Len()).Equals(6)
	assert.Bytes(buffer.Value).Equals([]byte("xyzabc"))

	buffer.Prepend([]byte{'u', 'v', 'w'})
	assert.Bytes(buffer.Value).Equals([]byte("uvwxyzabc"))
}
<commit_msg>test case for buffer string<commit_after>package alloc

import (
	"testing"

	v2testing "github.com/v2ray/v2ray-core/testing"
	"github.com/v2ray/v2ray-core/testing/assert"
)

func TestBufferClear(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer().Clear()
	defer buffer.Release()

	payload := "Bytes"
	buffer.Append([]byte(payload))
	assert.Int(buffer.Len()).Equals(len(payload))

	buffer.Clear()
	assert.Int(buffer.Len()).Equals(0)
}

func TestBufferIsFull(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer()
	defer buffer.Release()

	assert.Bool(buffer.IsFull()).IsTrue()

	buffer.Clear()
	assert.Bool(buffer.IsFull()).IsFalse()
}

func TestBufferPrepend(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer().Clear()
	defer buffer.Release()

	buffer.Append([]byte{'a', 'b', 'c'})
	buffer.Prepend([]byte{'x', 'y', 'z'})

	assert.Int(buffer.Len()).Equals(6)
	assert.Bytes(buffer.Value).Equals([]byte("xyzabc"))

	buffer.Prepend([]byte{'u', 'v', 'w'})
	assert.Bytes(buffer.Value).Equals([]byte("uvwxyzabc"))
}

func TestBufferString(t *testing.T) {
	v2testing.Current(t)

	buffer := NewBuffer().Clear()
	defer buffer.Release()

	buffer.AppendString("Test String")
	assert.String(buffer).Equals("Test String")
}
<|endoftext|>


<commit_before>package outputelastic

import (
	"context"
	"strings"
	"testing"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/tsaikd/gogstash/config"
	"github.com/tsaikd/gogstash/config/goglog"
	"github.com/tsaikd/gogstash/config/logevent"
	elastic "gopkg.in/olivere/elastic.v5"
)

func init() {
	goglog.Logger.SetLevel(logrus.DebugLevel)
	config.RegistOutputHandler(ModuleName, InitHandler)
}

func Test_output_elastic_module(t *testing.T) {
	assert := assert.New(t)
	assert.NotNil(assert)
	require := require.New(t)
	require.NotNil(require)

	ctx := context.Background()
	conf, err := config.LoadFromYAML([]byte(strings.TrimSpace(`
debugch: true
output:
  - type: elastic
    url: ["http://127.0.0.1:9200"]
    index: "gogstash-index-test"
    document_type: "testtype"
    document_id: "%{fieldstring}"
    bulk_actions: 0
	`)))
	require.NoError(err)
	err = conf.Start(ctx)
	if err != nil {
		require.True(ErrorCreateClientFailed1.In(err))
		t.Skip("skip test output elastic module")
	}

	conf.TestInputEvent(logevent.LogEvent{
		Timestamp: time.Date(2017, 4, 18, 19, 53, 1, 2, time.UTC),
		Message:   "output elastic test message",
		Extra: map[string]interface{}{
			"fieldstring": "ABC",
			"fieldnumber": 123,
		},
	})

	if event, err2 := conf.TestGetOutputEvent(300 * time.Millisecond); assert.NoError(err2) {
		require.Equal("output elastic test message", event.Message)
	}

	client, err := elastic.NewClient(
		elastic.SetURL("http://127.0.0.1:9200"),
		elastic.SetSniff(false),
	)
	require.NoError(err)
	require.NotNil(client)

	ctx, cancel := context.WithTimeout(context.Background(), 1000*time.Millisecond)
	defer cancel()
	result, err := client.Get().Index("gogstash-index-test").Id("ABC").Do(ctx)
	require.NoError(err)
	require.NotNil(result)
	require.NotNil(result.Source)
	require.Equal(`{"@timestamp":"2017-04-18T19:53:01.000000002Z","fieldnumber":123,"fieldstring":"ABC","message":"output elastic test message"}`, string(*result.Source))

	_, err = client.DeleteIndex("gogstash-index-test").Do(ctx)
	require.NoError(err)
}
<commit_msg>output/elastic: v6 for testing<commit_after>package outputelastic

import (
	"context"
	"strings"
	"testing"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/tsaikd/gogstash/config"
	"github.com/tsaikd/gogstash/config/goglog"
	"github.com/tsaikd/gogstash/config/logevent"
	elastic "gopkg.in/olivere/elastic.v6"
)

func init() {
	goglog.Logger.SetLevel(logrus.DebugLevel)
	config.RegistOutputHandler(ModuleName, InitHandler)
}

func Test_output_elastic_module(t *testing.T) {
	assert := assert.New(t)
	assert.NotNil(assert)
	require := require.New(t)
	require.NotNil(require)

	ctx := context.Background()
	conf, err := config.LoadFromYAML([]byte(strings.TrimSpace(`
debugch: true
output:
  - type: elastic
    url: ["http://127.0.0.1:9200"]
    index: "gogstash-index-test"
    document_type: "testtype"
    document_id: "%{fieldstring}"
    bulk_actions: 0
	`)))
	require.NoError(err)
	err = conf.Start(ctx)
	if err != nil {
		require.True(ErrorCreateClientFailed1.In(err))
		t.Skip("skip test output elastic module")
	}

	conf.TestInputEvent(logevent.LogEvent{
		Timestamp: time.Date(2017, 4, 18, 19, 53, 1, 2, time.UTC),
		Message:   "output elastic test message",
		Extra: map[string]interface{}{
			"fieldstring": "ABC",
			"fieldnumber": 123,
		},
	})

	if event, err2 := conf.TestGetOutputEvent(300 * time.Millisecond); assert.NoError(err2) {
		require.Equal("output elastic test message", event.Message)
	}

	client, err := elastic.NewClient(
		elastic.SetURL("http://127.0.0.1:9200"),
		elastic.SetSniff(false),
	)
	require.NoError(err)
	require.NotNil(client)

	ctx, cancel := context.WithTimeout(context.Background(), 1000*time.Millisecond)
	defer cancel()
	result, err := client.Get().Index("gogstash-index-test").Id("ABC").Do(ctx)
	require.NoError(err)
	require.NotNil(result)
	require.NotNil(result.Source)
	require.Equal(`{"@timestamp":"2017-04-18T19:53:01.000000002Z","fieldnumber":123,"fieldstring":"ABC","message":"output elastic test message"}`, string(*result.Source))

	_, err = client.DeleteIndex("gogstash-index-test").Do(ctx)
	require.NoError(err)
}
<|endoftext|>