<commit_before>package meter

import (
	"errors"
	"fmt"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/go-redis/redis"
)

type Event struct {
	name        string
	counters    *Counters
	labels      []string
	pool        *sync.Pool
	index       map[string]int
	resolutions []*Resolution
}

var isTemplateRX = regexp.MustCompile("\\{\\{[^\\}]+\\}\\}")

func IsTemplateName(name string) bool {
	return isTemplateRX.MatchString(name)
}

func NewEvent(name string, labels []string, res ...*Resolution) *Event {
	e := &Event{
		name:     name,
		counters: NewCounters(),
		labels:   NormalizeLabels(labels...),
		index:    make(map[string]int),
	}
	for i, label := range e.labels {
		e.index[label] = i
	}
	e.pool = &sync.Pool{
		New: func() interface{} {
			return Labels(make([]string, 2*len(e.labels)))
		},
	}
	for _, r := range res {
		if r != nil {
			e.resolutions = append(e.resolutions, r)
		}
	}
	return e

}
func (e *Event) get() Labels {
	labels := e.pool.Get().(Labels)
	for label, i := range e.index {
		labels[2*i] = label
		labels[2*i+1] = "*"
	}
	return labels
}
func (e *Event) put(labels Labels) {
	n := 2 * len(e.labels)
	if cap(labels) < n {
		return
	}
	e.pool.Put(labels[:n])
}

func (e *Event) AliasedLabels(input []string, aliases Aliases) (labels Labels) {
	labels = e.get()
	n := len(input)
	n = n - (n % 2)
	for i := 0; i < n; i += 2 {
		a := aliases.Alias(input[i])
		if j, ok := e.index[a]; ok {
			labels[j+1] = input[i+1]
		}
	}
	return
}

func (e *Event) Labels(input ...string) (labels []string) {
	return e.AliasedLabels(input, nil)
}
func (e *Event) Field(input ...string) string {
	return strings.Join(e.Labels(input...), ":")
}

func Replacer(labels ...string) *strings.Replacer {
	n := len(labels)
	n = n - (n % 2)
	r := make([]string, n)
	for i := 0; i < n; i++ {
		if (i % 2) == 0 {
			r[i] = fmt.Sprintf("{{%s}}", labels[i])
		} else {
			if v := labels[i]; v == "" {
				r[i] = "*"
			} else {
				r[i] = labels[i]
			}
		}
	}
	return strings.NewReplacer(r...)
}

func (e *Event) EventName(labels ...string) string {
	if IsTemplateName(e.name) {
		return Replacer(labels...).Replace(e.name)
	}
	return e.name
}

func (e *Event) HasLabel(a string) bool {
	_, ok := e.index[a]
	return ok
}

func (e *Event) Record(r *Resolution, t time.Time, labels []string) Record {
	return Record{
		Key:    e.Key(r, t, labels),
		Field:  strings.Join(labels, ":"),
		Time:   t,
		Labels: labels,
	}
}

func (e *Event) Records(res *Resolution, start, end time.Time, queries ...[]string) []Record {
	if res == nil {
		return nil
	}
	ts := res.TimeSequence(start, end)
	if len(ts) == 0 {
		ts = append(ts, res.Round(time.Now()))
	}
	results := make([]Record, 0, len(queries)*(len(ts)+1))
	for _, labels := range queries {
		labels = e.Labels(labels...)
		for _, tm := range ts {
			results = append(results, e.Record(res, tm, labels))
		}
	}
	return results
}

func (e *Event) Log(n int64, labels ...string) {
	e.counters.Increment(strings.Join(labels, labelSeparator), n)
}

const labelSeparator = string('0')

func (e *Event) MustPersist(tm time.Time, r *redis.Client) {
	if err := e.Persist(tm, r); err != nil {
		panic(err)
	}
}

var NilEventError = errors.New("Event is nil.")

func (e *Event) DimField(dim Dimension, q map[string]string) (field string, ok bool) {
	labels := e.get()
	defer e.put(labels)
	n := 0
	for _, label := range dim {
		if i, hasLabel := e.index[label]; hasLabel {
			if v := q[label]; v != "" {
				labels[i+1] = v
				n++
			}
		}
	}
	if n == len(dim) {
		ok = true
		field = strings.Join(labels, ":")
	}
	return
}

func (e *Event) AllField() string {
	labels := e.get()
	defer e.put(labels)
	return strings.Join(labels, ":")
}
func (e *Event) Persist(tm time.Time, r *redis.Client) error {
	if e == nil {
		return NilEventError
	}
	// Use a transaction to ensure each event type is persisted entirely
	b := e.counters.Flush()
	if len(b) == 0 {
		return nil
	}
	p := r.TxPipeline()
	defer p.Close()
	keys := make(map[string]time.Duration)
	all := e.AllField()
	dims := LabelDimensions(e.labels...)
	for fields, val := range b {
		labels := strings.Split(fields, labelSeparator)
		q := Labels(labels).Map()
		name := e.EventName(labels...)
		for _, res := range e.resolutions {
			if res == nil {
				continue
			}
			key := res.Key(name, tm)
			keys[key] = res.TTL()
			p.HIncrBy(key, all, val)
			if fields == "" {
				continue
			}
			for _, dim := range dims {
				if field, ok := e.DimField(dim, q); ok {
					p.HIncrBy(key, field, val)
				}
			}
		}
	}
	for k, ttl := range keys {
		if ttl > 0 {
			p.PExpire(k, ttl)
		}
	}
	_, err := p.Exec()
	if err != nil {
		e.counters.BatchIncrement(b)
	}
	return err
}

func (e *Event) Key(res *Resolution, tm time.Time, labels []string) string {
	return res.Key(e.EventName(labels...), tm)
}
<commit_msg>Set event label index to value pos<commit_after>package meter

import (
	"errors"
	"fmt"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/go-redis/redis"
)

type Event struct {
	name        string
	counters    *Counters
	labels      []string
	pool        *sync.Pool
	index       map[string]int
	resolutions []*Resolution
}

var isTemplateRX = regexp.MustCompile("\\{\\{[^\\}]+\\}\\}")

func IsTemplateName(name string) bool {
	return isTemplateRX.MatchString(name)
}

func NewEvent(name string, labels []string, res ...*Resolution) *Event {
	e := &Event{
		name:     name,
		counters: NewCounters(),
		labels:   NormalizeLabels(labels...),
		index:    make(map[string]int),
	}
	for i, label := range e.labels {
		e.index[label] = 2*i + 1
	}
	e.pool = &sync.Pool{
		New: func() interface{} {
			return Labels(make([]string, 2*len(e.labels)))
		},
	}
	for _, r := range res {
		if r != nil {
			e.resolutions = append(e.resolutions, r)
		}
	}
	return e

}
func (e *Event) get() Labels {
	labels := e.pool.Get().(Labels)
	for label, i := range e.index {
		labels[i-1] = label
		labels[i] = "*"
	}
	return labels
}
func (e *Event) put(labels Labels) {
	n := 2 * len(e.labels)
	if cap(labels) < n {
		return
	}
	e.pool.Put(labels[:n])
}

func (e *Event) AliasedLabels(input []string, aliases Aliases) (labels Labels) {
	labels = e.get()
	n := len(input)
	n = n - (n % 2)
	for i := 0; i < n; i += 2 {
		a := aliases.Alias(input[i])
		if j, ok := e.index[a]; ok {
			labels[j] = input[i+1]
		}
	}
	return
}

func (e *Event) Labels(input ...string) (labels []string) {
	return e.AliasedLabels(input, nil)
}
func (e *Event) Field(input ...string) string {
	return strings.Join(e.Labels(input...), ":")
}

func Replacer(labels ...string) *strings.Replacer {
	n := len(labels)
	n = n - (n % 2)
	r := make([]string, n)
	for i := 0; i < n; i++ {
		if (i % 2) == 0 {
			r[i] = fmt.Sprintf("{{%s}}", labels[i])
		} else {
			if v := labels[i]; v == "" {
				r[i] = "*"
			} else {
				r[i] = labels[i]
			}
		}
	}
	return strings.NewReplacer(r...)
}

func (e *Event) EventName(labels ...string) string {
	if IsTemplateName(e.name) {
		return Replacer(labels...).Replace(e.name)
	}
	return e.name
}

func (e *Event) HasLabel(a string) bool {
	_, ok := e.index[a]
	return ok
}

func (e *Event) Record(r *Resolution, t time.Time, labels []string) Record {
	return Record{
		Key:    e.Key(r, t, labels),
		Field:  strings.Join(labels, ":"),
		Time:   t,
		Labels: labels,
	}
}

func (e *Event) Records(res *Resolution, start, end time.Time, queries ...[]string) []Record {
	if res == nil {
		return nil
	}
	ts := res.TimeSequence(start, end)
	if len(ts) == 0 {
		ts = append(ts, res.Round(time.Now()))
	}
	results := make([]Record, 0, len(queries)*(len(ts)+1))
	for _, labels := range queries {
		labels = e.Labels(labels...)
		for _, tm := range ts {
			results = append(results, e.Record(res, tm, labels))
		}
	}
	return results
}

func (e *Event) Log(n int64, labels ...string) {
	e.counters.Increment(strings.Join(labels, labelSeparator), n)
}

const labelSeparator = string('0')

func (e *Event) MustPersist(tm time.Time, r *redis.Client) {
	if err := e.Persist(tm, r); err != nil {
		panic(err)
	}
}

var NilEventError = errors.New("Event is nil.")

func (e *Event) DimField(dim Dimension, q map[string]string) (field string, ok bool) {
	labels := e.get()
	defer e.put(labels)
	n := 0
	for _, label := range dim {
		if i, hasLabel := e.index[label]; hasLabel {
			if v := q[label]; v != "" {
				labels[i] = v
				n++
			}
		}
	}
	if n == len(dim) {
		ok = true
		field = strings.Join(labels, ":")
	}
	return
}

func (e *Event) AllField() string {
	labels := e.get()
	defer e.put(labels)
	return strings.Join(labels, ":")
}
func (e *Event) Persist(tm time.Time, r *redis.Client) error {
	if e == nil {
		return NilEventError
	}
	// Use a transaction to ensure each event type is persisted entirely
	b := e.counters.Flush()
	if len(b) == 0 {
		return nil
	}
	p := r.TxPipeline()
	defer p.Close()
	keys := make(map[string]time.Duration)
	all := e.AllField()
	dims := LabelDimensions(e.labels...)
	for fields, val := range b {
		labels := strings.Split(fields, labelSeparator)
		q := Labels(labels).Map()
		name := e.EventName(labels...)
		for _, res := range e.resolutions {
			if res == nil {
				continue
			}
			key := res.Key(name, tm)
			keys[key] = res.TTL()
			p.HIncrBy(key, all, val)
			if fields == "" {
				continue
			}
			for _, dim := range dims {
				if field, ok := e.DimField(dim, q); ok {
					p.HIncrBy(key, field, val)
				}
			}
		}
	}
	for k, ttl := range keys {
		if ttl > 0 {
			p.PExpire(k, ttl)
		}
	}
	_, err := p.Exec()
	if err != nil {
		e.counters.BatchIncrement(b)
	}
	return err
}

func (e *Event) Key(res *Resolution, tm time.Time, labels []string) string {
	return res.Key(e.EventName(labels...), tm)
}
<|endoftext|>


<commit_before>package http2

import (
	"github.com/summerwind/h2spec/config"
	"github.com/summerwind/h2spec/spec"
)

func HTTP2ConnectionPreface() *spec.TestGroup {
	tg := NewTestGroup("3.5", "HTTP/2 Connection Preface")

	tg.AddTestCase(&spec.TestCase{
		Desc:        "Sends invalid connection preface",
		Requirement: "The endpoint MUST terminate the TCP connection.",
		Run: func(c *config.Config, conn *spec.Conn) error {
			err := conn.Send("INVALID CONNECTION PREFACE\r\n\r\n")
			if err != nil {
				return err
			}

			return spec.VerifyConnectionClose(conn)
		},
	})

	return tg
}
<commit_msg>Add test case for checking server connection preface<commit_after>package http2

import (
	"github.com/summerwind/h2spec/config"
	"github.com/summerwind/h2spec/spec"
	"golang.org/x/net/http2"
)

func HTTP2ConnectionPreface() *spec.TestGroup {
	tg := NewTestGroup("3.5", "HTTP/2 Connection Preface")

	// The server connection preface consists of a potentially empty
	// SETTINGS frame (Section 6.5) that MUST be the first frame
	// the server sends in the HTTP/2 connection.
	tg.AddTestCase(&spec.TestCase{
		Desc:        "Sends client connection preface",
		Requirement: "The server connection preface MUST be the first frame the server sends in the HTTP/2 connection.",
		Run: func(c *config.Config, conn *spec.Conn) error {
			setting := http2.Setting{
				ID:  http2.SettingInitialWindowSize,
				Val: spec.DefaultWindowSize,
			}

			conn.Send("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
			conn.WriteSettings(setting)

			return spec.VerifyFrameType(conn, http2.FrameSettings)
		},
	})

	// Clients and servers MUST treat an invalid connection preface as
	// a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
	tg.AddTestCase(&spec.TestCase{
		Desc:        "Sends invalid connection preface",
		Requirement: "The endpoint MUST terminate the TCP connection.",
		Run: func(c *config.Config, conn *spec.Conn) error {
			err := conn.Send("INVALID CONNECTION PREFACE\r\n\r\n")
			if err != nil {
				return err
			}

			// Connection has not negotiated, so we verify connection close
			// instead of connection error.
			return spec.VerifyConnectionClose(conn)
		},
	})

	return tg
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"

	_ "github.com/dotdoom/goxmpp"
	"github.com/dotdoom/goxmpp/extensions/features/auth/mechanisms"
	"github.com/dotdoom/goxmpp/stream"
	"github.com/dotdoom/goxmpp/stream/elements/features"
)

/*type C2s struct {
	Conn          net.Conn
	Authenticated bool
}

var clients map[string]C2s*/

func C2sServer() error {
	listener, err := net.Listen("tcp", "0.0.0.0:5222")
	if err != nil {
		return err
	}

	println("Server started")
	for {
		conn, err := listener.Accept()
		if err == nil {
			go C2sConnection(conn)
		} else {
			println(err.Error())
		}
	}
}

func main() {
	err := C2sServer()
	if err != nil {
		println(err.Error())
	}
}

func C2sConnection(conn net.Conn) error {
	println("New connection")
	defer func() {
		conn.Close()
		println("Connection closed")
	}()

	st := stream.NewStream(conn)

	// Push states for all features we want to use
	//st.State.Push(&methods.GzipState{Level: 5})

	st.State.Push(&mechanisms.PlainState{
		Callback: func(user string, password string) bool {
			fmt.Println("Trying to auth (using PLAIN)", user)
			return true
		},
		RequireEncryption: true,
	})

	/*st.State.Push(&mechanisms.DigestMD5State{Callback: func(user string, salt string) string {
		fmt.Println("Trying to auth (using DIGEST-MD5)", user)
		return salt
	}})*/

	// Go through the features loop until stream is finally open (or something wrong happens)
	for st.Opened != true {
		st.ReadOpen()
		st.From, st.To = st.To, ""
		st.WriteOpen()

		if err := features.Loop(st); err != nil {
			fmt.Println("Features loop failed.", err)
			return err
		}
	}

	fmt.Println("Stream opened, required features passed.", st.From)

	return nil
}
<commit_msg>Add bind and session<commit_after>package main

import (
	"fmt"
	"net"

	_ "github.com/dotdoom/goxmpp"
	"github.com/dotdoom/goxmpp/extensions/features/auth/mechanisms"
	"github.com/dotdoom/goxmpp/extensions/features/bind"
	"github.com/dotdoom/goxmpp/stream"
	"github.com/dotdoom/goxmpp/stream/elements/features"
)

/*type C2s struct {
	Conn          net.Conn
	Authenticated bool
}

var clients map[string]C2s*/

func C2sServer() error {
	listener, err := net.Listen("tcp", "0.0.0.0:5222")
	if err != nil {
		return err
	}

	println("Server started")
	for {
		conn, err := listener.Accept()
		if err == nil {
			go C2sConnection(conn)
		} else {
			println(err.Error())
		}
	}
}

func main() {
	err := C2sServer()
	if err != nil {
		println(err.Error())
	}
}

func C2sConnection(conn net.Conn) error {
	println("New connection")
	defer func() {
		conn.Close()
		println("Connection closed")
	}()

	st := stream.NewStream(conn)

	// Push states for all features we want to use
	//st.State.Push(&methods.GzipState{Level: 5})

	st.State.Push(&bind.BindState{
		VerifyResource: func(rc string) bool {
			fmt.Println("Using resource", rc)
			return true
		},
	})

	st.State.Push(&mechanisms.PlainState{
		Callback: func(user string, password string) bool {
			fmt.Println("Trying to auth (using PLAIN)", user)
			return true
		},
		RequireEncryption: true,
	})

	/*st.State.Push(&mechanisms.DigestMD5State{Callback: func(user string, salt string) string {
		fmt.Println("Trying to auth (using DIGEST-MD5)", user)
		return salt
	}})*/

	// Go through the features loop until stream is finally open (or something wrong happens)
	for st.Opened != true {
		st.ReadOpen()
		st.From, st.To = st.To, ""
		st.WriteOpen()

		if err := features.Loop(st); err != nil {
			fmt.Println("Features loop failed.", err)
			return err
		}
	}

	fmt.Println("Stream opened, required features passed. JID is", st.To)

	for {
		e, err := st.ReadElement()
		if err != nil {
			fmt.Printf("cannot read element: %v\n", err)
			return err
		}
		fmt.Printf("got element: %#v", e)
		if feature_handler, ok := e.(features.Handler); ok {
			fmt.Println("calling feature handler")
			if err := feature_handler.Handle(st); err != nil {
				fmt.Printf("cannot handle feature: %v\n", err)
				return err
			}
			fmt.Println("feature handler completed")
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// A simple database migrator for PostgreSQL.

package gomigrate

import (
	"bytes"
	"database/sql"
	"errors"
	"io/ioutil"
	"log"
	"path/filepath"
	"sort"
)

type migrationType string

const (
	migrationTableName = "gomigrate"
	upMigration        = migrationType("up")
	downMigration      = migrationType("down")
)

var (
	InvalidMigrationFile  = errors.New("Invalid migration file")
	InvalidMigrationPair  = errors.New("Invalid pair of migration files")
	InvalidMigrationsPath = errors.New("Invalid migrations path")
	InvalidMigrationType  = errors.New("Invalid migration type")
	NoActiveMigrations    = errors.New("No active migrations to rollback")
)

type Migrator struct {
	DB             *sql.DB
	MigrationsPath string
	dbAdapter      Migratable
	migrations     map[uint64]*Migration
}

// Returns true if the migration table already exists.
func (m *Migrator) MigrationTableExists() (bool, error) {
	row := m.DB.QueryRow(m.dbAdapter.SelectMigrationTableSql(), migrationTableName)
	var tableName string
	err := row.Scan(&tableName)
	if err == sql.ErrNoRows {
		log.Print("Migrations table not found")
		return false, nil
	}
	if err != nil {
		log.Printf("Error checking for migration table: %v", err)
		return false, err
	}
	log.Print("Migrations table found")
	return true, nil
}

// Creates the migrations table if it doesn't exist.
func (m *Migrator) CreateMigrationsTable() error {
	_, err := m.DB.Query(m.dbAdapter.CreateMigrationTableSql())
	if err != nil {
		log.Fatalf("Error creating migrations table: %v", err)
	}

	log.Printf("Created migrations table: %s", migrationTableName)

	return nil
}

// Returns a new migrator.
func NewMigrator(db *sql.DB, adapter Migratable, migrationsPath string) (*Migrator, error) {
	// Normalize the migrations path.
	path := []byte(migrationsPath)
	pathLength := len(path)
	if path[pathLength-1] != '/' {
		path = append(path, '/')
	}

	log.Printf("Migrations path: %s", path)

	migrator := Migrator{
		db,
		string(path),
		adapter,
		make(map[uint64]*Migration),
	}

	// Create the migrations table if it doesn't exist.
	tableExists, err := migrator.MigrationTableExists()
	if err != nil {
		return nil, err
	}
	if !tableExists {
		if err := migrator.CreateMigrationsTable(); err != nil {
			return nil, err
		}
	}

	// Get all metadata from the database.
	if err := migrator.fetchMigrations(); err != nil {
		return nil, err
	}
	if err := migrator.getMigrationStatuses(); err != nil {
		return nil, err
	}

	return &migrator, nil
}

// Populates a migrator with a sorted list of migrations from the file system.
func (m *Migrator) fetchMigrations() error {
	pathGlob := append([]byte(m.MigrationsPath), []byte("*")...)

	matches, err := filepath.Glob(string(pathGlob))
	if err != nil {
		log.Fatalf("Error while globbing migrations: %v", err)
	}

	for _, match := range matches {
		num, migrationType, name, err := parseMigrationPath(match)
		if err != nil {
			log.Printf("Invalid migration file found: %s", match)
			continue
		}

		log.Printf("Migration file found: %s", match)

		migration, ok := m.migrations[num]
		if !ok {
			migration = &Migration{Id: num, Name: name, Status: Inactive}
			m.migrations[num] = migration
		}
		if migrationType == upMigration {
			migration.UpPath = match
		} else {
			migration.DownPath = match
		}
	}

	// Validate each migration.
	for _, migration := range m.migrations {
		if !migration.valid() {
			path := migration.UpPath
			if path == "" {
				path = migration.DownPath
			}
			log.Printf("Invalid migration pair for path: %s", path)
			return InvalidMigrationPair
		}
	}

	log.Printf("Migrations file pairs found: %v", len(m.migrations))

	return nil
}

// Queries the migration table to determine the status of each
// migration.
func (m *Migrator) getMigrationStatuses() error {
	for _, migration := range m.migrations {
		row := m.DB.QueryRow(m.dbAdapter.GetMigrationSql(), migration.Id)
		var mid uint64
		err := row.Scan(&mid)
		if err == sql.ErrNoRows {
			continue
		}
		if err != nil {
			log.Printf(
				"Error getting migration status for %s: %v",
				migration.Name,
				err,
			)
			return err
		}
		migration.Status = Active
	}
	return nil
}

// Returns a sorted list of migration ids for a given status. -1 returns
// all migrations.
func (m *Migrator) Migrations(status int) []*Migration {
	// Sort all migration ids.
	ids := make([]uint64, 0)
	for id, _ := range m.migrations {
		ids = append(ids, id)
	}
	sort.Sort(uint64slice(ids))

	// Find ids for the given status.
	migrations := make([]*Migration, 0)
	for _, id := range ids {
		migration := m.migrations[id]
		if status == -1 || migration.Status == status {
			migrations = append(migrations, migration)
		}
	}
	return migrations
}

// Applies a single migration.
func (m *Migrator) ApplyMigration(migration *Migration, mType migrationType) error {
	var path string
	if mType == upMigration {
		path = migration.UpPath
	} else if mType == downMigration {
		path = migration.DownPath
	} else {
		return InvalidMigrationType
	}

	log.Printf("Applying migration: %s", path)

	sql, err := ioutil.ReadFile(path)
	if err != nil {
		log.Printf("Error reading migration: %s", path)
		return err
	}
	transaction, err := m.DB.Begin()
	if err != nil {
		log.Printf("Error opening transaction: %v", err)
		return err
	}

	for n, subMigration := range splitMigrationString(string(sql)) {
		if allWhitespace.Match([]byte(subMigration)) {
			continue
		}

		log.Printf("Applying submigration: %v", n+1)

		for _, line := range bytes.Split([]byte(subMigration), []byte("\n")) {
			log.Printf("MIGRATION: %s", line)
		}

		// Perform the migration.
		result, err := transaction.Exec(string(subMigration))
		if err != nil {
			log.Printf("Error executing migration: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		}
		if rowsAffected, err := result.RowsAffected(); err != nil {
			log.Printf("Error getting rows affected: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		} else {
			log.Printf("Rows affected: %v", rowsAffected)
		}
	}

	// Log the event.
	if mType == upMigration {
		_, err = transaction.Exec(
			m.dbAdapter.MigrationLogInsertSql(),
			migration.Id,
		)
	} else {
		_, err = transaction.Exec(
			m.dbAdapter.MigrationLogDeleteSql(),
			migration.Id,
		)
	}
	if err != nil {
		log.Printf("Error logging migration: %v", err)
		if rollbackErr := transaction.Rollback(); rollbackErr != nil {
			log.Printf("Error rolling back transaction: %v", rollbackErr)
			return rollbackErr
		}
		return err
	}

	// Commit and update the struct status.
	if err := transaction.Commit(); err != nil {
		log.Printf("Error commiting transaction: %v", err)
		return err
	}
	if mType == upMigration {
		migration.Status = Active
	} else {
		migration.Status = Inactive
	}

	return nil
}

// Applies all inactive migrations.
func (m *Migrator) Migrate() error {
	for _, migration := range m.Migrations(Inactive) {
		if err := m.ApplyMigration(migration, upMigration); err != nil {
			return err
		}
	}
	return nil
}

// Rolls back the last migration.
func (m *Migrator) Rollback() error {
	return m.RollbackN(1)
}

// Rolls back N migrations.
func (m *Migrator) RollbackN(n int) error {
	migrations := m.Migrations(Active)
	if len(migrations) == 0 {
		return NoActiveMigrations
	}

	last_migration := len(migrations) - 1 - n

	for i := len(migrations) - 1; i != last_migration; i-- {
		if err := m.ApplyMigration(migrations[i], downMigration); err != nil {
			return err
		}
	}

	return nil
}

// Rolls back all migrations.
func (m *Migrator) RollbackAll(n int) error {
	migrations := m.Migrations(Active)
	return m.RollbackN(len(migrations))
}
<commit_msg>Don't take args for RollbackAll<commit_after>// A simple database migrator for PostgreSQL.

package gomigrate

import (
	"bytes"
	"database/sql"
	"errors"
	"io/ioutil"
	"log"
	"path/filepath"
	"sort"
)

type migrationType string

const (
	migrationTableName = "gomigrate"
	upMigration        = migrationType("up")
	downMigration      = migrationType("down")
)

var (
	InvalidMigrationFile  = errors.New("Invalid migration file")
	InvalidMigrationPair  = errors.New("Invalid pair of migration files")
	InvalidMigrationsPath = errors.New("Invalid migrations path")
	InvalidMigrationType  = errors.New("Invalid migration type")
	NoActiveMigrations    = errors.New("No active migrations to rollback")
)

type Migrator struct {
	DB             *sql.DB
	MigrationsPath string
	dbAdapter      Migratable
	migrations     map[uint64]*Migration
}

// Returns true if the migration table already exists.
func (m *Migrator) MigrationTableExists() (bool, error) {
	row := m.DB.QueryRow(m.dbAdapter.SelectMigrationTableSql(), migrationTableName)
	var tableName string
	err := row.Scan(&tableName)
	if err == sql.ErrNoRows {
		log.Print("Migrations table not found")
		return false, nil
	}
	if err != nil {
		log.Printf("Error checking for migration table: %v", err)
		return false, err
	}
	log.Print("Migrations table found")
	return true, nil
}

// Creates the migrations table if it doesn't exist.
func (m *Migrator) CreateMigrationsTable() error {
	_, err := m.DB.Query(m.dbAdapter.CreateMigrationTableSql())
	if err != nil {
		log.Fatalf("Error creating migrations table: %v", err)
	}

	log.Printf("Created migrations table: %s", migrationTableName)

	return nil
}

// Returns a new migrator.
func NewMigrator(db *sql.DB, adapter Migratable, migrationsPath string) (*Migrator, error) {
	// Normalize the migrations path.
	path := []byte(migrationsPath)
	pathLength := len(path)
	if path[pathLength-1] != '/' {
		path = append(path, '/')
	}

	log.Printf("Migrations path: %s", path)

	migrator := Migrator{
		db,
		string(path),
		adapter,
		make(map[uint64]*Migration),
	}

	// Create the migrations table if it doesn't exist.
	tableExists, err := migrator.MigrationTableExists()
	if err != nil {
		return nil, err
	}
	if !tableExists {
		if err := migrator.CreateMigrationsTable(); err != nil {
			return nil, err
		}
	}

	// Get all metadata from the database.
	if err := migrator.fetchMigrations(); err != nil {
		return nil, err
	}
	if err := migrator.getMigrationStatuses(); err != nil {
		return nil, err
	}

	return &migrator, nil
}

// Populates a migrator with a sorted list of migrations from the file system.
func (m *Migrator) fetchMigrations() error {
	pathGlob := append([]byte(m.MigrationsPath), []byte("*")...)

	matches, err := filepath.Glob(string(pathGlob))
	if err != nil {
		log.Fatalf("Error while globbing migrations: %v", err)
	}

	for _, match := range matches {
		num, migrationType, name, err := parseMigrationPath(match)
		if err != nil {
			log.Printf("Invalid migration file found: %s", match)
			continue
		}

		log.Printf("Migration file found: %s", match)

		migration, ok := m.migrations[num]
		if !ok {
			migration = &Migration{Id: num, Name: name, Status: Inactive}
			m.migrations[num] = migration
		}
		if migrationType == upMigration {
			migration.UpPath = match
		} else {
			migration.DownPath = match
		}
	}

	// Validate each migration.
	for _, migration := range m.migrations {
		if !migration.valid() {
			path := migration.UpPath
			if path == "" {
				path = migration.DownPath
			}
			log.Printf("Invalid migration pair for path: %s", path)
			return InvalidMigrationPair
		}
	}

	log.Printf("Migrations file pairs found: %v", len(m.migrations))

	return nil
}

// Queries the migration table to determine the status of each
// migration.
func (m *Migrator) getMigrationStatuses() error {
	for _, migration := range m.migrations {
		row := m.DB.QueryRow(m.dbAdapter.GetMigrationSql(), migration.Id)
		var mid uint64
		err := row.Scan(&mid)
		if err == sql.ErrNoRows {
			continue
		}
		if err != nil {
			log.Printf(
				"Error getting migration status for %s: %v",
				migration.Name,
				err,
			)
			return err
		}
		migration.Status = Active
	}
	return nil
}

// Returns a sorted list of migration ids for a given status. -1 returns
// all migrations.
func (m *Migrator) Migrations(status int) []*Migration {
	// Sort all migration ids.
	ids := make([]uint64, 0)
	for id, _ := range m.migrations {
		ids = append(ids, id)
	}
	sort.Sort(uint64slice(ids))

	// Find ids for the given status.
	migrations := make([]*Migration, 0)
	for _, id := range ids {
		migration := m.migrations[id]
		if status == -1 || migration.Status == status {
			migrations = append(migrations, migration)
		}
	}
	return migrations
}

// Applies a single migration.
func (m *Migrator) ApplyMigration(migration *Migration, mType migrationType) error {
	var path string
	if mType == upMigration {
		path = migration.UpPath
	} else if mType == downMigration {
		path = migration.DownPath
	} else {
		return InvalidMigrationType
	}

	log.Printf("Applying migration: %s", path)

	sql, err := ioutil.ReadFile(path)
	if err != nil {
		log.Printf("Error reading migration: %s", path)
		return err
	}
	transaction, err := m.DB.Begin()
	if err != nil {
		log.Printf("Error opening transaction: %v", err)
		return err
	}

	for n, subMigration := range splitMigrationString(string(sql)) {
		if allWhitespace.Match([]byte(subMigration)) {
			continue
		}

		log.Printf("Applying submigration: %v", n+1)

		for _, line := range bytes.Split([]byte(subMigration), []byte("\n")) {
			log.Printf("MIGRATION: %s", line)
		}

		// Perform the migration.
		result, err := transaction.Exec(string(subMigration))
		if err != nil {
			log.Printf("Error executing migration: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		}
		if rowsAffected, err := result.RowsAffected(); err != nil {
			log.Printf("Error getting rows affected: %v", err)
			if rollbackErr := transaction.Rollback(); rollbackErr != nil {
				log.Printf("Error rolling back transaction: %v", rollbackErr)
				return rollbackErr
			}
			return err
		} else {
			log.Printf("Rows affected: %v", rowsAffected)
		}
	}

	// Log the event.
	if mType == upMigration {
		_, err = transaction.Exec(
			m.dbAdapter.MigrationLogInsertSql(),
			migration.Id,
		)
	} else {
		_, err = transaction.Exec(
			m.dbAdapter.MigrationLogDeleteSql(),
			migration.Id,
		)
	}
	if err != nil {
		log.Printf("Error logging migration: %v", err)
		if rollbackErr := transaction.Rollback(); rollbackErr != nil {
			log.Printf("Error rolling back transaction: %v", rollbackErr)
			return rollbackErr
		}
		return err
	}

	// Commit and update the struct status.
	if err := transaction.Commit(); err != nil {
		log.Printf("Error commiting transaction: %v", err)
		return err
	}
	if mType == upMigration {
		migration.Status = Active
	} else {
		migration.Status = Inactive
	}

	return nil
}

// Applies all inactive migrations.
func (m *Migrator) Migrate() error {
	for _, migration := range m.Migrations(Inactive) {
		if err := m.ApplyMigration(migration, upMigration); err != nil {
			return err
		}
	}
	return nil
}

// Rolls back the last migration.
func (m *Migrator) Rollback() error {
	return m.RollbackN(1)
}

// Rolls back N migrations.
func (m *Migrator) RollbackN(n int) error {
	migrations := m.Migrations(Active)
	if len(migrations) == 0 {
		return NoActiveMigrations
	}

	last_migration := len(migrations) - 1 - n

	for i := len(migrations) - 1; i != last_migration; i-- {
		if err := m.ApplyMigration(migrations[i], downMigration); err != nil {
			return err
		}
	}

	return nil
}

// Rolls back all migrations.
func (m *Migrator) RollbackAll() error {
	migrations := m.Migrations(Active)
	return m.RollbackN(len(migrations))
}
<|endoftext|>


<commit_before>package gonp

import (
	"testing"
)

func equalsSesElemArray(ses1, ses2 []SesElem) bool {
	m, n := len(ses1), len(ses2)
	if m != n {
		return true
	}
	for i := 0; i < m; i++ {
		if ses1[i].e != ses2[i].e || ses1[i].t != ses2[i].t {
			return false
		}
	}
	return true
}

func assert(t *testing.T, b bool) {
	if !b {
		t.Fail()
	}
}

func TestDiff1(t *testing.T) {
	diff := New("abc", "abd")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesCommon},
		{e: 'b', t: SesCommon},
		{e: 'c', t: SesDelete},
		{e: 'd', t: SesAdd},
	}
	assert(t, diff.Editdistance() == 2)
	assert(t, lcs == "ab")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff2(t *testing.T) {
	diff := New("abcdef", "dacfea")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'd', t: SesAdd},
		{e: 'a', t: SesCommon},
		{e: 'b', t: SesDelete},
		{e: 'c', t: SesCommon},
		{e: 'd', t: SesDelete},
		{e: 'e', t: SesDelete},
		{e: 'f', t: SesCommon},
		{e: 'e', t: SesAdd},
		{e: 'a', t: SesAdd},
	}
	assert(t, diff.Editdistance() == 6)
	assert(t, lcs == "acf")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff3(t *testing.T) {
	diff := New("acbdeacbed", "acebdabbabed")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesCommon},
		{e: 'c', t: SesCommon},
		{e: 'e', t: SesAdd},
		{e: 'b', t: SesCommon},
		{e: 'd', t: SesCommon},
		{e: 'e', t: SesDelete},
		{e: 'a', t: SesCommon},
		{e: 'c', t: SesDelete},
		{e: 'b', t: SesCommon},
		{e: 'b', t: SesAdd},
		{e: 'a', t: SesAdd},
		{e: 'b', t: SesAdd},
		{e: 'e', t: SesCommon},
		{e: 'd', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 6)
	assert(t, lcs == "acbdabed")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff4(t *testing.T) {
	diff := New("abcbda", "bdcaba")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesDelete},
		{e: 'b', t: SesCommon},
		{e: 'd', t: SesAdd},
		{e: 'c', t: SesCommon},
		{e: 'a', t: SesAdd},
		{e: 'b', t: SesCommon},
		{e: 'd', t: SesDelete},
		{e: 'a', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 4)
	assert(t, lcs == "bcba")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff5(t *testing.T) {
	diff := New("bokko", "bokkko")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'b', t: SesCommon},
		{e: 'o', t: SesCommon},
		{e: 'k', t: SesCommon},
		{e: 'k', t: SesCommon},
		{e: 'k', t: SesAdd},
		{e: 'o', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 1)
	assert(t, lcs == "bokko")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffEmptyString1(t *testing.T) {
	diff := New("", "")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{}
	assert(t, diff.Editdistance() == 0)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffEmptyString2(t *testing.T) {
	diff := New("a", "")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesDelete},
	}
	assert(t, diff.Editdistance() == 1)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffEmptyString3(t *testing.T) {
	diff := New("", "b")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'b', t: SesAdd},
	}
	assert(t, diff.Editdistance() == 1)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffMultiByteString(t *testing.T) {
	diff := New("久保竜彦", "久保達彦")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: '久', t: SesCommon},
		{e: '保', t: SesCommon},
		{e: '竜', t: SesDelete},
		{e: '達', t: SesAdd},
		{e: '彦', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 2)
	assert(t, lcs == "久保彦")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffOnlyEditdistance(t *testing.T) {
	diff := New("abc", "abd")
	diff.OnlyEd()
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{}
	assert(t, diff.Editdistance() == 2)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}
<commit_msg>add some test<commit_after>package gonp

import (
	"testing"
)

func equalsSesElemArray(ses1, ses2 []SesElem) bool {
	m, n := len(ses1), len(ses2)
	if m != n {
		return true
	}
	for i := 0; i < m; i++ {
		if ses1[i].e != ses2[i].e || ses1[i].t != ses2[i].t {
			return false
		}
	}
	return true
}

func assert(t *testing.T, b bool) {
	if !b {
		t.Fail()
	}
}

func TestDiff1(t *testing.T) {
	diff := New("abc", "abd")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesCommon},
		{e: 'b', t: SesCommon},
		{e: 'c', t: SesDelete},
		{e: 'd', t: SesAdd},
	}
	assert(t, diff.Editdistance() == 2)
	assert(t, lcs == "ab")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff2(t *testing.T) {
	diff := New("abcdef", "dacfea")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'd', t: SesAdd},
		{e: 'a', t: SesCommon},
		{e: 'b', t: SesDelete},
		{e: 'c', t: SesCommon},
		{e: 'd', t: SesDelete},
		{e: 'e', t: SesDelete},
		{e: 'f', t: SesCommon},
		{e: 'e', t: SesAdd},
		{e: 'a', t: SesAdd},
	}
	assert(t, diff.Editdistance() == 6)
	assert(t, lcs == "acf")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff3(t *testing.T) {
	diff := New("acbdeacbed", "acebdabbabed")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesCommon},
		{e: 'c', t: SesCommon},
		{e: 'e', t: SesAdd},
		{e: 'b', t: SesCommon},
		{e: 'd', t: SesCommon},
		{e: 'e', t: SesDelete},
		{e: 'a', t: SesCommon},
		{e: 'c', t: SesDelete},
		{e: 'b', t: SesCommon},
		{e: 'b', t: SesAdd},
		{e: 'a', t: SesAdd},
		{e: 'b', t: SesAdd},
		{e: 'e', t: SesCommon},
		{e: 'd', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 6)
	assert(t, lcs == "acbdabed")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff4(t *testing.T) {
	diff := New("abcbda", "bdcaba")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesDelete},
		{e: 'b', t: SesCommon},
		{e: 'd', t: SesAdd},
		{e: 'c', t: SesCommon},
		{e: 'a', t: SesAdd},
		{e: 'b', t: SesCommon},
		{e: 'd', t: SesDelete},
		{e: 'a', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 4)
	assert(t, lcs == "bcba")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiff5(t *testing.T) {
	diff := New("bokko", "bokkko")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'b', t: SesCommon},
		{e: 'o', t: SesCommon},
		{e: 'k', t: SesCommon},
		{e: 'k', t: SesCommon},
		{e: 'k', t: SesAdd},
		{e: 'o', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 1)
	assert(t, lcs == "bokko")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffEmptyString1(t *testing.T) {
	diff := New("", "")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{}
	assert(t, diff.Editdistance() == 0)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffEmptyString2(t *testing.T) {
	diff := New("a", "")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'a', t: SesDelete},
	}
	assert(t, diff.Editdistance() == 1)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffEmptyString3(t *testing.T) {
	diff := New("", "b")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: 'b', t: SesAdd},
	}
	assert(t, diff.Editdistance() == 1)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffMultiByteString(t *testing.T) {
	diff := New("久保竜彦", "久保達彦")
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{
		{e: '久', t: SesCommon},
		{e: '保', t: SesCommon},
		{e: '竜', t: SesDelete},
		{e: '達', t: SesAdd},
		{e: '彦', t: SesCommon},
	}
	assert(t, diff.Editdistance() == 2)
	assert(t, lcs == "久保彦")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffOnlyEditdistance(t *testing.T) {
	diff := New("abc", "abd")
	diff.OnlyEd()
	diff.Compose()
	lcs := diff.LcsString()
	sesActual := diff.Ses()
	sesExpected := []SesElem{}
	assert(t, diff.Editdistance() == 2)
	assert(t, lcs == "")
	assert(t, equalsSesElemArray(sesActual, sesExpected))
}

func TestDiffSprintSes(t *testing.T) {
	diff := New("a\nb\nc", "a\n1\nc")
	diff.Compose()
	ses := diff.SprintSes()
	assert(t, ses == "  a\n  \n\n- b\n+ 1\n  \n\n  c\n")
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"path/filepath"
	"fmt"
	"regexp"
	"bytes"
	goopt "github.com/droundy/goopt"
	"./highlight"
)

var Author = "Alexander Solovyov"
var Version = "0.2"
var Summary = "gr [OPTS] string-to-search\n"
var Description = `Go search and replace (not done yet) in files`

var byteNewLine []byte = []byte("\n")
// FIXME: global variable :(
// Used to prevent appear of sparse newline at the end of output
var prependNewLine = false

type StringList []string

var IgnoreDirs = StringList{"autom4te.cache", "blib", "_build", ".bzr", ".cdv",
	"cover_db", "CVS", "_darcs", "~.dep", "~.dot", ".git", ".hg", "~.nib",
	".pc", "~.plst", "RCS", "SCCS", "_sgbak", ".svn", "_obj"}

type RegexpList []*regexp.Regexp

var IgnoreFiles = regexpList([]string{`~$`, `#.+#$`, `[._].*\.swp$`, `core\.[0-9]+$`,
	`\.pyc$`, `\.o$`, `\.6$`})

var onlyName = goopt.Flag([]string{"-n", "--filename"}, []string{},
	"print only filenames", "")
var ignoreFiles = goopt.Strings([]string{"-x", "--exclude"}, "RE",
	"exclude files that match the regexp from search")
var singleline = goopt.Flag([]string{"-s", "--singleline"}, []string{},
	"match on a single line (^/$ will be beginning/end of line)", "")
var replace = goopt.String([]string{"-r", "--replace"}, "",
	"replace found substrings with this string")
var force = goopt.Flag([]string{"-f", "--force"}, []string{},
	"force replacement in binary files", "")

func main() {
	goopt.Author = Author
	goopt.Version = Version
	goopt.Summary = Summary
	goopt.Description = func() string { return Description }
	goopt.Parse(nil)

	if len(goopt.Args) == 0 {
		println(goopt.Usage())
		return
	}

	IgnoreFiles = append(IgnoreFiles, regexpList(*ignoreFiles)...)

	pattern, err := regexp.Compile(goopt.Args[0])
	errhandle(err, true, "can't compile regexp %s", goopt.Args[0])

	searchFiles(pattern)
}

func errhandle(err os.Error, exit bool, moreinfo string, a ...interface{}) {
	if err == nil {
		return
	}
	fmt.Fprintf(os.Stderr, "ERR %s\n%s\n", err,
		fmt.Sprintf(moreinfo, a...))
	if exit {
		os.Exit(1)
	}
}

func regexpList(sa []string) RegexpList {
	ra := make(RegexpList, len(sa))
	for i, s := range sa {
		ra[i] = regexp.MustCompile(s)
	}
	return ra
}

func searchFiles(pattern *regexp.Regexp) {
	v := &GRVisitor{pattern}

	errors := make(chan os.Error, 64)

	filepath.Walk(".", v, errors)

	select {
	case err := <-errors:
		errhandle(err, true, "some error")
	default:
	}
}

type GRVisitor struct {
	pattern *regexp.Regexp
}

func (v *GRVisitor) VisitDir(fn string, fi *os.FileInfo) bool {
	if IgnoreDirs.Contains(fi.Name) {
		return false
	}
	return true
}

func (v *GRVisitor) VisitFile(fn string, fi *os.FileInfo) {
	if !fi.IsRegular() {
		return
	}

	if fi.Size >= 1024*1024*10 {
		fmt.Fprintf(os.Stderr, "Skipping %s, too big: %d\n", fn, fi.Size)
		return
	}

	if fi.Size == 0 {
		return
	}

	if IgnoreFiles.Match(fn) {
		return
	}

	f, content := v.GetFileAndContent(fn, fi)

	if len(*replace) > 0 {
		changed, result := v.ReplaceInFile(fn, content)
		if changed {
			f.Seek(0, 0)
			n, err := f.Write(result)
			errhandle(err, true, "Error writing replacement in file %s", fn)
			if int64(n) > fi.Size {
				err := f.Truncate(int64(n))
				errhandle(err, true, "Error truncating file to size %d", f)
			}
		}
	} else {
		v.SearchFile(fn, content)
	}

	f.Close()
}

func (v *GRVisitor) GetFileAndContent(fn string, fi *os.FileInfo) (f *os.File, content []byte) {
	var err os.Error
	var msg string

	if len(*replace) > 0 {
		f, err = os.Open(fn, os.O_RDWR, 0666)
		msg = "can't open file %s for reading and writing"
	} else {
		f, err = os.Open(fn, os.O_RDONLY, 0666)
		msg = "can't open file %s for reading"
	}

	if err != nil {
		errhandle(err, false, msg, fn)
		return
	}

	content = make([]byte, fi.Size)
	n, err := f.Read(content)
	errhandle(err, true, "can't read file %s", fn)
	if int64(n) != fi.Size {
		panic(fmt.Sprintf("Not whole file was read, only %d from %d",
			n, fi.Size))
	}

	return
}

func (v *GRVisitor) SearchFile(fn string, content []byte) {
	lines := IntList([]int{})
	binary := false

	if bytes.IndexByte(content, 0) != -1 {
		binary = true
	}

	for _, info := range v.FindAllIndex(content) {
		if lines.Contains(info.num) {
			continue
		}

		if prependNewLine {
			fmt.Println("")
			prependNewLine = false
		}

		var first = len(lines) == 0
		lines = append(lines, info.num)

		if first {
			if binary && !*onlyName {
				fmt.Printf("Binary file %s matches\n", fn)
				break
			} else {
				highlight.Printf("green", "%s\n", fn)
			}
		}

		if *onlyName {
			return
		}

		highlight.Printf("bold yellow", "%d:", info.num)
		highlight.Reprintlnf("on_yellow", v.pattern, "%s", info.line)
	}

	if len(lines) > 0 {
		prependNewLine = true
	}
}

func (v *GRVisitor) ReplaceInFile(fn string, content []byte) (changed bool, result []byte) {
	changed = false
	binary := false
	changenum := 0

	if *singleline {
		panic("Can't handle singleline replacements yet")
	}

	if bytes.IndexByte(content, 0) != -1 {
		binary = true
	}

	result = v.pattern.ReplaceAllFunc(content, func (s []byte) []byte {
		if binary && !*force {
			errhandle(
				os.NewError("supply --force to force change of binary file"),
				false, "")
		}
		if !changed {
			changed = true
			highlight.Printf("green", "%s", fn)
		}

		changenum += 1
		return []byte(*replace)
	})

	highlight.Printf("bold yellow", " - %d changes made\n", changenum)

	return changed, result
}

type LineInfo struct {
	num  int
	line []byte
}

// will return slice of [linenum, line] slices
func (v *GRVisitor) FindAllIndex(content []byte) (res []*LineInfo) {
	linenum := 1

	if *singleline {
		begin, end := 0, 0
		for i := 0; i < len(content); i++ {
			if content[i] == '\n' {
				end = i
				line := content[begin:end]
				if v.pattern.Match(line) {
					res = append(res, &LineInfo{linenum, line})
				}
				linenum += 1
				begin = end + 1
			}
		}
		return res
	}

	last := 0
	for _, bounds := range v.pattern.FindAllIndex(content, -1) {
		linenum += bytes.Count(content[last:bounds[0]], byteNewLine)
		last = bounds[0]
		begin, end := beginend(content, bounds[0], bounds[1])
		res = append(res, &LineInfo{linenum, content[begin:end]})
	}
	return res
}

// Given a []byte, start and finish of some inner slice, will find nearest
// newlines on both ends of this slice
func beginend(s []byte, start int, finish int) (begin int, end int) {
	begin = 0
	end = len(s)

	for i := start; i >= 0; i-- {
		if s[i] == byteNewLine[0] {
			begin = i + 1
			break
		}
	}

	// -1 to check if current location is not end of string
	for i := finish - 1; i < len(s); i++ {
		if s[i] == byteNewLine[0] {
			end = i
			break
		}
	}

	return
}

type IntList []int
func (il IntList) Contains(i int) bool {
	for _, x := range il {
		if x == i {
			return true
		}
	}
	return false
}

func (sl StringList) Contains(s string) bool {
	for _, x := range sl {
		if x == s {
			return true
		}
	}
	return false
}

func (rl RegexpList) Match(s string) bool {
	for _, x := range rl {
		if x.Match([]byte(s)) {
			return true
		}
	}
	return false
}
<commit_msg>drop short option for force<commit_after>package main

import (
	"os"
	"path/filepath"
	"fmt"
	"regexp"
	"bytes"
	goopt "github.com/droundy/goopt"
	"./highlight"
)

var Author = "Alexander Solovyov"
var Version = "0.2"
var Summary = "gr [OPTS] string-to-search\n"
var Description = `Go search and replace (not done yet) in files`

var byteNewLine []byte = []byte("\n")
// FIXME: global variable :(
// Used to prevent appear of sparse newline at the end of output
var prependNewLine = false

type StringList []string

var IgnoreDirs = StringList{"autom4te.cache", "blib", "_build", ".bzr", ".cdv",
	"cover_db", "CVS", "_darcs", "~.dep", "~.dot", ".git", ".hg", "~.nib",
	".pc", "~.plst", "RCS", "SCCS", "_sgbak", ".svn", "_obj"}

type RegexpList []*regexp.Regexp

var IgnoreFiles = regexpList([]string{`~$`, `#.+#$`, `[._].*\.swp$`, `core\.[0-9]+$`,
	`\.pyc$`, `\.o$`, `\.6$`})

var onlyName = goopt.Flag([]string{"-n", "--filename"}, []string{},
	"print only filenames", "")
var ignoreFiles = goopt.Strings([]string{"-x", "--exclude"}, "RE",
	"exclude files that match the regexp from search")
var singleline = goopt.Flag([]string{"-s", "--singleline"}, []string{},
	"match on a single line (^/$ will be beginning/end of line)", "")
var replace = goopt.String([]string{"-r", "--replace"}, "",
	"replace found substrings with this string")
var force = goopt.Flag([]string{"--force"}, []string{},
	"force replacement in binary files", "")

func main() {
	goopt.Author = Author
	goopt.Version = Version
	goopt.Summary = Summary
	goopt.Description = func() string { return Description }
	goopt.Parse(nil)

	if len(goopt.Args) == 0 {
		println(goopt.Usage())
		return
	}

	IgnoreFiles = append(IgnoreFiles, regexpList(*ignoreFiles)...)

	pattern, err := regexp.Compile(goopt.Args[0])
	errhandle(err, true, "can't compile regexp %s", goopt.Args[0])

	searchFiles(pattern)
}

func errhandle(err os.Error, exit bool, moreinfo string, a ...interface{}) {
	if err == nil {
		return
	}
	fmt.Fprintf(os.Stderr, "ERR %s\n%s\n", err,
		fmt.Sprintf(moreinfo, a...))
	if exit {
		os.Exit(1)
	}
}

func regexpList(sa []string) RegexpList {
	ra := make(RegexpList, len(sa))
	for i, s := range sa {
		ra[i] = regexp.MustCompile(s)
	}
	return ra
}

func searchFiles(pattern *regexp.Regexp) {
	v := &GRVisitor{pattern}

	errors := make(chan os.Error, 64)

	filepath.Walk(".", v, errors)

	select {
	case err := <-errors:
		errhandle(err, true, "some error")
	default:
	}
}

type GRVisitor struct {
	pattern *regexp.Regexp
}

func (v *GRVisitor) VisitDir(fn string, fi *os.FileInfo) bool {
	if IgnoreDirs.Contains(fi.Name) {
		return false
	}
	return true
}

func (v *GRVisitor) VisitFile(fn string, fi *os.FileInfo) {
	if !fi.IsRegular() {
		return
	}

	if fi.Size >= 1024*1024*10 {
		fmt.Fprintf(os.Stderr, "Skipping %s, too big: %d\n", fn, fi.Size)
		return
	}

	if fi.Size == 0 {
		return
	}

	if IgnoreFiles.Match(fn) {
		return
	}

	f, content := v.GetFileAndContent(fn, fi)

	if len(*replace) > 0 {
		changed, result := v.ReplaceInFile(fn, content)
		if changed {
			f.Seek(0, 0)
			n, err := f.Write(result)
			errhandle(err, true, "Error writing replacement in file %s", fn)
			if int64(n) > fi.Size {
				err := f.Truncate(int64(n))
				errhandle(err, true, "Error truncating file to size %d", f)
			}
		}
	} else {
		v.SearchFile(fn, content)
	}

	f.Close()
}

func (v *GRVisitor) GetFileAndContent(fn string, fi *os.FileInfo) (f *os.File, content []byte) {
	var err os.Error
	var msg string

	if len(*replace) > 0 {
		f, err = os.Open(fn, os.O_RDWR, 0666)
		msg = "can't open file %s for reading and writing"
	} else {
		f, err = os.Open(fn, os.O_RDONLY, 0666)
		msg = "can't open file %s for reading"
	}

	if err != nil {
		errhandle(err, false, msg, fn)
		return
	}

	content = make([]byte, fi.Size)
	n, err := f.Read(content)
	errhandle(err, true, "can't read file %s", fn)
	if int64(n) != fi.Size {
		panic(fmt.Sprintf("Not whole file was read, only %d from %d",
			n, fi.Size))
	}

	return
}

func (v *GRVisitor) SearchFile(fn string, content []byte) {
	lines := IntList([]int{})
	binary := false

	if bytes.IndexByte(content, 0) != -1 {
		binary = true
	}

	for _, info := range v.FindAllIndex(content) {
		if lines.Contains(info.num) {
			continue
		}

		if prependNewLine {
			fmt.Println("")
			prependNewLine = false
		}

		var first = len(lines) == 0
		lines = append(lines, info.num)

		if first {
			if binary && !*onlyName {
				fmt.Printf("Binary file %s matches\n", fn)
				break
			} else {
				highlight.Printf("green", "%s\n", fn)
			}
		}

		if *onlyName {
			return
		}

		highlight.Printf("bold yellow", "%d:", info.num)
		highlight.Reprintlnf("on_yellow", v.pattern, "%s", info.line)
	}

	if len(lines) > 0 {
		prependNewLine = true
	}
}

func (v *GRVisitor) ReplaceInFile(fn string, content []byte) (changed bool, result []byte) {
	changed = false
	binary := false
	changenum := 0

	if *singleline {
		panic("Can't handle singleline replacements yet")
	}

	if bytes.IndexByte(content, 0) != -1 {
		binary = true
	}

	result = v.pattern.ReplaceAllFunc(content, func (s []byte) []byte {
		if binary && !*force {
			errhandle(
				os.NewError("supply --force to force change of binary file"),
				false, "")
		}
		if !changed {
			changed = true
			highlight.Printf("green", "%s", fn)
		}

		changenum += 1
		return []byte(*replace)
	})

	highlight.Printf("bold yellow", " - %d changes made\n", changenum)

	return changed, result
}

type LineInfo struct {
	num  int
	line []byte
}

// will return slice of [linenum, line] slices
func (v *GRVisitor) FindAllIndex(content []byte) (res []*LineInfo) {
	linenum := 1

	if *singleline {
		begin, end := 0, 0
		for i := 0; i < len(content); i++ {
			if content[i] == '\n' {
				end = i
				line := content[begin:end]
				if v.pattern.Match(line) {
					res = append(res, &LineInfo{linenum, line})
				}
				linenum += 1
				begin = end + 1
			}
		}
		return res
	}

	last := 0
	for _, bounds := range v.pattern.FindAllIndex(content, -1) {
		linenum += bytes.Count(content[last:bounds[0]], byteNewLine)
		last = bounds[0]
		begin, end := beginend(content, bounds[0], bounds[1])
		res = append(res, &LineInfo{linenum, content[begin:end]})
	}
	return res
}

// Given a []byte, start and finish of some inner slice, will find nearest
// newlines on both ends of this slice
func beginend(s []byte, start int, finish int) (begin int, end int) {
	begin = 0
	end = len(s)

	for i := start; i >= 0; i-- {
		if s[i] == byteNewLine[0] {
			begin = i + 1
			break
		}
	}

	// -1 to check if current location is not end of string
	for i := finish - 1; i < len(s); i++ {
		if s[i] == byteNewLine[0] {
			end = i
			break
		}
	}

	return
}

type IntList []int
func (il IntList) Contains(i int) bool {
	for _, x := range il {
		if x == i {
			return true
		}
	}
	return false
}

func (sl StringList) Contains(s string) bool {
	for _, x := range sl {
		if x == s {
			return true
		}
	}
	return false
}

func (rl RegexpList) Match(s string) bool {
	for _, x := range rl {
		if x.Match([]byte(s)) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package processorcommand

import (
	"fmt"

	"github.com/Imgur/mandible/imageprocessor/thumbType"
)

const GM_COMMAND = "convert"

func ConvertToJpeg(filename string) (string, error) {
	outfile := fmt.Sprintf("%s_jpg", filename)

	args := []string{
		filename,
		"-flatten",
		"JPEG:" + outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func FixOrientation(filename string) (string, error) {
	outfile := fmt.Sprintf("%s_ort", filename)

	args := []string{
		filename,
		"-auto-orient",
		outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func Quality(filename string, quality int) (string, error) {
	outfile := fmt.Sprintf("%s_q", filename)

	args := []string{
		filename,
		"-quality",
		fmt.Sprintf("%d", quality),
		"-density",
		"72x72",
		outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func ResizePercent(filename string, percent int) (string, error) {
	outfile := fmt.Sprintf("%s_rp", filename)

	args := []string{
		filename,
		"-resize",
		fmt.Sprintf("%d%%", percent),
		outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func SquareThumb(filename, name string, size int, format thumbType.ThumbType) (string, error) {
	outfile := fmt.Sprintf("%s_%s", filename, name)

	args := []string{
		fmt.Sprintf("%s[0]", filename),
		"-quality",
		"94",
		"-resize",
		fmt.Sprintf("%dx%d^", size, size),
		"-gravity",
		"center",
		"-crop",
		fmt.Sprintf("%dx%d+0+0", size, size),
		"-density",
		"72x72",
		"-unsharp",
		"0.5",
		fmt.Sprintf("%s:%s", format.ToString(), outfile),
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func Thumb(filename, name string, width, height int, format thumbType.ThumbType) (string, error) {
	outfile := fmt.Sprintf("%s_%s", filename, name)

	args := []string{
		fmt.Sprintf("%s[0]", filename),
		"-quality",
		"83",
		"-resize",
		fmt.Sprintf("%dx%d>", width, height),
		"-density",
		"72x72",
		fmt.Sprintf("%s:%s", format.ToString(), outfile),
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func CircleThumb(filename, name string, width int, format thumbType.ThumbType) (string, error) {
	outfile := fmt.Sprintf("%s_%s", filename, name)

	filename, err := Thumb(filename, name, width*2, width*2, format)
	if err != nil {
		return "", err
	}

	args := []string{
		"-size",
		fmt.Sprintf("%dx%d", width, width),
		"xc:none",
		"-fill",
		filename,
		"-quality",
		"83",
		"-density",
		"72x72",
		"-draw",
		fmt.Sprintf("circle %d,%d %d,1", width/2, width/2, width/2),
		fmt.Sprintf("%s:%s", format.ToString(), outfile),
	}

	err = runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}
<commit_msg>update circle thumb<commit_after>package processorcommand

import (
	"fmt"

	"github.com/Imgur/mandible/imageprocessor/thumbType"
)

const GM_COMMAND = "convert"

func ConvertToJpeg(filename string) (string, error) {
	outfile := fmt.Sprintf("%s_jpg", filename)

	args := []string{
		filename,
		"-flatten",
		"JPEG:" + outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func FixOrientation(filename string) (string, error) {
	outfile := fmt.Sprintf("%s_ort", filename)

	args := []string{
		filename,
		"-auto-orient",
		outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func Quality(filename string, quality int) (string, error) {
	outfile := fmt.Sprintf("%s_q", filename)

	args := []string{
		filename,
		"-quality",
		fmt.Sprintf("%d", quality),
		"-density",
		"72x72",
		outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func ResizePercent(filename string, percent int) (string, error) {
	outfile := fmt.Sprintf("%s_rp", filename)

	args := []string{
		filename,
		"-resize",
		fmt.Sprintf("%d%%", percent),
		outfile,
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func SquareThumb(filename, name string, size int, format thumbType.ThumbType) (string, error) {
	outfile := fmt.Sprintf("%s_%s", filename, name)

	args := []string{
		fmt.Sprintf("%s[0]", filename),
		"-quality",
		"94",
		"-resize",
		fmt.Sprintf("%dx%d^", size, size),
		"-gravity",
		"center",
		"-crop",
		fmt.Sprintf("%dx%d+0+0", size, size),
		"-density",
		"72x72",
		"-unsharp",
		"0.5",
		fmt.Sprintf("%s:%s", format.ToString(), outfile),
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func Thumb(filename, name string, width, height int, format thumbType.ThumbType) (string, error) {
	outfile := fmt.Sprintf("%s_%s", filename, name)

	args := []string{
		fmt.Sprintf("%s[0]", filename),
		"-quality",
		"83",
		"-resize",
		fmt.Sprintf("%dx%d>", width, height),
		"-density",
		"72x72",
		fmt.Sprintf("%s:%s", format.ToString(), outfile),
	}

	err := runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}

func CircleThumb(filename, name string, width int, format thumbType.ThumbType) (string, error) {
	outfile := fmt.Sprintf("%s_%s", filename, name)

	filename, err := SquareThumb(filename, name, width*2, format)
	if err != nil {
		return "", err
	}

	args := []string{
		"-size",
		fmt.Sprintf("%dx%d", width, width),
		"xc:none",
		"-fill",
		filename,
		"-quality",
		"83",
		"-density",
		"72x72",
		"-draw",
		fmt.Sprintf("circle %d,%d %d,1", width/2, width/2, width/2),
		fmt.Sprintf("PNG:%s", outfile),
	}

	err = runProcessorCommand(GM_COMMAND, args)
	if err != nil {
		return "", err
	}

	return outfile, nil
}
<|endoftext|>


<commit_before>package main

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

func main() {
	addr := os.Getenv("ADDR")
	if addr == "" {
		addr = ":8080"
	}

	http.HandleFunc("/", catHandler)
	if err := http.ListenAndServe(addr, nil); err != nil {
		fmt.Fprintf(os.Stderr, "Fatal: %s\n", err)
	}
}

func catHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Got Req")
	w.WriteHeader(200)
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s %s %s\n", r.Method, r.RequestURI, r.Proto)
	r.Header.WriteSubset(os.Stdout, nil)
	fmt.Printf("\n")
	fmt.Println(string(body))
}
<commit_msg>Log RemoteAddr<commit_after>package main

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

func main() {
	addr := os.Getenv("ADDR")
	if addr == "" {
		addr = ":8080"
	}

	http.HandleFunc("/", catHandler)
	if err := http.ListenAndServe(addr, nil); err != nil {
		fmt.Fprintf(os.Stderr, "Fatal: %s\n", err)
	}
}

func catHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("Request from %s\n", r.RemoteAddr)

	w.WriteHeader(200)
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s %s %s\n", r.Method, r.RequestURI, r.Proto)
	r.Header.WriteSubset(os.Stdout, nil)
	fmt.Printf("\n")
	fmt.Println(string(body))
}
<|endoftext|>


<commit_before>package img_test

import (
	"flag"
	"fmt"
	"github.com/dooman87/transformimgs/img"
	"io/ioutil"
	"log"
	"os"
	"testing"
)

var (
	FILES = []string{
		"HT_Paper.png",
		"HT_Stationery.png",
		"JBBAKUMBBK_baku_medium_back_chair_black.jpg",
		"otto-funhouse.jpg",
		"OW20170515_HPHB_B2B2.jpg",
		"OW20170515_HPHB_B2C4.jpg",
		"Monochrome_CategoryImage2.png",
	}
)

type result struct {
	file     string
	origSize int
	optSize  int
}

type transform func(orig []byte) ([]byte, error)

var (
	proc *img.ImageMagickProcessor
)

func TestMain(m *testing.M) {
	var (
		err     error
		im      string
		imIdent string
	)

	flag.StringVar(&im, "imConvert", "", "Imagemagick convert command")
	flag.StringVar(&imIdent, "imIdentify", "", "Imagemagick identify command")
	flag.Parse()

	proc, err = img.NewProcessor(im, imIdent)
	if err != nil {
		log.Printf("Error while creating image processor: %+v", err)
		os.Exit(1)
	}
	os.Exit(m.Run())
}

func TestImageMagickProcessor_Optimise(t *testing.T) {
	imgOpT(t, func(orig []byte) ([]byte, error) {
		return proc.Optimise(orig)
	})
}

func BenchmarkImageMagickProcessor_Optimise(b *testing.B) {
	f := fmt.Sprintf("%s/%s", "./test_files", "OW20170515_HPHB_B2B2.jpg")

	orig, err := ioutil.ReadFile(f)
	if err != nil {
		b.Errorf("Can't read file %s: %+v", f, err)
	}
	img.Debug = false

	for i := 0; i < b.N; i++ {
		_, err = proc.Optimise(orig)
		if err != nil {
			b.Errorf("Can't transform file: %+v", err)
		}
	}

	img.Debug = true
}

func TestImageMagickProcessor_Resize(t *testing.T) {
	imgOpT(t, func(orig []byte) ([]byte, error) {
		return proc.Resize(orig, "50")
	})
}

func TestImageMagickProcessor_FitToSize(t *testing.T) {
	imgOpT(t, func(orig []byte) ([]byte, error) {
		return proc.FitToSize(orig, "50x50")
	})
}

func imgOpT(t *testing.T, fn transform) {
	results := make([]*result, 0)
	for _, imgFile := range FILES {
		f := fmt.Sprintf("%s/%s", "./test_files", imgFile)

		orig, err := ioutil.ReadFile(f)
		if err != nil {
			t.Errorf("Can't read file %s: %+v", f, err)
		}

		optimisedImg, err := fn(orig)

		if err != nil {
			t.Errorf("Can't transform file: %+v", err)
		}

		results = append(results, &result{
			file:     imgFile,
			origSize: len(orig),
			optSize:  len(optimisedImg),
		})
		ioutil.WriteFile(fmt.Sprintf("./test_files/opt_%s", imgFile), optimisedImg, 0777)

		if len(optimisedImg) > len(orig) {
			t.Errorf("Image %s is not optimised", f)
		}
	}

	for _, r := range results {
		log.Printf("%60s | %10d | %10d | %.2f", r.file, r.optSize, r.origSize, 1.0-(float32(r.optSize)/float32(r.origSize)))
	}
}
<commit_msg>Commented out writing optimised file.<commit_after>package img_test

import (
	"flag"
	"fmt"
	"github.com/dooman87/transformimgs/img"
	"io/ioutil"
	"log"
	"os"
	"testing"
)

var (
	FILES = []string{
		"HT_Paper.png",
		"HT_Stationery.png",
		"JBBAKUMBBK_baku_medium_back_chair_black.jpg",
		"otto-funhouse.jpg",
		"OW20170515_HPHB_B2B2.jpg",
		"OW20170515_HPHB_B2C4.jpg",
		"Monochrome_CategoryImage2.png",
	}
)

type result struct {
	file     string
	origSize int
	optSize  int
}

type transform func(orig []byte) ([]byte, error)

var (
	proc *img.ImageMagickProcessor
)

func TestMain(m *testing.M) {
	var (
		err     error
		im      string
		imIdent string
	)

	flag.StringVar(&im, "imConvert", "", "Imagemagick convert command")
	flag.StringVar(&imIdent, "imIdentify", "", "Imagemagick identify command")
	flag.Parse()

	proc, err = img.NewProcessor(im, imIdent)
	if err != nil {
		log.Printf("Error while creating image processor: %+v", err)
		os.Exit(1)
	}
	os.Exit(m.Run())
}

func TestImageMagickProcessor_Optimise(t *testing.T) {
	imgOpT(t, func(orig []byte) ([]byte, error) {
		return proc.Optimise(orig)
	})
}

func BenchmarkImageMagickProcessor_Optimise(b *testing.B) {
	f := fmt.Sprintf("%s/%s", "./test_files", "OW20170515_HPHB_B2B2.jpg")

	orig, err := ioutil.ReadFile(f)
	if err != nil {
		b.Errorf("Can't read file %s: %+v", f, err)
	}
	img.Debug = false

	for i := 0; i < b.N; i++ {
		_, err = proc.Optimise(orig)
		if err != nil {
			b.Errorf("Can't transform file: %+v", err)
		}
	}

	img.Debug = true
}

func TestImageMagickProcessor_Resize(t *testing.T) {
	imgOpT(t, func(orig []byte) ([]byte, error) {
		return proc.Resize(orig, "50")
	})
}

func TestImageMagickProcessor_FitToSize(t *testing.T) {
	imgOpT(t, func(orig []byte) ([]byte, error) {
		return proc.FitToSize(orig, "50x50")
	})
}

func imgOpT(t *testing.T, fn transform) {
	results := make([]*result, 0)
	for _, imgFile := range FILES {
		f := fmt.Sprintf("%s/%s", "./test_files", imgFile)

		orig, err := ioutil.ReadFile(f)
		if err != nil {
			t.Errorf("Can't read file %s: %+v", f, err)
		}

		optimisedImg, err := fn(orig)

		if err != nil {
			t.Errorf("Can't transform file: %+v", err)
		}

		results = append(results, &result{
			file:     imgFile,
			origSize: len(orig),
			optSize:  len(optimisedImg),
		})
		//ioutil.WriteFile(fmt.Sprintf("./test_files/opt_%s", imgFile), optimisedImg, 0777)

		if len(optimisedImg) > len(orig) {
			t.Errorf("Image %s is not optimised", f)
		}
	}

	for _, r := range results {
		log.Printf("%60s | %10d | %10d | %.2f", r.file, r.optSize, r.origSize, 1.0-(float32(r.optSize)/float32(r.origSize)))
	}
}
<|endoftext|>


<commit_before>package main

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

func main() {
	addr := os.Getenv("ADDR")
	if addr == "" {
		addr = ":8080"
	}

	http.HandleFunc("/", catHandler)
	http.ListenAndServe(addr, nil)
}

func catHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Got Req")
	w.WriteHeader(200)
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s %s %s\n", r.Method, r.RequestURI, r.Proto)
	r.Header.WriteSubset(os.Stdout, nil)
	fmt.Printf("\n")
	fmt.Println(string(body))
}
<commit_msg>Print Listen error so I know why the process doesn't start<commit_after>package main

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

func main() {
	addr := os.Getenv("ADDR")
	if addr == "" {
		addr = ":8080"
	}

	http.HandleFunc("/", catHandler)
	if err := http.ListenAndServe(addr, nil); err != nil {
		fmt.Fprintf(os.Stderr, "Fatal: %s\n", err)
	}
}

func catHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Got Req")
	w.WriteHeader(200)
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s %s %s\n", r.Method, r.RequestURI, r.Proto)
	r.Header.WriteSubset(os.Stdout, nil)
	fmt.Printf("\n")
	fmt.Println(string(body))
}
<|endoftext|>


<commit_before>package gracedown

import (
	"net"
	"net/http"
)

type Server struct {
	Server *http.Server
}

func NewWithServer(s *http.Server) *Server {
	return &Server{
		Server: s,
	}
}

func (srv *Server) ListenAndServe() error {
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}
	ln, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}
	return srv.Serve(ln)
}

func (srv *Server) Serve(l net.Listener) error {
	return srv.Server.Serve(l)
}
<commit_msg>fix Addr<commit_after>package gracedown

import (
	"net"
	"net/http"
)

type Server struct {
	Server *http.Server
}

func NewWithServer(s *http.Server) *Server {
	return &Server{
		Server: s,
	}
}

func (srv *Server) ListenAndServe() error {
	addr := srv.Server.Addr
	if addr == "" {
		addr = ":http"
	}
	ln, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}
	return srv.Serve(ln)
}

func (srv *Server) Serve(l net.Listener) error {
	return srv.Server.Serve(l)
}
<|endoftext|>


<commit_before>package graph

import (
	"fmt"
	"io"
	"strings"

	"github.com/zimmski/tavor/token"
	"github.com/zimmski/tavor/token/constraints"
	"github.com/zimmski/tavor/token/lists"
	"github.com/zimmski/tavor/token/primitives"
)

type dotGraph struct {
	edges    []dotEdge
	vertices map[token.Token]dotVertice

	end token.Token
}

type dotEdge struct {
	from, to token.Token
	optional bool
	label    string
}

type dotVertice struct {
	label string
	typ   string
}

func nodeUID(tok token.Token) string {
	return fmt.Sprintf("%p", tok)[1:]
}

func (g *dotGraph) addDot(tok token.Token) (start, next map[token.Token]bool) {
	start = make(map[token.Token]bool)
	next = make(map[token.Token]bool)

	switch t := tok.(type) {
	case *constraints.Optional:
		v := t.InternalGet()

		s, n := g.addDot(v)

		for k := range s {
			start[k] = true
		}
		for k := range n {
			next[k] = true
		}

		start[g.end] = false
		next[g.end] = false
	case *lists.One:
		l := t.InternalLen()

		for i := 0; i < l; i++ {
			c, _ := t.InternalGet(i)

			if o, ok := c.(token.OptionalToken); ok && o.IsOptional() {
				start[g.end] = false
				next[g.end] = false
			}

			s, n := g.addDot(c)

			for k, v := range s {
				start[k] = v
			}
			for k, v := range n {
				next[k] = v
			}
		}
	case *lists.All:
		var prev map[token.Token]bool

		l := t.InternalLen()

		for i := 0; i < l; i++ {
			c, _ := t.InternalGet(i)

			s, n := g.addDot(c)

			if i == 0 {
				for k, v := range s {
					if k == g.end {
						continue
					}

					start[k] = v
				}
			} else {
				found := false

				for pt, po := range prev {
					for st, so := range s {
						if pt == g.end || st == g.end {
							continue
						}

						g.edges = append(g.edges, dotEdge{
							from:     pt,
							to:       st,
							optional: po || so,
						})

						if so {
							found = true
						}
					}
				}

				if found {
					for pt := range prev {
						if pt == g.end {
							continue
						}

						n[pt] = false
					}
				}
			}

			prev = n

			if i == l-1 || l == 1 {
				for k, v := range n {
					if k == g.end {
						continue
					}

					next[k] = v
				}
			}
		}
	case *lists.Repeat:
		var times string
		if t.From() == t.To() {
			times = fmt.Sprintf("%dx", t.From())
		} else {
			times = fmt.Sprintf("%d-%dx", t.From(), t.To())
		}

		a := primitives.NewConstantString("")
		g.vertices[a] = dotVertice{
			label: a.String(),
			typ:   "point",
		}

		b := primitives.NewConstantString("")
		g.vertices[b] = dotVertice{
			label: b.String(),
			typ:   "point",
		}

		v, _ := t.InternalGet(0)

		s, n := g.addDot(v)

		for st, so := range s {
			g.edges = append(g.edges, dotEdge{
				from:     a,
				to:       st,
				optional: so,
			})
		}

		for nt, no := range n {
			g.edges = append(g.edges, dotEdge{
				from:     nt,
				to:       b,
				optional: no,
			})
		}

		g.edges = append(g.edges, dotEdge{
			from:     b,
			to:       a,
			optional: false,
			label:    times,
		})

		if t.From() == 0 {
			start[a] = true
			next[b] = true
		} else {
			start[a] = false
			next[b] = false
		}
	case token.ListToken:
		panic(fmt.Errorf("%#v not implemented", t))
	case *primitives.RangeInt:
		label := fmt.Sprintf("%d..%d", t.From(), t.To())

		if st := t.Step(); st != 1 {
			label += fmt.Sprintf(" with step %d", st)
		}

		g.vertices[tok] = dotVertice{
			label: label,
		}

		start[tok] = false
		next[tok] = false
	case *primitives.Scope:
		return g.addDot(t.InternalGet())
	default:
		g.vertices[tok] = dotVertice{
			label: tok.String(),
		}

		start[tok] = false
		next[tok] = false
	}

	return
}

// WriteDot writes the token graph as DOT format to the writer
func WriteDot(root token.Token, dst io.Writer) {
	g := &dotGraph{
		vertices: make(map[token.Token]dotVertice),

		end: primitives.NewConstantString("END"),
	}

	start, next := g.addDot(root)

	foundEnd := false

	for k := range start {
		if k == g.end {
			foundEnd = true

			break
		}
	}
	for _, edge := range g.edges {
		if edge.to == g.end {
			foundEnd = true

			break
		}
	}

	if foundEnd {
		g.vertices[g.end] = dotVertice{
			label: g.end.String(),
		}
	}

	fmt.Fprintf(dst, "digraph Graphing {\n")

	fmt.Fprintf(dst, "\tnode [shape = doublecircle];")
	for tok := range next {
		fmt.Fprintf(dst, " %s", nodeUID(tok))
	}
	fmt.Fprintf(dst, ";\n")

	fmt.Fprintf(dst, "\tnode [shape = point] START;\n")

	for tok, vertice := range g.vertices {
		if vertice.typ != "" {
			fmt.Fprintf(dst, "\tnode [shape = %s] %s;\n", vertice.typ, nodeUID(tok))
		}
	}

	fmt.Fprintf(dst, "\tnode [shape = ellipse];\n")

	fmt.Fprintln(dst)

	for tok, vertice := range g.vertices {
		// Double escape the labels so that graphviz display the special sequences (\n, \t, ...)
		label := strings.Replace(fmt.Sprintf("%q", vertice.label), "\\", "\\\\", -1)
		fmt.Fprintf(dst, "\t%s [label=%s]\n", nodeUID(tok), label)
	}

	fmt.Fprintln(dst)

	found := false

	for tok, opt := range start {
		fmt.Fprintf(dst, "\tSTART -> %s", nodeUID(tok))

		if opt {
			fmt.Fprintf(dst, " [style=dotted]")

			found = true
		}

		fmt.Fprintf(dst, ";\n")
	}

	if found {
		for _, edge := range g.edges {
			if edge.optional {
				fmt.Fprintf(dst, "\tSTART -> %s;\n", nodeUID(edge.to))
			}
		}
	}

	for _, edge := range g.edges {
		fmt.Fprintf(dst, "\t%s -> %s", nodeUID(edge.from), nodeUID(edge.to))

		if edge.optional || edge.label != "" {
			fmt.Fprint(dst, "[")

			if edge.optional {
				fmt.Fprintf(dst, " style=dotted")
			}
			if edge.label != "" {
				fmt.Fprintf(dst, " label=%q", edge.label)
			}

			fmt.Fprint(dst, "]")
		}

		fmt.Fprintf(dst, ";\n")
	}

	fmt.Fprintf(dst, "}\n")

	/*
		digraph graphname {

			size="8,5"
			node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
			node [shape = circle];

		    a [label="Google"]
		    b [label="Apple"]
		    c [label="UCLA"]
		    d [label="Stanford"]
		    a -> b [label=50, color=blue];
		    b -> c [label=-10, color=red];
		    b -> d [label="A", color=green];
			b -- d [style=dotted];
		}
	*/
}
<commit_msg>Graph: Change accepting states to double ellipses<commit_after>package graph

import (
	"fmt"
	"io"
	"strings"

	"github.com/zimmski/tavor/token"
	"github.com/zimmski/tavor/token/constraints"
	"github.com/zimmski/tavor/token/lists"
	"github.com/zimmski/tavor/token/primitives"
)

type dotGraph struct {
	edges    []dotEdge
	vertices map[token.Token]dotVertice

	end token.Token
}

type dotEdge struct {
	from, to token.Token
	optional bool
	label    string
}

type dotVertice struct {
	label string
	typ   string
}

func nodeUID(tok token.Token) string {
	return fmt.Sprintf("%p", tok)[1:]
}

func (g *dotGraph) addDot(tok token.Token) (start, next map[token.Token]bool) {
	start = make(map[token.Token]bool)
	next = make(map[token.Token]bool)

	switch t := tok.(type) {
	case *constraints.Optional:
		v := t.InternalGet()

		s, n := g.addDot(v)

		for k := range s {
			start[k] = true
		}
		for k := range n {
			next[k] = true
		}

		start[g.end] = false
		next[g.end] = false
	case *lists.One:
		l := t.InternalLen()

		for i := 0; i < l; i++ {
			c, _ := t.InternalGet(i)

			if o, ok := c.(token.OptionalToken); ok && o.IsOptional() {
				start[g.end] = false
				next[g.end] = false
			}

			s, n := g.addDot(c)

			for k, v := range s {
				start[k] = v
			}
			for k, v := range n {
				next[k] = v
			}
		}
	case *lists.All:
		var prev map[token.Token]bool

		l := t.InternalLen()

		for i := 0; i < l; i++ {
			c, _ := t.InternalGet(i)

			s, n := g.addDot(c)

			if i == 0 {
				for k, v := range s {
					if k == g.end {
						continue
					}

					start[k] = v
				}
			} else {
				found := false

				for pt, po := range prev {
					for st, so := range s {
						if pt == g.end || st == g.end {
							continue
						}

						g.edges = append(g.edges, dotEdge{
							from:     pt,
							to:       st,
							optional: po || so,
						})

						if so {
							found = true
						}
					}
				}

				if found {
					for pt := range prev {
						if pt == g.end {
							continue
						}

						n[pt] = false
					}
				}
			}

			prev = n

			if i == l-1 || l == 1 {
				for k, v := range n {
					if k == g.end {
						continue
					}

					next[k] = v
				}
			}
		}
	case *lists.Repeat:
		var times string
		if t.From() == t.To() {
			times = fmt.Sprintf("%dx", t.From())
		} else {
			times = fmt.Sprintf("%d-%dx", t.From(), t.To())
		}

		a := primitives.NewConstantString("")
		g.vertices[a] = dotVertice{
			label: a.String(),
			typ:   "point",
		}

		b := primitives.NewConstantString("")
		g.vertices[b] = dotVertice{
			label: b.String(),
			typ:   "point",
		}

		v, _ := t.InternalGet(0)

		s, n := g.addDot(v)

		for st, so := range s {
			g.edges = append(g.edges, dotEdge{
				from:     a,
				to:       st,
				optional: so,
			})
		}

		for nt, no := range n {
			g.edges = append(g.edges, dotEdge{
				from:     nt,
				to:       b,
				optional: no,
			})
		}

		g.edges = append(g.edges, dotEdge{
			from:     b,
			to:       a,
			optional: false,
			label:    times,
		})

		if t.From() == 0 {
			start[a] = true
			next[b] = true
		} else {
			start[a] = false
			next[b] = false
		}
	case token.ListToken:
		panic(fmt.Errorf("%#v not implemented", t))
	case *primitives.RangeInt:
		label := fmt.Sprintf("%d..%d", t.From(), t.To())

		if st := t.Step(); st != 1 {
			label += fmt.Sprintf(" with step %d", st)
		}

		g.vertices[tok] = dotVertice{
			label: label,
		}

		start[tok] = false
		next[tok] = false
	case *primitives.Scope:
		return g.addDot(t.InternalGet())
	default:
		g.vertices[tok] = dotVertice{
			label: tok.String(),
		}

		start[tok] = false
		next[tok] = false
	}

	return
}

// WriteDot writes the token graph as DOT format to the writer
func WriteDot(root token.Token, dst io.Writer) {
	g := &dotGraph{
		vertices: make(map[token.Token]dotVertice),

		end: primitives.NewConstantString("END"),
	}

	start, next := g.addDot(root)

	foundEnd := false

	for k := range start {
		if k == g.end {
			foundEnd = true

			break
		}
	}
	for _, edge := range g.edges {
		if edge.to == g.end {
			foundEnd = true

			break
		}
	}

	if foundEnd {
		g.vertices[g.end] = dotVertice{
			label: g.end.String(),
		}
	}

	fmt.Fprintf(dst, "digraph Graphing {\n")

	fmt.Fprintf(dst, "\tnode [peripheries = 2];")
	for tok := range next {
		fmt.Fprintf(dst, " %s", nodeUID(tok))
	}
	fmt.Fprintf(dst, "; node [peripheries = 1];\n")

	fmt.Fprintf(dst, "\tnode [shape = point] START;\n")

	for tok, vertice := range g.vertices {
		if vertice.typ != "" {
			fmt.Fprintf(dst, "\tnode [shape = %s] %s;\n", vertice.typ, nodeUID(tok))
		}
	}

	fmt.Fprintf(dst, "\tnode [shape = ellipse];\n")

	fmt.Fprintln(dst)

	for tok, vertice := range g.vertices {
		// Double escape the labels so that graphviz display the special sequences (\n, \t, ...)
		label := strings.Replace(fmt.Sprintf("%q", vertice.label), "\\", "\\\\", -1)
		fmt.Fprintf(dst, "\t%s [label=%s]\n", nodeUID(tok), label)
	}

	fmt.Fprintln(dst)

	found := false

	for tok, opt := range start {
		fmt.Fprintf(dst, "\tSTART -> %s", nodeUID(tok))

		if opt {
			fmt.Fprintf(dst, " [style=dotted]")

			found = true
		}

		fmt.Fprintf(dst, ";\n")
	}

	if found {
		for _, edge := range g.edges {
			if edge.optional {
				fmt.Fprintf(dst, "\tSTART -> %s;\n", nodeUID(edge.to))
			}
		}
	}

	for _, edge := range g.edges {
		fmt.Fprintf(dst, "\t%s -> %s", nodeUID(edge.from), nodeUID(edge.to))

		if edge.optional || edge.label != "" {
			fmt.Fprint(dst, "[")

			if edge.optional {
				fmt.Fprintf(dst, " style=dotted")
			}
			if edge.label != "" {
				fmt.Fprintf(dst, " label=%q", edge.label)
			}

			fmt.Fprint(dst, "]")
		}

		fmt.Fprintf(dst, ";\n")
	}

	fmt.Fprintf(dst, "}\n")

	/*
		digraph graphname {

			size="8,5"
			node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
			node [shape = circle];

		    a [label="Google"]
		    b [label="Apple"]
		    c [label="UCLA"]
		    d [label="Stanford"]
		    a -> b [label=50, color=blue];
		    b -> c [label=-10, color=red];
		    b -> d [label="A", color=green];
			b -- d [style=dotted];
		}
	*/
}
<|endoftext|>


<commit_before>package github

import (
	"fmt"
	"github.com/google/go-github/github"
	"strings"
	"sync"
)

var ReposNames = []string{
	"GigaSpaces/xap",
	"GigaSpaces/xap-open"}

type Repo struct {
	owner string
	repo  string
	sha   string
}

func (repo Repo) String() string {
	return fmt.Sprintf("Repo{owner:%s, repo:%s, sha:%s}", repo.owner, repo.repo, repo.sha)
}

func createReposFromNames(names []string) []*Repo {
	fmt.Printf("creating repos from names %s\n", names);
	ret := make([]*Repo, 0)
	for _, name := range names {
		if strings.TrimSpace(name) != "" && strings.Contains(name, "/") {
			components := strings.Split(name, "/")
			ret = append(ret, &Repo{owner: components[0], repo: components[1]})
		}
	}
	fmt.Printf("repos are %s\n", names);
	return ret
}

func fillTipSha(repos []*Repo, client *github.Client) *sync.WaitGroup {
	var wg sync.WaitGroup
	for _, repo := range repos {
		wg.Add(1)
		go func(repo *Repo) {
			defer wg.Done()
			//fmt.Printf("working on repo %#v\n", repo)
			ref, _, err := client.Git.GetRef(repo.owner, repo.repo, "refs/heads/master")
			if err != nil {
				fmt.Printf("error: %#v\n", err)
			}
			//fmt.Printf("Ref: %s\nURL: %s\n", *ref.Ref, *ref.URL)
			//fmt.Printf("Type: %s\nURL: %s\nSHA: %s\n", *ref.Object.Type, *ref.Object.URL, *ref.Object.SHA)
			repo.sha = *ref.Object.SHA
		}(repo)
	}
	return &wg
}

func createBranchesWithProgress(repos []*Repo, branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	progressChan = make(chan RepoStatus, len(repos))
	resChan = make(chan map[string]interface{})
	intermediateProgressChan := make(chan RepoStatus, len(repos))
	for _, repo := range repos {
		go func(repo *Repo) {
			_, _, err := client.Git.CreateRef(repo.owner, repo.repo, &github.Reference{
				Ref: github.String("refs/heads/" + branch),
				Object: &github.GitObject{
					SHA: &repo.sha,
				},
			})
			if err != nil {
				fmt.Printf("error createing branch %s in repo: %#v, error is %s:\n", branch, repo, err.Error())
				intermediateProgressChan <- RepoStatus{Name: repo.owner + "/" +repo.repo, Success: false}
			} else {
				fmt.Printf("branch %s created in repo %#v\n", branch, repo)
				intermediateProgressChan <- RepoStatus{Name: repo.owner + "/" +repo.repo, Success: true}
			}
		}(repo)
	}
	go func() {
		var statuses map[string]interface{} = make(map[string]interface{})
		for range repos {
			status := <-intermediateProgressChan
			statuses[status.Name] = status.Success
			progressChan <- status
		}
		resChan <- statuses
		close(progressChan)
		close(resChan)
		close(intermediateProgressChan)
	}()
	return progressChan, resChan
}

func deleteBranchesWithProgress(repos []*Repo, branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	progressChan = make(chan RepoStatus, len(repos))
	resChan = make(chan map[string]interface{})
	intermediateProgressChan := make(chan RepoStatus, len(repos))
	for _, repo := range repos {
		go func(repo *Repo) {
			_, err := client.Git.DeleteRef(repo.owner, repo.repo, "refs/heads/" + branch)
			if err != nil {
				fmt.Printf("error deleting branch %s in repo: %#v, error is %s:\n", branch, repo, err.Error())
				intermediateProgressChan <- RepoStatus{Name: repo.repo, Success: false}
			} else {
				//fmt.Printf("branch %s deleted from repo %#v\n", branch, repo)
				intermediateProgressChan <- RepoStatus{Name: repo.repo, Success: true}
			}
		}(repo)
	}
	go func() {
		var statuses map[string]interface{} = make(map[string]interface{})
		for range repos {
			status := <-intermediateProgressChan
			statuses[status.Name] = status.Success
			progressChan <- status
		}
		resChan <- statuses
		close(progressChan)
		close(resChan)
		close(intermediateProgressChan)
	}()
	return progressChan, resChan
}

type BranchOnRepositories struct {
	Name     string       `json:"name"`
	Statuses map[string]bool `json:"statuses"`
}

func ListAllRefsAsMap(client *github.Client) chan map[string]map[string]bool {
	type branch struct {
		repo   string
		branch string
	}
	branches := make(chan branch, 100)
	repos := createReposFromNames(ReposNames)
	var wg sync.WaitGroup
	for _, repo := range repos {
		wg.Add(1)
		go func(repo *Repo) {
			defer func() {
				wg.Done()
			}()
			heads, err := ListRefs(client, repo.owner, repo.repo)
			if err == nil {
				for _, head := range heads {
					branchName := strings.TrimPrefix(*head.Ref, "refs/heads/")
					branches <- branch{repo.owner + "/" + repo.repo, branchName}
				}
			} else {
				fmt.Printf("List all ref error: %#v, on repo %#v\n", err, repo)
			}
		}(repo)
	}

	// closer
	go func() {
		wg.Wait()
		close(branches)
	}()

	var res map[string]map[string]bool = make(map[string]map[string]bool)
	resChan := make(chan map[string]map[string]bool)
	go func() {
		for branch := range branches {
			if b, ok := res[branch.branch]; ok {
				b[branch.repo] = true
			}else {
				res[branch.branch] = map[string]bool{branch.repo : true}
			}
		}
		resChan <- res
		close(resChan)
	}()
	return resChan
}

func DeleteBranchWithProgress(branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	repos := createReposFromNames(ReposNames)
	return deleteBranchesWithProgress(repos, branch, client)
}

func CreateBranchsWithProgress(branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	repos := createReposFromNames(ReposNames)
	fillTipSha(repos, client).Wait()
	return createBranchesWithProgress(repos, branch, client)
}

func ListRefs(client *github.Client, owner string, repo string) ([]github.Reference, error) {
	refs, _, err := client.Git.ListRefs(owner, repo, &github.ReferenceListOptions{Type: "heads/"})
	//refs, _, err := client.Git.ListRefs(owner, repo, &github.ReferenceListOptions{Type:"heads"});
	return refs, err
}

type RefList struct {
}

type UIBranch struct {
	Name  string       `json:"name"`
	Repos []RepoStatus `json:"repos"`
}

type RepoStatus struct {
	Name    string `json:"name"`
	Success bool   `json:"success"`
}

type repoWithRefs struct {
	name string
	refs []github.Reference
}<commit_msg>Add logs<commit_after>package github

import (
	"fmt"
	"github.com/google/go-github/github"
	"strings"
	"sync"
)

var ReposNames = []string{
	"GigaSpaces/xap",
	"GigaSpaces/xap-open"}

type Repo struct {
	owner string
	repo  string
	sha   string
}

func (repo Repo) String() string {
	return fmt.Sprintf("Repo{owner:%s, repo:%s, sha:%s}", repo.owner, repo.repo, repo.sha)
}

func createReposFromNames(names []string) []*Repo {
	fmt.Printf("creating repos from names %s\n", names);
	ret := make([]*Repo, 0)
	for _, name := range names {
		if strings.TrimSpace(name) != "" && strings.Contains(name, "/") {
			components := strings.Split(name, "/")
			ret = append(ret, &Repo{owner: components[0], repo: components[1]})
		}
	}
	fmt.Printf("repos are %s\n", names);
	return ret
}

func fillTipSha(repos []*Repo, client *github.Client) *sync.WaitGroup {
	var wg sync.WaitGroup
	for _, repo := range repos {
		wg.Add(1)
		go func(repo *Repo) {
			defer wg.Done()
			//fmt.Printf("working on repo %#v\n", repo)
			ref, _, err := client.Git.GetRef(repo.owner, repo.repo, "refs/heads/master")
			if err != nil {
				fmt.Printf("error: %#v\n", err)
			}
			//fmt.Printf("Ref: %s\nURL: %s\n", *ref.Ref, *ref.URL)
			//fmt.Printf("Type: %s\nURL: %s\nSHA: %s\n", *ref.Object.Type, *ref.Object.URL, *ref.Object.SHA)
			repo.sha = *ref.Object.SHA
		}(repo)
	}
	return &wg
}

func createBranchesWithProgress(repos []*Repo, branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	progressChan = make(chan RepoStatus, len(repos))
	resChan = make(chan map[string]interface{})
	intermediateProgressChan := make(chan RepoStatus, len(repos))
	for _, repo := range repos {
		go func(repo *Repo) {
			_, _, err := client.Git.CreateRef(repo.owner, repo.repo, &github.Reference{
				Ref: github.String("refs/heads/" + branch),
				Object: &github.GitObject{
					SHA: &repo.sha,
				},
			})
			if err != nil {
				fmt.Printf("error createing branch %s in repo: %#v, error is %s:\n", branch, repo, err.Error())
				intermediateProgressChan <- RepoStatus{Name: repo.owner + "/" +repo.repo, Success: false}
			} else {
				fmt.Printf("branch %s created in repo %#v\n", branch, repo)
				intermediateProgressChan <- RepoStatus{Name: repo.owner + "/" +repo.repo, Success: true}
			}
		}(repo)
	}
	go func() {
		var statuses map[string]interface{} = make(map[string]interface{})
		for range repos {
			status := <-intermediateProgressChan
			statuses[status.Name] = status.Success
			progressChan <- status
		}
		resChan <- statuses
		close(progressChan)
		close(resChan)
		close(intermediateProgressChan)
	}()
	return progressChan, resChan
}

func deleteBranchesWithProgress(repos []*Repo, branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	progressChan = make(chan RepoStatus, len(repos))
	resChan = make(chan map[string]interface{})
	intermediateProgressChan := make(chan RepoStatus, len(repos))
	for _, repo := range repos {
		go func(repo *Repo) {
			_, err := client.Git.DeleteRef(repo.owner, repo.repo, "refs/heads/" + branch)
			if err != nil {
				fmt.Printf("error deleting branch %s in repo: %#v, error is %s:\n", branch, repo, err.Error())
				intermediateProgressChan <- RepoStatus{Name: repo.repo, Success: false}
			} else {
				//fmt.Printf("branch %s deleted from repo %#v\n", branch, repo)
				intermediateProgressChan <- RepoStatus{Name: repo.repo, Success: true}
			}
		}(repo)
	}
	go func() {
		var statuses map[string]interface{} = make(map[string]interface{})
		for range repos {
			status := <-intermediateProgressChan
			statuses[status.Name] = status.Success
			progressChan <- status
		}
		resChan <- statuses
		close(progressChan)
		close(resChan)
		close(intermediateProgressChan)
	}()
	return progressChan, resChan
}

type BranchOnRepositories struct {
	Name     string       `json:"name"`
	Statuses map[string]bool `json:"statuses"`
}

func ListAllRefsAsMap(client *github.Client) chan map[string]map[string]bool {
	type branch struct {
		repo   string
		branch string
	}
	branches := make(chan branch, 100)
	repos := createReposFromNames(ReposNames)
	fmt.Printf("ReposNames are: %s\n", ReposNames)
	var wg sync.WaitGroup
	for _, repo := range repos {
		fmt.Printf("ListAllRefsAsMap working on repo: %s\n", *repo)
		wg.Add(1)
		go func(repo *Repo) {
			defer func() {
				wg.Done()
			}()
			heads, err := ListRefs(client, repo.owner, repo.repo)
			if err == nil {
				for _, head := range heads {
					branchName := strings.TrimPrefix(*head.Ref, "refs/heads/")
					branches <- branch{repo.owner + "/" + repo.repo, branchName}
				}
			} else {
				fmt.Printf("List all ref error: %#v, on repo %#v\n", err, repo)
			}
		}(repo)
	}

	// closer
	go func() {
		wg.Wait()
		close(branches)
	}()

	var res map[string]map[string]bool = make(map[string]map[string]bool)
	resChan := make(chan map[string]map[string]bool)
	go func() {
		for branch := range branches {
			if b, ok := res[branch.branch]; ok {
				b[branch.repo] = true
			}else {
				res[branch.branch] = map[string]bool{branch.repo : true}
			}
		}
		resChan <- res
		close(resChan)
	}()
	return resChan
}

func DeleteBranchWithProgress(branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	repos := createReposFromNames(ReposNames)
	return deleteBranchesWithProgress(repos, branch, client)
}

func CreateBranchsWithProgress(branch string, client *github.Client) (progressChan chan RepoStatus, resChan chan map[string]interface{}) {
	repos := createReposFromNames(ReposNames)
	fillTipSha(repos, client).Wait()
	return createBranchesWithProgress(repos, branch, client)
}

func ListRefs(client *github.Client, owner string, repo string) ([]github.Reference, error) {
	refs, _, err := client.Git.ListRefs(owner, repo, &github.ReferenceListOptions{Type: "heads/"})
	//refs, _, err := client.Git.ListRefs(owner, repo, &github.ReferenceListOptions{Type:"heads"});
	return refs, err
}

type RefList struct {
}

type UIBranch struct {
	Name  string       `json:"name"`
	Repos []RepoStatus `json:"repos"`
}

type RepoStatus struct {
	Name    string `json:"name"`
	Success bool   `json:"success"`
}

type repoWithRefs struct {
	name string
	refs []github.Reference
}<|endoftext|>


<commit_before>package controllers

import (
	"github.com/robfig/revel"
	"github.com/PacketFire/goqdb/app/models"
	"net/http"
	"encoding/json"
)
type Api struct {
	Core
}

func (c *Api) Index () revel.Result {

	entries, err := c.getEntries(0, -1, "")

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	}

	return c.RenderJson(entries)
}

func (c *Api) Post () revel.Result {

	var post models.QdbEntry

	dec := json.NewDecoder(c.Request.Body)

	err := dec.Decode(&post)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
		revel.TRACE.Print(err)
		return c.RenderJson(nil)
	}

	/* validation stuffs */
	if post.Quote == "" || post.Author == "" {
		c.Response.Status = http.StatusBadRequest
		return c.RenderJson(nil)
	}

	err = c.insertEntry(&post)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
		revel.TRACE.Print(err)
		return c.RenderJson(nil)
	}

	c.Response.Status = http.StatusCreated
	return c.RenderJson(post)
}

func (c *Api) One (id int) revel.Result {

	entries, err := c.getEntryById(id)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	} else {
		if len(entries) == 0 {
			c.Response.Status = http.StatusNotFound
		}
	}
	return c.RenderJson(entries)
}

func (c *Api) UpVote (id int) revel.Result {

	changes, err := c.upVote(id)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	} else {
		if changes == 0 {
			c.Response.Status = http.StatusNotFound
		}
	}
	return c.RenderJson(nil)
}

func (c *Api) DownVote (id int) revel.Result {

	changes, err := c.downVote(id)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	} else {
		if changes == 0 {
			c.Response.Status = http.StatusNotFound
		}
	}
	return c.RenderJson(nil)
}
<commit_msg>Render json now sets utf-8 charset, like it's supposed to<commit_after>package controllers

import (
	"github.com/robfig/revel"
	"github.com/PacketFire/goqdb/app/models"
	"net/http"
	"encoding/json"
)
type Api struct {
	Core
}

func (c *Api) Index () revel.Result {

	entries, err := c.getEntries(0, -1, "")

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	}
	c.Response.ContentType = "application/json; charset=utf-8"

	return c.RenderJson(entries)
}

func (c *Api) Post () revel.Result {

	var post models.QdbEntry

	dec := json.NewDecoder(c.Request.Body)

	err := dec.Decode(&post)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
		revel.TRACE.Print(err)
		return c.RenderJson(nil)
	}

	/* validation stuffs */
	if post.Quote == "" || post.Author == "" {
		c.Response.Status = http.StatusBadRequest
		return c.RenderJson(nil)
	}

	err = c.insertEntry(&post)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
		revel.TRACE.Print(err)
		return c.RenderJson(nil)
	}

	c.Response.Status = http.StatusCreated
	c.Response.ContentType = "application/json; charset=utf-8"
	return c.RenderJson(post)
}

func (c *Api) One (id int) revel.Result {

	entries, err := c.getEntryById(id)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	} else {
		if len(entries) == 0 {
			c.Response.Status = http.StatusNotFound
		}
	}
	c.Response.ContentType = "application/json; charset=utf-8"
	return c.RenderJson(entries)
}

func (c *Api) UpVote (id int) revel.Result {

	changes, err := c.upVote(id)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	} else {
		if changes == 0 {
			c.Response.Status = http.StatusNotFound
		}
	}
	return c.RenderJson(nil)
}

func (c *Api) DownVote (id int) revel.Result {

	changes, err := c.downVote(id)

	if err != nil {
		c.Response.Status = http.StatusInternalServerError
	} else {
		if changes == 0 {
			c.Response.Status = http.StatusNotFound
		}
	}
	return c.RenderJson(nil)
}
<|endoftext|>