<commit_before>package aranGO

// TODO Must Implement revision control

import (
	"errors"
	nap "github.com/jmcvetta/napping"
	"reflect"
)

// options to create collection
type CollectionOptions struct {
	Name    string `json:"name"`
	Type    uint   `json:"type"`
	Sync    bool   `json:"waitForSync,omitempty"`
	Compact bool   `json:"doCompact,omitempty"`
	//Cannot create with custom journal? TODO
	//JournalSize string                 `json:"journalSize,omitempty"`
	System   bool                   `json:"isSystem,omitempty"`
	Volatile bool                   `json:"isVolatile,omitempty"`
	Keys     map[string]interface{} `json:"keyOptions,omitempty"`

	// Cluster
	Shards    int      `json:"numberOfShards,omitempty"`
	ShardKeys []string `json:"shardKeys,omitempty"`
}

type Collection struct {
	db     *Database `json:"db"`
	Name   string    `json:"name"`
	System bool      `json:"isSystem"`
	Status int       `json:"status"`
	// 3 = Edges , 2 =  Documents
	Type     int    `json:"type"`
	policy   string `json:"-"`
	revision bool   `json:"-"`
}

// Save saves doc into collection, doc should have Document Embedded to retrieve error and Key later.
func (col *Collection) Save(doc interface{}) error {
	var err error
	var res *nap.Response

	if col.Type == 2 {
		res, err = col.db.send("document?collection="+col.Name, "", "POST", doc, &doc, &doc)
	} else {
		return errors.New("Trying to save doc into EdgeCollection")
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 && res.Status() != 202 {
		return errors.New("Unable to save document")
	}

	return nil
}

// Save Edge into Edges collection
func (col *Collection) SaveEdge(doc interface{}, from string, to string) error {
	var err error
	var res *nap.Response

	if col.Type == 3 {
		res, err = col.db.send("edge?collection="+col.Name+"&from="+from+"&to="+to, "", "POST", doc, &doc, &doc)
	} else {
		return errors.New("Trying to save document into Edge-Collection")
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 && res.Status() != 202 {
		return errors.New("Unable to save document error")
	}

	return nil

}

// Relate documents in edge collection
func (col *Collection) Relate(from *Document, to *Document, label interface{}) error {
	if col.Type == 2 {
		return errors.New("Invalid collection to add Edge: " + col.Name)
	}
	if from.Id == "" || to.Id == "" {
		return errors.New("from or to documents don't exist")
	}

	if from == nil || to == nil {
		return errors.New("Invalid document to link")
	}

	return col.SaveEdge(label, from.Id, to.Id)

}

//Get Document
func (col *Collection) Get(key string, doc interface{}) error {
	var err error

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		_, err = col.db.get("document", col.Name+"/"+key, "GET", nil, &doc, &doc)
	} else {
		_, err = col.db.get("edge", col.Name+"/"+key, "GET", nil, &doc, &doc)
	}

	if err != nil {
		return err
	}

	return nil
}

// Replace document
func (col *Collection) Replace(key string, doc interface{}) error {
	var err error
	var res *nap.Response

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		res, err = col.db.send("document", col.Name+"/"+key, "PUT", doc, &doc, &doc)
	} else {
		res, err = col.db.send("edge", col.Name+"/"+key, "PUT", doc, &doc, &doc)
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 {
		return errors.New("Unable to replace document")
	}

	return nil
}

func (col *Collection) Patch(key string, doc interface{}) error {
	var err error
	var res *nap.Response

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		res, err = col.db.send("document", col.Name+"/"+key, "PATCH", doc, &doc, &doc)
	} else {
		res, err = col.db.send("edge", col.Name+"/"+key, "PATCH", doc, &doc, &doc)
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 {
		return errors.New("Unable to replace document")
	}

	return nil
}

func (col *Collection) Delete(key string) error {
	var err error
	var res *nap.Response

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		res, err = col.db.get("document", col.Name+"/"+key, "DELETE", nil, nil, nil)
	} else {
		res, err = col.db.get("edge", col.Name+"/"+key, "DELETE", nil, nil, nil)
	}
	if err != nil {
		return err
	}

	switch res.Status() {
	case 202, 200:
		return nil
	default:
		return errors.New("Document don't exist or revision error")

	}
}

func (col *Collection) Exist() bool {
	return true
}

func Collections(db *Database) error {
	var err error
	var res *nap.Response

	// get all non-system collections
	res, err = db.get("collection?excludeSystem=true", "", "GET", nil, db, db)
	if err != nil {
		return err
	}

	if res.Status() == 200 {
		return nil
	} else {
		return errors.New("Failed to retrieve collections from Database")
	}
}

func reflectValue(obj interface{}) reflect.Value {
	var val reflect.Value

	if reflect.TypeOf(obj).Kind() == reflect.Ptr {
		val = reflect.ValueOf(obj).Elem()
	} else {
		val = reflect.ValueOf(obj)
	}
	return val
}

// check if a key is unique or not
func (c *Collection) Unique(key string, value interface{}, index string) (bool, error) {
	var cur *Cursor
	var err error
	switch index {
	case "hash":
		// must implement other simple query function s
	case "skip-list":

	default:
		cur, err = c.Example(map[string]interface{}{key: value}, 0, 2)
	}
	if err != nil {
		return false, err
	}

	if cur.Amount > 0 {
		return false, nil
	}

	return true, nil
}

// Simple Queries

func (c *Collection) All(skip, limit int) (*Cursor, error) {
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
	query := map[string]interface{}{"collection": c.Name, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "all", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

func (c *Collection) Example(doc interface{}, skip, limit int) (*Cursor, error) {
	var cur Cursor
  if skip < 0 || limit < 0{
    return nil, errors.New("Invalid skip or limit")
  }
	query := map[string]interface{}{"collection": c.Name, "example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

func (c *Collection) First(example, doc interface{}) error {
	query := map[string]interface{}{"collection": c.Name, "example": doc}
	// sernd request
	res, err := c.db.send("simple", "first-example", "PUT", query, &doc, &doc)

	if err != nil {
		return err
	}

	if res.Status() == 200 {
		return nil
	} else {
		return errors.New("Failed to execute query")
	}
}

//Example query using hash index
func (c *Collection) ExampleHash(doc interface{},skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example-hash", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Example query using skip-list index
func (c *Collection) ExampleSkip(doc interface{},skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example-skiplist", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Example query using bitarray index
func (c *Collection) ExampleBitArray(doc interface{},skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example-bitarray", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Coditional query using skiplist index
func (c *Collection) ConditionSkipList(condition string,skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  if condition == ""{
    return nil,errors.New("Invalid conditions")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"condition": condition, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-condition-skiplist", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Coditional query using bitarray index
func (c *Collection) ConditionBitArray(condition string,skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  if condition == ""{
    return nil,errors.New("Invalid conditions")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"condition": condition, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-condition-bitarray", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Return random number
func (c *Collection) Any(doc interface{}) (error){
	res, err := c.db.send("simple", "any", "PUT", nil, &doc, &doc)

	if err != nil {
		return err
	}

	if res.Status() == 200 {
		return nil
	} else {
		return errors.New("Failed to execute query")
	}
}

<commit_msg>added collection option helpers and fix patch document<commit_after>package aranGO

// TODO Must Implement revision control

import (
	"errors"
	nap "github.com/jmcvetta/napping"
	"reflect"
)

// options to create collection
type CollectionOptions struct {
	Name    string `json:"name"`
	Type    uint   `json:"type"`
	Sync    bool   `json:"waitForSync,omitempty"`
	Compact bool   `json:"doCompact,omitempty"`
	//Cannot create with custom journal? TODO
	//JournalSize string                 `json:"journalSize,omitempty"`
	System   bool                   `json:"isSystem,omitempty"`
	Volatile bool                   `json:"isVolatile,omitempty"`
	Keys     map[string]interface{} `json:"keyOptions,omitempty"`

	// Cluster
	Shards    int      `json:"numberOfShards,omitempty"`
	ShardKeys []string `json:"shardKeys,omitempty"`
}

func (opt *CollectionOptions) IsEdge() {
  opt.Type = 3
  return
}

func (opt *CollectionOptions) IsDocument() {
  opt.Type = 2
  return
}

func (opt *CollectionOptions) MustSync() {
  opt.Sync = true
  return
}

func (opt *CollectionOptions) IsVolatile() {
  opt.Volatile = true
  return
}

type Collection struct {
	db     *Database `json:"db"`
	Name   string    `json:"name"`
	System bool      `json:"isSystem"`
	Status int       `json:"status"`
	// 3 = Edges , 2 =  Documents
	Type     int    `json:"type"`
	policy   string `json:"-"`
	revision bool   `json:"-"`
}

// Save saves doc into collection, doc should have Document Embedded to retrieve error and Key later.
func (col *Collection) Save(doc interface{}) error {
	var err error
	var res *nap.Response

	if col.Type == 2 {
		res, err = col.db.send("document?collection="+col.Name, "", "POST", doc, &doc, &doc)
	} else {
		return errors.New("Trying to save doc into EdgeCollection")
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 && res.Status() != 202 {
		return errors.New("Unable to save document")
	}

	return nil
}

// Save Edge into Edges collection
func (col *Collection) SaveEdge(doc interface{}, from string, to string) error {
	var err error
	var res *nap.Response

	if col.Type == 3 {
		res, err = col.db.send("edge?collection="+col.Name+"&from="+from+"&to="+to, "", "POST", doc, &doc, &doc)
	} else {
		return errors.New("Trying to save document into Edge-Collection")
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 && res.Status() != 202 {
		return errors.New("Unable to save document error")
	}

	return nil

}

// Relate documents in edge collection
func (col *Collection) Relate(from *Document, to *Document, label interface{}) error {
	if col.Type == 2 {
		return errors.New("Invalid collection to add Edge: " + col.Name)
	}
	if from.Id == "" || to.Id == "" {
		return errors.New("from or to documents don't exist")
	}

	if from == nil || to == nil {
		return errors.New("Invalid document to link")
	}

	return col.SaveEdge(label, from.Id, to.Id)

}

//Get Document
func (col *Collection) Get(key string, doc interface{}) error {
	var err error

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		_, err = col.db.get("document", col.Name+"/"+key, "GET", nil, &doc, &doc)
	} else {
		_, err = col.db.get("edge", col.Name+"/"+key, "GET", nil, &doc, &doc)
	}

	if err != nil {
		return err
	}

	return nil
}

// Replace document
func (col *Collection) Replace(key string, doc interface{}) error {
	var err error
	var res *nap.Response

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		res, err = col.db.send("document", col.Name+"/"+key, "PUT", doc, &doc, &doc)
	} else {
		res, err = col.db.send("edge", col.Name+"/"+key, "PUT", doc, &doc, &doc)
	}

	if err != nil {
		return err
	}

	if res.Status() != 201 {
		return errors.New("Unable to replace document")
	}

	return nil
}

func (col *Collection) Patch(key string, doc interface{}) error {
	var err error
	var res *nap.Response

	if key == "" {
		return errors.New("Key must not be empty")
	}

  if col.Type == 2 {
    res, err = col.db.send("document", col.Name+"/"+key, "PATCH", doc, &doc, &doc)
  } else {
    res, err = col.db.send("edge", col.Name+"/"+key+"?rev=", "PATCH", doc, &doc, &doc)
  }

	if err != nil {
		return err
	}

  switch res.Status(){
    case 400:
      return errors.New("Body does not contain a valid JSON representation of a document.")
    case 404:
      return errors.New("Collection or document was not found")
    case 412:
      return errors.New("Collection or document was not found")
    default:
      return nil
  }
}

func (col *Collection) Delete(key string) error {
	var err error
	var res *nap.Response

	if key == "" {
		return errors.New("Key must not be empty")
	}

	if col.Type == 2 {
		res, err = col.db.get("document", col.Name+"/"+key, "DELETE", nil, nil, nil)
	} else {
		res, err = col.db.get("edge", col.Name+"/"+key, "DELETE", nil, nil, nil)
	}
	if err != nil {
		return err
	}

	switch res.Status() {
    case 202, 200:
      return nil
    default:
      return errors.New("Document don't exist or revision error")

	}
}

func (col *Collection) Exist() bool {
	return true
}

func Collections(db *Database) error {
	var err error
	var res *nap.Response

	// get all non-system collections
	res, err = db.get("collection?excludeSystem=true", "", "GET", nil, db, db)
	if err != nil {
		return err
	}

	if res.Status() == 200 {
		return nil
	} else {
		return errors.New("Failed to retrieve collections from Database")
	}
}

func reflectValue(obj interface{}) reflect.Value {
	var val reflect.Value

	if reflect.TypeOf(obj).Kind() == reflect.Ptr {
		val = reflect.ValueOf(obj).Elem()
	} else {
		val = reflect.ValueOf(obj)
	}
	return val
}

// check if a key is unique or not
func (c *Collection) Unique(key string, value interface{}, index string) (bool, error) {
	var cur *Cursor
	var err error
	switch index {
	case "hash":
		// must implement other simple query function s
	case "skip-list":

	default:
		cur, err = c.Example(map[string]interface{}{key: value}, 0, 2)
	}
	if err != nil {
		return false, err
	}

	if cur.Amount > 0 {
		return false, nil
	}

	return true, nil
}

// Simple Queries

func (c *Collection) All(skip, limit int) (*Cursor, error) {
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
	query := map[string]interface{}{"collection": c.Name, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "all", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

func (c *Collection) Example(doc interface{}, skip, limit int) (*Cursor, error) {
	var cur Cursor
  if skip < 0 || limit < 0{
    return nil, errors.New("Invalid skip or limit")
  }
	query := map[string]interface{}{"collection": c.Name, "example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

func (c *Collection) First(example, doc interface{}) error {
	query := map[string]interface{}{"collection": c.Name, "example": doc}
	// sernd request
	res, err := c.db.send("simple", "first-example", "PUT", query, &doc, &doc)

	if err != nil {
		return err
	}

	if res.Status() == 200 {
		return nil
	} else {
		return errors.New("Failed to execute query")
	}
}

//Example query using hash index
func (c *Collection) ExampleHash(doc interface{},skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example-hash", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Example query using skip-list index
func (c *Collection) ExampleSkip(doc interface{},skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example-skiplist", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Example query using bitarray index
func (c *Collection) ExampleBitArray(doc interface{},skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"example": doc, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-example-bitarray", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Coditional query using skiplist index
func (c *Collection) ConditionSkipList(condition string,skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  if condition == ""{
    return nil,errors.New("Invalid conditions")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"condition": condition, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-condition-skiplist", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Coditional query using bitarray index
func (c *Collection) ConditionBitArray(condition string,skip int,limit int,index string) (*Cursor,error){
	var cur Cursor
  if skip < 0 || limit < 0 {
    return nil, errors.New("Invalid skip or limit")
  }
  if condition == ""{
    return nil,errors.New("Invalid conditions")
  }
  query := map[string]interface{}{"collection": c.Name, "index" : index,"condition": condition, "skip": skip, "limit": limit}
	res, err := c.db.send("simple", "by-condition-bitarray", "PUT", query, &cur, &cur)

	if err != nil {
		return nil, err
	}

	if res.Status() == 201 {
		return &cur, nil
	} else {
		return nil, errors.New("Failed to execute query")
	}
}

//Return random number
func (c *Collection) Any(doc interface{}) (error){
	res, err := c.db.send("simple", "any", "PUT", nil, &doc, &doc)

	if err != nil {
		return err
	}

	if res.Status() == 200 {
		return nil
	} else {
		return errors.New("Failed to execute query")
	}
}

<|endoftext|>


<commit_before>package lights_test

import (
	"image/color"

	. "github.com/inceptionllc/go-lights/color"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Core", func() {

	Describe("Schedule Parser", func() {

		It("should parse color codes", func() {
			c, err := ParseColorCode("#ABCDEF")
			Ω(err).ShouldNot(HaveOccurred())
			Ω(c).Should(Equal(color.RGBA{0xab, 0xcd, 0xef, 0x00}))
			c, err = ParseColorCode("#abcdef")
			Ω(err).ShouldNot(HaveOccurred())
			Ω(c).Should(Equal(color.RGBA{0xab, 0xcd, 0xef, 0x00}))
			c, err = ParseColorCode("#ABC")
			Ω(err).ShouldNot(HaveOccurred())
			Ω(c).Should(Equal(color.RGBA{0xaa, 0xbb, 0xcc, 0x00}))
		})
	})
})
<commit_msg>Fix import error<commit_after>package lights_test

import (
	"image/color"

	. "github.com/inceptionllc/go-lights"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Core", func() {

	Describe("Schedule Parser", func() {

		It("should parse color codes", func() {
			c, err := ParseColorCode("#ABCDEF")
			Ω(err).ShouldNot(HaveOccurred())
			Ω(c).Should(Equal(color.RGBA{0xab, 0xcd, 0xef, 0x00}))
			c, err = ParseColorCode("#abcdef")
			Ω(err).ShouldNot(HaveOccurred())
			Ω(c).Should(Equal(color.RGBA{0xab, 0xcd, 0xef, 0x00}))
			c, err = ParseColorCode("#ABC")
			Ω(err).ShouldNot(HaveOccurred())
			Ω(c).Should(Equal(color.RGBA{0xaa, 0xbb, 0xcc, 0x00}))
		})
	})
})
<|endoftext|>


<commit_before>// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
	"fmt"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

var (
	skipPush bool
)

func init() {

	upFlagset := pflag.NewFlagSet("up", pflag.ExitOnError)
	upFlagset.BoolVar(&skipPush, "skip-push", false, "Skip pushing function to remote registry")
	upCmd.Flags().AddFlagSet(upFlagset)

	build, _, _ := faasCmd.Find([]string{"build"})
	upCmd.Flags().AddFlagSet(build.Flags())

	push, _, _ := faasCmd.Find([]string{"push"})
	upCmd.Flags().AddFlagSet(push.Flags())

	deploy, _, _ := faasCmd.Find([]string{"deploy"})
	upCmd.Flags().AddFlagSet(deploy.Flags())

	faasCmd.AddCommand(upCmd)
}

// upCmd is a wrapper to the build, push and deploy commands
var upCmd = &cobra.Command{
	Use:   `up -f [YAML_FILE] [--skip-push] [flags from build, push, deploy]`,
	Short: "Builds, pushes and deploys OpenFaaS function containers",
	Long: `Build, Push, and Deploy OpenFaaS function containers either via the
supplied YAML config using the "--yaml" flag (which may contain multiple function
definitions), or directly via flags.

The push step may be skipped by setting the --skip-push flag.

Note: All flags from the build, push and deploy flags are valid and can be combined,
see the --help text for those commands for details.`,
	Example: `  faas-cli up -f myfn.yaml
faas-cli up --filter "*gif*" --secret dockerhuborg`,
	PreRunE: preRunUp,
	RunE:    upHandler,
}

func preRunUp(cmd *cobra.Command, args []string) error {
	if err := preRunBuild(cmd, args); err != nil {
		return err
	}
	if err := preRunDeploy(cmd, args); err != nil {
		return err
	}
	return nil
}

func upHandler(cmd *cobra.Command, args []string) error {
	if err := runBuild(cmd, args); err != nil {
		return err
	}
	fmt.Println()
	if !skipPush {
		if err := runPush(cmd, args); err != nil {
			return err
		}
		fmt.Println()
	}
	if err := runDeploy(cmd, args); err != nil {
		return err
	}
	return nil
}
<commit_msg>Add `--skip-deploy` flag to `up` command<commit_after>// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
	"fmt"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

var (
	skipPush   bool
	skipDeploy bool
)

func init() {

	upFlagset := pflag.NewFlagSet("up", pflag.ExitOnError)
	upFlagset.BoolVar(&skipPush, "skip-push", false, "Skip pushing function to remote registry")
	upFlagset.BoolVar(&skipDeploy, "skip-deploy", false, "Skip function deployment")
	upCmd.Flags().AddFlagSet(upFlagset)

	build, _, _ := faasCmd.Find([]string{"build"})
	upCmd.Flags().AddFlagSet(build.Flags())

	push, _, _ := faasCmd.Find([]string{"push"})
	upCmd.Flags().AddFlagSet(push.Flags())

	deploy, _, _ := faasCmd.Find([]string{"deploy"})
	upCmd.Flags().AddFlagSet(deploy.Flags())

	faasCmd.AddCommand(upCmd)
}

// upCmd is a wrapper to the build, push and deploy commands
var upCmd = &cobra.Command{
	Use:   `up -f [YAML_FILE] [--skip-push] [--skip-deploy] [flags from build, push, deploy]`,
	Short: "Builds, pushes and deploys OpenFaaS function containers",
	Long: `Build, Push, and Deploy OpenFaaS function containers either via the
supplied YAML config using the "--yaml" flag (which may contain multiple function
definitions), or directly via flags.

The push step may be skipped by setting the --skip-push flag
and the deploy step with --skip-deploy.

Note: All flags from the build, push and deploy flags are valid and can be combined,
see the --help text for those commands for details.`,
	Example: `  faas-cli up -f myfn.yaml
faas-cli up --filter "*gif*" --secret dockerhuborg`,
	PreRunE: preRunUp,
	RunE:    upHandler,
}

func preRunUp(cmd *cobra.Command, args []string) error {
	if err := preRunBuild(cmd, args); err != nil {
		return err
	}
	if err := preRunDeploy(cmd, args); err != nil {
		return err
	}
	return nil
}

func upHandler(cmd *cobra.Command, args []string) error {
	if err := runBuild(cmd, args); err != nil {
		return err
	}
	fmt.Println()
	if !skipPush {
		if err := runPush(cmd, args); err != nil {
			return err
		}
		fmt.Println()
	}
	if !skipDeploy {
		if err := runDeploy(cmd, args); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	log "code.google.com/p/log4go"
)

const (
	// signal command
	SignalNum   = 1
	ProtoFinish = 0
	ProtoReady  = 1
)

type Ring struct {
	// read
	// rn int
	rp int
	// add data here split reade & write in one cacheline
	data []Proto
	num  int
	mask int
	// write
	// wn int
	wp int
}

func NewRing(num int) *Ring {
	r := new(Ring)
	r.init(num)
	return r
}

func (r *Ring) init(num int) {
	num = (num + 1) & ^1
	r.data = make([]Proto, num)
	r.num = num
	r.mask = r.num - 1
}

func (r *Ring) Init(num int) {
	r.init(num)
}

func (r *Ring) Get() (proto *Proto, err error) {
	if r.rp == r.wp {
		return nil, ErrRingEmpty
	}
	proto = &r.data[r.rp&r.mask]
	return
}

func (r *Ring) GetAdv() {
	r.rp++
	if Debug {
		log.Debug("ring rp: %d, idx: %d", r.rp, r.rp&r.mask)
	}
}

func (r *Ring) Set() (proto *Proto, err error) {
	if r.wp-r.rp >= r.num {
		return nil, ErrRingFull
	}
	proto = &r.data[r.wp&r.mask]
	return
}

func (r *Ring) SetAdv() {
	r.wp++
	if Debug {
		log.Debug("ring wp: %d, idx: %d", r.wp, r.wp&r.mask)
	}
}

func (r *Ring) Reset() {
	r.rp = 0
	r.wp = 0
}
<commit_msg>fix bug<commit_after>package main

import (
	log "code.google.com/p/log4go"
)

const (
	// signal command
	SignalNum   = 1
	ProtoFinish = 0
	ProtoReady  = 1
)

type Ring struct {
	// read
	rp   uint64
	num  uint64
	mask uint64
	// TODO split cacheline, many cpu cache line size is 64
	// pad [40]byte
	// write
	wp   uint64
	data []Proto
}

func NewRing(num int) *Ring {
	r := new(Ring)
	r.init(uint64(num))
	return r
}

func (r *Ring) Init(num int) {
	r.init(uint64(num))
}

func (r *Ring) init(num uint64) {
	// 2^N
	if num&(num-1) != 0 {
		for num&(num-1) != 0 {
			num &= (num - 1)
		}
		num = num << 1
	}
	r.data = make([]Proto, num)
	r.num = num
	r.mask = r.num - 1
}

func (r *Ring) Get() (proto *Proto, err error) {
	if r.rp == r.wp {
		return nil, ErrRingEmpty
	}
	proto = &r.data[r.rp&r.mask]
	return
}

func (r *Ring) GetAdv() {
	r.rp++
	if Debug {
		log.Debug("ring rp: %d, idx: %d", r.rp, r.rp&r.mask)
	}
}

func (r *Ring) Set() (proto *Proto, err error) {
	if r.wp-r.rp >= r.num {
		return nil, ErrRingFull
	}
	proto = &r.data[r.wp&r.mask]
	return
}

func (r *Ring) SetAdv() {
	r.wp++
	if Debug {
		log.Debug("ring wp: %d, idx: %d", r.wp, r.wp&r.mask)
	}
}

func (r *Ring) Reset() {
	r.rp = 0
	r.wp = 0
	// prevent pad compiler optimization
	// r.pad = [40]byte{}
}
<|endoftext|>


<commit_before>package common

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"io/ioutil"
	"log"

	"engo.io/engo"
	"engo.io/gl"
	"github.com/golang/freetype"
	"github.com/golang/freetype/truetype"
	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

var (
	dpi = float64(72)
)

type Font struct {
	URL  string
	Size float64
	BG   color.Color
	FG   color.Color
	TTF  *truetype.Font
}

// Create is for loading fonts from the disk, given a location
func (f *Font) Create() error {
	// Read and parse the font
	ttfBytes, err := ioutil.ReadFile(f.URL)
	if err != nil {
		return err
	}

	ttf, err := freetype.ParseFont(ttfBytes)
	if err != nil {
		return err
	}
	f.TTF = ttf

	return nil
}

// CreatePreloaded is for loading fonts which have already been defined (and loaded) within Preload
func (f *Font) CreatePreloaded() error {
	fontres, err := engo.Files.Resource(f.URL)
	if err != nil {
		return err
	}

	font, ok := fontres.(FontResource)
	if !ok {
		return fmt.Errorf("preloaded font is not of type `*truetype.Font`: %s", f.URL)
	}

	f.TTF = font.Font
	return nil
}

func (f *Font) TextDimensions(text string) (int, int, int) {
	fnt := f.TTF
	size := f.Size
	var (
		totalWidth  = fixed.Int26_6(0)
		totalHeight = fixed.Int26_6(size)
		maxYBearing = fixed.Int26_6(0)
	)
	fupe := fixed.Int26_6(fnt.FUnitsPerEm())

	for _, char := range text {
		idx := fnt.Index(char)
		hm := fnt.HMetric(fupe, idx)
		vm := fnt.VMetric(fupe, idx)
		g := truetype.GlyphBuf{}
		err := g.Load(fnt, fupe, idx, font.HintingNone)
		if err != nil {
			log.Println(err)
			return 0, 0, 0
		}
		totalWidth += hm.AdvanceWidth

		yB := (vm.TopSideBearing * fixed.Int26_6(size)) / fupe
		if yB > maxYBearing {
			maxYBearing = yB
		}
		dY := (vm.AdvanceHeight * fixed.Int26_6(size)) / fupe
		if dY > totalHeight {
			totalHeight = dY
		}
	}

	// Scale to actual pixel size
	totalWidth *= fixed.Int26_6(size)
	totalWidth /= fupe

	return int(totalWidth), int(totalHeight), int(maxYBearing)
}

func (f *Font) RenderNRGBA(text string) *image.NRGBA {
	width, height, yBearing := f.TextDimensions(text)
	font := f.TTF
	size := f.Size

	if size <= 0 {
		panic("Font size cannot be <= 0")
	}

	// Default colors
	if f.FG == nil {
		f.FG = color.NRGBA{0, 0, 0, 0}
	}
	if f.BG == nil {
		f.BG = color.NRGBA{0, 0, 0, 0}
	}

	// Colors
	fg := image.NewUniform(f.FG)
	bg := image.NewUniform(f.BG)

	// Create the font context
	c := freetype.NewContext()

	nrgba := image.NewNRGBA(image.Rect(0, 0, width, height))
	draw.Draw(nrgba, nrgba.Bounds(), bg, image.ZP, draw.Src)

	c.SetDPI(dpi)
	c.SetFont(font)
	c.SetFontSize(size)
	c.SetClip(nrgba.Bounds())
	c.SetDst(nrgba)
	c.SetSrc(fg)

	// Draw the text.
	pt := fixed.P(0, yBearing)
	_, err := c.DrawString(text, pt)
	if err != nil {
		log.Println(err)
		return nil
	}

	return nrgba
}

func (f *Font) Render(text string) Texture {
	nrgba := f.RenderNRGBA(text)

	// Create texture
	imObj := NewImageObject(nrgba)
	return NewTextureSingle(imObj)
}

// generateFontAtlas generates the font atlas for this given font, using the first `c` Unicode characters.
func (f *Font) generateFontAtlas(c int) FontAtlas {
	atlas := FontAtlas{
		XLocation: make([]float32, c),
		YLocation: make([]float32, c),
		Width:     make([]float32, c),
		Height:    make([]float32, c),
	}

	currentX := float32(0)
	currentY := float32(0)

	// Default colors
	if f.FG == nil {
		f.FG = color.NRGBA{0, 0, 0, 0}
	}
	if f.BG == nil {
		f.BG = color.NRGBA{0, 0, 0, 0}
	}

	d := &font.Drawer{}
	d.Src = image.NewUniform(f.FG)
	d.Face = truetype.NewFace(f.TTF, &truetype.Options{
		Size:    f.Size,
		DPI:     dpi,
		Hinting: font.HintingNone,
	})

	lineHeight := d.Face.Metrics().Height

	for i := 0; i < c; i++ {
		_, adv, ok := d.Face.GlyphBounds(rune(i))
		if !ok {
			continue
		}

		atlas.Width[i] = float32(adv.Ceil())
		atlas.Height[i] = float32(lineHeight.Ceil()) + 5
		atlas.XLocation[i] = currentX
		atlas.YLocation[i] = currentY

		currentX += float32(adv.Ceil())
		if currentX > 255 || i >= c-1 {
			if currentX > atlas.TotalWidth {
				atlas.TotalWidth = currentX
			}
			currentX = 0
			currentY += float32(lineHeight.Ceil()) + 5
			atlas.TotalHeight += float32(lineHeight.Ceil()) + 5
		}
	}

	// Create texture
	actual := image.NewNRGBA(image.Rect(0, 0, int(atlas.TotalWidth), int(atlas.TotalHeight)))
	d.Dst = actual

	currentX = 0
	currentY = float32(lineHeight.Ceil())
	for i := 0; i < c; i++ {
		_, adv, ok := d.Face.GlyphBounds(rune(i))
		if !ok {
			continue
		}
		d.Dot = fixed.P(int(currentX), int(currentY))
		d.DrawBytes([]byte{byte(i)})
		currentX += float32(adv.Ceil())
		if currentX > 255 || i == c-1 {
			currentX = 0
			currentY += float32(lineHeight.Ceil()) + 5
		}
	}

	imObj := NewImageObject(actual)
	atlas.Texture = NewTextureSingle(imObj).id

	return atlas
}

// A FontAtlas is a representation of some of the Font characters, as an image
type FontAtlas struct {
	Texture *gl.Texture
	// XLocation contains the X-coordinate of the starting position of all characters
	XLocation []float32
	// YLocation contains the Y-coordinate of the starting position of all characters
	YLocation []float32
	// Width contains the width in pixels of all the characters, including the spacing between characters
	Width []float32
	// Height contains the height in pixels of all the characters
	Height []float32
	// TotalWidth is the total amount of pixels the `FontAtlas` is wide; useful for determining the `Viewport`,
	// which is relative to this value.
	TotalWidth float32
	// TotalHeight is the total amount of pixels the `FontAtlas` is high; useful for determining the `Viewport`,
	// which is relative to this value.
	TotalHeight float32
}

// Text represents a string drawn onto the screen, as used by the `TextShader`.
type Text struct {
	// Font is the reference to the font you're using to render this. This includes the color, as well as the font size.
	Font *Font
	// Text is the actual text you want to draw. This may include newlines (\n).
	Text string
	// LineSpacing is the amount of additional spacing there is between the lines (when `Text` consists of multiple lines),
	// relative to the `Size` of the `Font`.
	LineSpacing float32
	// LetterSpacing is the amount of additional spacing there is between the characters, relative to the `Size` of
	// the `Font`.
	LetterSpacing float32
	// RightToLeft is an experimental variable used to indicate that subsequent characters come to the left of the
	// previous character.
	RightToLeft bool
}

func (Text) Texture() *gl.Texture                       { return nil }
func (Text) Width() float32                             { return 0 }
func (Text) Height() float32                            { return 0 }
func (Text) View() (float32, float32, float32, float32) { return 0, 0, 1, 1 }
func (Text) Close()                                     {}
<commit_msg>add a dynamic buffer<commit_after>package common

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"io/ioutil"
	"log"

	"engo.io/engo"
	"engo.io/gl"
	"github.com/golang/freetype"
	"github.com/golang/freetype/truetype"
	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

var (
	dpi = float64(72)
)

type Font struct {
	URL  string
	Size float64
	BG   color.Color
	FG   color.Color
	TTF  *truetype.Font
}

// Create is for loading fonts from the disk, given a location
func (f *Font) Create() error {
	// Read and parse the font
	ttfBytes, err := ioutil.ReadFile(f.URL)
	if err != nil {
		return err
	}

	ttf, err := freetype.ParseFont(ttfBytes)
	if err != nil {
		return err
	}
	f.TTF = ttf

	return nil
}

// CreatePreloaded is for loading fonts which have already been defined (and loaded) within Preload
func (f *Font) CreatePreloaded() error {
	fontres, err := engo.Files.Resource(f.URL)
	if err != nil {
		return err
	}

	font, ok := fontres.(FontResource)
	if !ok {
		return fmt.Errorf("preloaded font is not of type `*truetype.Font`: %s", f.URL)
	}

	f.TTF = font.Font
	return nil
}

func (f *Font) TextDimensions(text string) (int, int, int) {
	fnt := f.TTF
	size := f.Size
	var (
		totalWidth  = fixed.Int26_6(0)
		totalHeight = fixed.Int26_6(size)
		maxYBearing = fixed.Int26_6(0)
	)
	fupe := fixed.Int26_6(fnt.FUnitsPerEm())

	for _, char := range text {
		idx := fnt.Index(char)
		hm := fnt.HMetric(fupe, idx)
		vm := fnt.VMetric(fupe, idx)
		g := truetype.GlyphBuf{}
		err := g.Load(fnt, fupe, idx, font.HintingNone)
		if err != nil {
			log.Println(err)
			return 0, 0, 0
		}
		totalWidth += hm.AdvanceWidth

		yB := (vm.TopSideBearing * fixed.Int26_6(size)) / fupe
		if yB > maxYBearing {
			maxYBearing = yB
		}
		dY := (vm.AdvanceHeight * fixed.Int26_6(size)) / fupe
		if dY > totalHeight {
			totalHeight = dY
		}
	}

	// Scale to actual pixel size
	totalWidth *= fixed.Int26_6(size)
	totalWidth /= fupe

	return int(totalWidth), int(totalHeight), int(maxYBearing)
}

func (f *Font) RenderNRGBA(text string) *image.NRGBA {
	width, height, yBearing := f.TextDimensions(text)
	font := f.TTF
	size := f.Size

	if size <= 0 {
		panic("Font size cannot be <= 0")
	}

	// Default colors
	if f.FG == nil {
		f.FG = color.NRGBA{0, 0, 0, 0}
	}
	if f.BG == nil {
		f.BG = color.NRGBA{0, 0, 0, 0}
	}

	// Colors
	fg := image.NewUniform(f.FG)
	bg := image.NewUniform(f.BG)

	// Create the font context
	c := freetype.NewContext()

	nrgba := image.NewNRGBA(image.Rect(0, 0, width, height))
	draw.Draw(nrgba, nrgba.Bounds(), bg, image.ZP, draw.Src)

	c.SetDPI(dpi)
	c.SetFont(font)
	c.SetFontSize(size)
	c.SetClip(nrgba.Bounds())
	c.SetDst(nrgba)
	c.SetSrc(fg)

	// Draw the text.
	pt := fixed.P(0, yBearing)
	_, err := c.DrawString(text, pt)
	if err != nil {
		log.Println(err)
		return nil
	}

	return nrgba
}

func (f *Font) Render(text string) Texture {
	nrgba := f.RenderNRGBA(text)

	// Create texture
	imObj := NewImageObject(nrgba)
	return NewTextureSingle(imObj)
}

// generateFontAtlas generates the font atlas for this given font, using the first `c` Unicode characters.
func (f *Font) generateFontAtlas(c int) FontAtlas {
	atlas := FontAtlas{
		XLocation: make([]float32, c),
		YLocation: make([]float32, c),
		Width:     make([]float32, c),
		Height:    make([]float32, c),
	}

	currentX := float32(0)
	currentY := float32(0)

	// Default colors
	if f.FG == nil {
		f.FG = color.NRGBA{0, 0, 0, 0}
	}
	if f.BG == nil {
		f.BG = color.NRGBA{0, 0, 0, 0}
	}

	d := &font.Drawer{}
	d.Src = image.NewUniform(f.FG)
	d.Face = truetype.NewFace(f.TTF, &truetype.Options{
		Size:    f.Size,
		DPI:     dpi,
		Hinting: font.HintingNone,
	})

	lineHeight := d.Face.Metrics().Height
	lineBuffer := float32(lineHeight.Ceil()) / 2

	for i := 0; i < c; i++ {
		_, adv, ok := d.Face.GlyphBounds(rune(i))
		if !ok {
			continue
		}

		atlas.Width[i] = float32(adv.Ceil())
		atlas.Height[i] = float32(lineHeight.Ceil()) + lineBuffer
		fmt.Println(float32(lineHeight.Ceil()))
		atlas.XLocation[i] = currentX
		atlas.YLocation[i] = currentY

		currentX += float32(adv.Ceil())
		if currentX > 255 || i >= c-1 {
			if currentX > atlas.TotalWidth {
				atlas.TotalWidth = currentX
			}
			currentX = 0
			currentY += float32(lineHeight.Ceil()) + lineBuffer
			atlas.TotalHeight += float32(lineHeight.Ceil()) + lineBuffer
		}
	}

	// Create texture
	actual := image.NewNRGBA(image.Rect(0, 0, int(atlas.TotalWidth), int(atlas.TotalHeight)))
	d.Dst = actual

	currentX = 0
	currentY = float32(lineHeight.Ceil())
	for i := 0; i < c; i++ {
		_, adv, ok := d.Face.GlyphBounds(rune(i))
		if !ok {
			continue
		}
		d.Dot = fixed.P(int(currentX), int(currentY))
		d.DrawBytes([]byte{byte(i)})
		currentX += float32(adv.Ceil())
		if currentX > 255 || i == c-1 {
			currentX = 0
			currentY += float32(lineHeight.Ceil()) + lineBuffer
		}
	}

	imObj := NewImageObject(actual)
	atlas.Texture = NewTextureSingle(imObj).id

	return atlas
}

// A FontAtlas is a representation of some of the Font characters, as an image
type FontAtlas struct {
	Texture *gl.Texture
	// XLocation contains the X-coordinate of the starting position of all characters
	XLocation []float32
	// YLocation contains the Y-coordinate of the starting position of all characters
	YLocation []float32
	// Width contains the width in pixels of all the characters, including the spacing between characters
	Width []float32
	// Height contains the height in pixels of all the characters
	Height []float32
	// TotalWidth is the total amount of pixels the `FontAtlas` is wide; useful for determining the `Viewport`,
	// which is relative to this value.
	TotalWidth float32
	// TotalHeight is the total amount of pixels the `FontAtlas` is high; useful for determining the `Viewport`,
	// which is relative to this value.
	TotalHeight float32
}

// Text represents a string drawn onto the screen, as used by the `TextShader`.
type Text struct {
	// Font is the reference to the font you're using to render this. This includes the color, as well as the font size.
	Font *Font
	// Text is the actual text you want to draw. This may include newlines (\n).
	Text string
	// LineSpacing is the amount of additional spacing there is between the lines (when `Text` consists of multiple lines),
	// relative to the `Size` of the `Font`.
	LineSpacing float32
	// LetterSpacing is the amount of additional spacing there is between the characters, relative to the `Size` of
	// the `Font`.
	LetterSpacing float32
	// RightToLeft is an experimental variable used to indicate that subsequent characters come to the left of the
	// previous character.
	RightToLeft bool
}

func (Text) Texture() *gl.Texture                       { return nil }
func (Text) Width() float32                             { return 0 }
func (Text) Height() float32                            { return 0 }
func (Text) View() (float32, float32, float32, float32) { return 0, 0, 1, 1 }
func (Text) Close()                                     {}
<|endoftext|>


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

package buildutil

import (
	"go/build"
	"strings"
	"testing"
)

// TransitiveImports returns a set containing all of importpath's
// transitive dependencies.
func TransitiveImports(importpath string, cgo bool) (map[string]struct{}, error) {
	buildContext := build.Default
	buildContext.CgoEnabled = cgo

	imports := make(map[string]struct{})

	var addImports func(string) error
	addImports = func(root string) error {
		// Skip runtime packages (i.e. packages which don't contain a ".")
		//
		// TODO(peter): This is necessary because we're not handling vendoring
		// correctly. The upstream code this was borrowed from
		// (golang/tools/refactor) has changed significantly.
		if strings.IndexByte(root, '.') == -1 {
			return nil
		}

		pkg, err := buildContext.Import(root, buildContext.GOPATH, 0)
		if err != nil {
			return err
		}

		for _, imp := range pkg.Imports {
			// https://github.com/golang/tools/blob/master/refactor/importgraph/graph.go#L115
			if imp == "C" {
				continue // "C" is fake
			}
			if _, ok := imports[imp]; !ok {
				imports[imp] = struct{}{}
				if err := addImports(imp); err != nil {
					return err
				}
			}
		}
		return nil
	}

	return imports, addImports(importpath)
}

// VerifyNoImports verifies that a package doesn't depend (directly or
// indirectly) on forbidden packages. The forbidden packages are specified as
// either exact matches or prefix matches.
// If GOPATH isn't set, it is an indication that the source is not available and
// the test is skipped.
func VerifyNoImports(
	t testing.TB,
	pkgPath string,
	cgo bool,
	forbiddenPkgs, forbiddenPrefixes []string,
) {
	// Skip test if source is not available.
	if build.Default.GOPATH == "" {
		t.Skip("GOPATH isn't set")
	}

	imports, err := TransitiveImports(pkgPath, true)
	if err != nil {
		t.Fatal(err)
	}

	for _, forbidden := range forbiddenPkgs {
		if _, ok := imports[forbidden]; ok {
			t.Errorf("Package %s includes %s, which is forbidden", pkgPath, forbidden)
		}
	}
	for _, forbiddenPrefix := range forbiddenPrefixes {
		for k := range imports {
			if strings.HasPrefix(k, forbiddenPrefix) {
				t.Errorf("Package %s includes %s, which is forbidden", pkgPath, k)
			}
		}
	}
}
<commit_msg>testutils/buildutil: properly canonicalize import paths<commit_after>// Copyright 2015 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// Author: Peter Mattis (peter@cockroachlabs.com)

package buildutil

import (
	"go/build"
	"strings"
	"testing"
)

// TransitiveImports returns a set containing all of importpath's
// transitive dependencies.
func TransitiveImports(importpath string, cgo bool) (map[string]struct{}, error) {
	buildContext := build.Default
	buildContext.CgoEnabled = cgo

	imports := make(map[string]struct{})

	var addImports func(string) error
	addImports = func(root string) error {
		pkg, err := buildContext.Import(root, "", 0)
		if err != nil {
			return err
		}

		for _, imp := range pkg.Imports {
			// https://github.com/golang/tools/blob/master/refactor/importgraph/graph.go#L115
			if imp == "C" {
				continue // "C" is fake
			}
			importPkg, err := buildContext.Import(imp, pkg.Dir, build.FindOnly)
			if err != nil {
				return err
			}
			imp = importPkg.ImportPath
			if _, ok := imports[imp]; !ok {
				imports[imp] = struct{}{}
				if err := addImports(imp); err != nil {
					return err
				}
			}
		}
		return nil
	}

	return imports, addImports(importpath)
}

// VerifyNoImports verifies that a package doesn't depend (directly or
// indirectly) on forbidden packages. The forbidden packages are specified as
// either exact matches or prefix matches.
// If GOPATH isn't set, it is an indication that the source is not available and
// the test is skipped.
func VerifyNoImports(
	t testing.TB,
	pkgPath string,
	cgo bool,
	forbiddenPkgs, forbiddenPrefixes []string,
) {
	// Skip test if source is not available.
	if build.Default.GOPATH == "" {
		t.Skip("GOPATH isn't set")
	}

	imports, err := TransitiveImports(pkgPath, true)
	if err != nil {
		t.Fatal(err)
	}

	for _, forbidden := range forbiddenPkgs {
		if _, ok := imports[forbidden]; ok {
			t.Errorf("Package %s includes %s, which is forbidden", pkgPath, forbidden)
		}
	}
	for _, forbiddenPrefix := range forbiddenPrefixes {
		for k := range imports {
			if strings.HasPrefix(k, forbiddenPrefix) {
				t.Errorf("Package %s includes %s, which is forbidden", pkgPath, k)
			}
		}
	}
}
<|endoftext|>


<commit_before>package hamming

// Distance returns the hamming distance between two DNA strands A and B.
func Distance(a, b string) (int, error) {
	return 0, nil
}
<commit_msg>Solve hamming<commit_after>package hamming

import "errors"

// Distance returns the hamming distance between two DNA strands A and B.
func Distance(a, b string) (int, error) {
	distance := 0
	if len(a) != len(b) {
		return distance, errors.New("a and b must be of equal length")
	}

	for i := range a {
		if a[i] != b[i] {
			distance++
		}
	}
	return distance, nil
}
<|endoftext|>


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

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/maruel/subcommands"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/auth/client/authcli"
	"go.chromium.org/luci/common/cli"
	"go.chromium.org/luci/common/data/rand/mathrand"
	"go.chromium.org/luci/common/lhttp"
	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/common/logging/gologger"
	"go.chromium.org/luci/grpc/prpc"

	"go.chromium.org/luci/hardcoded/chromeinfra"
)

const (
	userAgent = "luci-prpc"
)

var logCfg = gologger.LoggerConfig{
	Format: `%{message}`,
	Out:    os.Stderr,
}

// exit codes:
const (
	ecInvalidCommandLine = -iota
	ecAuthenticatedClientError
	ecOtherError
)

type exitCode struct {
	err  error
	code int
}

func (e *exitCode) Error() string { return e.err.Error() }

// cmdRun is a base of all prpc subcommands.
// It defines some common flags, such as logging and auth, and useful methods.
type cmdRun struct {
	subcommands.CommandRunBase
	verbose bool
	auth    authcli.Flags
}

// ModifyContext implements cli.ContextModificator.
func (r *cmdRun) ModifyContext(ctx context.Context) context.Context {
	if r.verbose {
		ctx = logging.SetLevel(ctx, logging.Debug)
	}
	return ctx
}

// registerBaseFlags registers common flags used by all subcommands.
func (r *cmdRun) registerBaseFlags(defaultAuthOpts auth.Options) {
	r.Flags.BoolVar(&r.verbose, "verbose", false, "Enable more logging.")
	r.auth.Register(&r.Flags, defaultAuthOpts)
}

func (r *cmdRun) authenticatedClient(ctx context.Context, host string) (*prpc.Client, error) {
	authOpts, err := r.auth.Options()
	if err != nil {
		return nil, err
	}
	a := auth.NewAuthenticator(ctx, auth.OptionalLogin, authOpts)
	httpClient, err := a.Client()
	if err != nil {
		return nil, err
	}

	client := prpc.Client{
		C:       httpClient,
		Host:    host,
		Options: prpc.DefaultOptions(),
	}
	client.Options.Insecure = lhttp.IsLocalHost(host)
	return &client, nil
}

// argErr prints an err and usage to stderr and returns an exit code.
func (r *cmdRun) argErr(shortDesc, usageLine, format string, a ...interface{}) int {
	if format != "" {
		fmt.Fprintf(os.Stderr, format+"\n", a...)
	}
	fmt.Fprintln(os.Stderr, shortDesc)
	fmt.Fprintln(os.Stderr, usageLine)
	fmt.Fprintln(os.Stderr, "\nFlags:")
	r.Flags.PrintDefaults()
	return ecInvalidCommandLine
}

// done prints err to stderr if it is not nil and returns an exit code.
func (r *cmdRun) done(err error) int {
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		if err, ok := err.(*exitCode); ok {
			return err.code
		}
		return ecOtherError
	}
	return 0
}

func getApplication(defaultAuthOpts auth.Options) *cli.Application {
	return &cli.Application{
		Name:  "prpc",
		Title: "Provisional Remote Procedure Call CLI",
		Context: func(ctx context.Context) context.Context {
			return logCfg.Use(ctx)
		},
		Commands: []*subcommands.Command{
			cmdCall(defaultAuthOpts),
			cmdShow(defaultAuthOpts),

			{ /* spacer */ },

			authcli.SubcommandLogin(defaultAuthOpts, "login", false),
			authcli.SubcommandLogout(defaultAuthOpts, "logout", false),

			{ /* spacer */ },

			subcommands.CmdHelp,
		},
	}
}

func main() {
	mathrand.SeedRandomly()
	app := getApplication(chromeinfra.DefaultAuthOptions())
	os.Exit(subcommands.Run(app, os.Args[1:]))
}
<commit_msg>[prpc] Add -force-insecure flag<commit_after>// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/maruel/subcommands"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/auth/client/authcli"
	"go.chromium.org/luci/common/cli"
	"go.chromium.org/luci/common/data/rand/mathrand"
	"go.chromium.org/luci/common/lhttp"
	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/common/logging/gologger"
	"go.chromium.org/luci/grpc/prpc"

	"go.chromium.org/luci/hardcoded/chromeinfra"
)

const (
	userAgent = "luci-prpc"
)

var logCfg = gologger.LoggerConfig{
	Format: `%{message}`,
	Out:    os.Stderr,
}

// exit codes:
const (
	ecInvalidCommandLine = -iota
	ecAuthenticatedClientError
	ecOtherError
)

type exitCode struct {
	err  error
	code int
}

func (e *exitCode) Error() string { return e.err.Error() }

// cmdRun is a base of all prpc subcommands.
// It defines some common flags, such as logging and auth, and useful methods.
type cmdRun struct {
	subcommands.CommandRunBase
	verbose       bool
	forceInsecure bool
	auth          authcli.Flags
}

// ModifyContext implements cli.ContextModificator.
func (r *cmdRun) ModifyContext(ctx context.Context) context.Context {
	if r.verbose {
		ctx = logging.SetLevel(ctx, logging.Debug)
	}
	return ctx
}

// registerBaseFlags registers common flags used by all subcommands.
func (r *cmdRun) registerBaseFlags(defaultAuthOpts auth.Options) {
	r.Flags.BoolVar(&r.verbose, "verbose", false, "Enable more logging.")
	r.Flags.BoolVar(&r.forceInsecure, "force-insecure", false, "Force HTTP instead of HTTPS")
	r.auth.Register(&r.Flags, defaultAuthOpts)
}

func (r *cmdRun) authenticatedClient(ctx context.Context, host string) (*prpc.Client, error) {
	authOpts, err := r.auth.Options()
	if err != nil {
		return nil, err
	}
	a := auth.NewAuthenticator(ctx, auth.OptionalLogin, authOpts)
	httpClient, err := a.Client()
	if err != nil {
		return nil, err
	}

	client := prpc.Client{
		C:       httpClient,
		Host:    host,
		Options: prpc.DefaultOptions(),
	}
	client.Options.Insecure = r.forceInsecure || lhttp.IsLocalHost(host)
	return &client, nil
}

// argErr prints an err and usage to stderr and returns an exit code.
func (r *cmdRun) argErr(shortDesc, usageLine, format string, a ...interface{}) int {
	if format != "" {
		fmt.Fprintf(os.Stderr, format+"\n", a...)
	}
	fmt.Fprintln(os.Stderr, shortDesc)
	fmt.Fprintln(os.Stderr, usageLine)
	fmt.Fprintln(os.Stderr, "\nFlags:")
	r.Flags.PrintDefaults()
	return ecInvalidCommandLine
}

// done prints err to stderr if it is not nil and returns an exit code.
func (r *cmdRun) done(err error) int {
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		if err, ok := err.(*exitCode); ok {
			return err.code
		}
		return ecOtherError
	}
	return 0
}

func getApplication(defaultAuthOpts auth.Options) *cli.Application {
	return &cli.Application{
		Name:  "prpc",
		Title: "Provisional Remote Procedure Call CLI",
		Context: func(ctx context.Context) context.Context {
			return logCfg.Use(ctx)
		},
		Commands: []*subcommands.Command{
			cmdCall(defaultAuthOpts),
			cmdShow(defaultAuthOpts),

			{ /* spacer */ },

			authcli.SubcommandLogin(defaultAuthOpts, "login", false),
			authcli.SubcommandLogout(defaultAuthOpts, "logout", false),

			{ /* spacer */ },

			subcommands.CmdHelp,
		},
	}
}

func main() {
	mathrand.SeedRandomly()
	app := getApplication(chromeinfra.DefaultAuthOptions())
	os.Exit(subcommands.Run(app, os.Args[1:]))
}
<|endoftext|>


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

package template

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"reflect"
	"strings"
	"unicode"
	"utf8"
)

// FuncMap is the type of the map defining the mapping from names to functions.
// Each function must have either a single return value, or two return values of
// which the second has type os.Error.
type FuncMap map[string]interface{}

var funcs = map[string]reflect.Value{
	"and":    reflect.ValueOf(and),
	"html":   reflect.ValueOf(HTMLEscaper),
	"index":  reflect.ValueOf(index),
	"js":     reflect.ValueOf(JSEscaper),
	"not":    reflect.ValueOf(not),
	"or":     reflect.ValueOf(or),
	"printf": reflect.ValueOf(fmt.Sprintf),
}

// addFuncs adds to values the functions in funcs, converting them to reflect.Values.
func addFuncs(values map[string]reflect.Value, funcMap FuncMap) {
	for name, fn := range funcMap {
		v := reflect.ValueOf(fn)
		if v.Kind() != reflect.Func {
			panic("value for " + name + " not a function")
		}
		if !goodFunc(v.Type()) {
			panic(fmt.Errorf("can't handle multiple results from method/function %q", name))
		}
		values[name] = v
	}
}

// goodFunc checks that the function or method has the right result signature.
func goodFunc(typ reflect.Type) bool {
	// We allow functions with 1 result or 2 results where the second is an os.Error.
	switch {
	case typ.NumOut() == 1:
		return true
	case typ.NumOut() == 2 && typ.Out(1) == osErrorType:
		return true
	}
	return false
}

// findFunction looks for a function in the template, set, and global map.
func findFunction(name string, tmpl *Template, set *Set) (reflect.Value, bool) {
	if tmpl != nil {
		if fn := tmpl.funcs[name]; fn.IsValid() {
			return fn, true
		}
	}
	if set != nil {
		if fn := set.funcs[name]; fn.IsValid() {
			return fn, true
		}
	}
	if fn := funcs[name]; fn.IsValid() {
		return fn, true
	}
	return reflect.Value{}, false
}

// Indexing.

// index returns the result of indexing its first argument by the following
// arguments.  Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
// indexed item must be a map, slice, or array.
func index(item interface{}, indices ...interface{}) (interface{}, os.Error) {
	v := reflect.ValueOf(item)
	for _, i := range indices {
		index := reflect.ValueOf(i)
		switch v.Kind() {
		case reflect.Array, reflect.Slice:
			var x int64
			switch index.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				x = index.Int()
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
				x = int64(index.Uint())
			default:
				return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
			}
			if x < 0 || x >= int64(v.Len()) {
				return nil, fmt.Errorf("index out of range: %d", x)
			}
			v = v.Index(int(x))
		case reflect.Map:
			if !index.Type().AssignableTo(v.Type().Key()) {
				return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
			}
			v = v.MapIndex(index)
			if !v.IsValid() {
				return nil, fmt.Errorf("index %v not present in map", index.Interface())
			}
		default:
			return nil, fmt.Errorf("can't index item of type %s", index.Type())
		}
	}
	return v.Interface(), nil
}

// Boolean logic.

// and returns the Boolean AND of its arguments.
func and(arg0 interface{}, args ...interface{}) (truth bool) {
	truth, _ = isTrue(reflect.ValueOf(arg0))
	for i := 0; truth && i < len(args); i++ {
		truth, _ = isTrue(reflect.ValueOf(args[i]))
	}
	return
}

// or returns the Boolean OR of its arguments.
func or(arg0 interface{}, args ...interface{}) (truth bool) {
	truth, _ = isTrue(reflect.ValueOf(arg0))
	for i := 0; !truth && i < len(args); i++ {
		truth, _ = isTrue(reflect.ValueOf(args[i]))
	}
	return
}

// not returns the Boolean negation of its argument.
func not(arg interface{}) (truth bool) {
	truth, _ = isTrue(reflect.ValueOf(arg))
	return !truth
}

// HTML escaping.

var (
	htmlQuot = []byte(""") // shorter than """
	htmlApos = []byte("'") // shorter than "'"
	htmlAmp  = []byte("&")
	htmlLt   = []byte("<")
	htmlGt   = []byte(">")
)

// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
func HTMLEscape(w io.Writer, b []byte) {
	last := 0
	for i, c := range b {
		var html []byte
		switch c {
		case '"':
			html = htmlQuot
		case '\'':
			html = htmlApos
		case '&':
			html = htmlAmp
		case '<':
			html = htmlLt
		case '>':
			html = htmlGt
		default:
			continue
		}
		w.Write(b[last:i])
		w.Write(html)
		last = i + 1
	}
	w.Write(b[last:])
}

// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
func HTMLEscapeString(s string) string {
	// Avoid allocation if we can.
	if strings.IndexAny(s, `'"&<>`) < 0 {
		return s
	}
	var b bytes.Buffer
	HTMLEscape(&b, []byte(s))
	return b.String()
}

// HTMLEscaper returns the escaped HTML equivalent of the textual
// representation of its arguments.
func HTMLEscaper(args ...interface{}) string {
	ok := false
	var s string
	if len(args) == 1 {
		s, ok = args[0].(string)
	}
	if !ok {
		s = fmt.Sprint(args...)
	}
	return HTMLEscapeString(s)
}

// JavaScript escaping.

var (
	jsLowUni = []byte(`\u00`)
	hex      = []byte("0123456789ABCDEF")

	jsBackslash = []byte(`\\`)
	jsApos      = []byte(`\'`)
	jsQuot      = []byte(`\"`)
)

// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
func JSEscape(w io.Writer, b []byte) {
	last := 0
	for i := 0; i < len(b); i++ {
		c := b[i]

		if ' ' <= c && c < utf8.RuneSelf && c != '\\' && c != '"' && c != '\'' {
			// fast path: nothing to do
			continue
		}
		w.Write(b[last:i])

		if c < utf8.RuneSelf {
			// Quotes and slashes get quoted.
			// Control characters get written as \u00XX.
			switch c {
			case '\\':
				w.Write(jsBackslash)
			case '\'':
				w.Write(jsApos)
			case '"':
				w.Write(jsQuot)
			default:
				w.Write(jsLowUni)
				t, b := c>>4, c&0x0f
				w.Write(hex[t : t+1])
				w.Write(hex[b : b+1])
			}
		} else {
			// Unicode rune.
			rune, size := utf8.DecodeRune(b[i:])
			if unicode.IsPrint(rune) {
				w.Write(b[i : i+size])
			} else {
				// TODO(dsymonds): Do this without fmt?
				fmt.Fprintf(w, "\\u%04X", rune)
			}
			i += size - 1
		}
		last = i + 1
	}
	w.Write(b[last:])
}

// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
func JSEscapeString(s string) string {
	// Avoid allocation if we can.
	if strings.IndexFunc(s, jsIsSpecial) < 0 {
		return s
	}
	var b bytes.Buffer
	JSEscape(&b, []byte(s))
	return b.String()
}

func jsIsSpecial(rune int) bool {
	switch rune {
	case '\\', '\'', '"':
		return true
	}
	return rune < ' ' || utf8.RuneSelf <= rune
}

// JSEscaper returns the escaped JavaScript equivalent of the textual
// representation of its arguments.
func JSEscaper(args ...interface{}) string {
	ok := false
	var s string
	if len(args) == 1 {
		s, ok = args[0].(string)
	}
	if !ok {
		s = fmt.Sprint(args...)
	}
	return JSEscapeString(s)
}
<commit_msg>exp/template: index: forgot the always last-to-arrive uintptr.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package template

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"reflect"
	"strings"
	"unicode"
	"utf8"
)

// FuncMap is the type of the map defining the mapping from names to functions.
// Each function must have either a single return value, or two return values of
// which the second has type os.Error.
type FuncMap map[string]interface{}

var funcs = map[string]reflect.Value{
	"and":    reflect.ValueOf(and),
	"html":   reflect.ValueOf(HTMLEscaper),
	"index":  reflect.ValueOf(index),
	"js":     reflect.ValueOf(JSEscaper),
	"not":    reflect.ValueOf(not),
	"or":     reflect.ValueOf(or),
	"printf": reflect.ValueOf(fmt.Sprintf),
}

// addFuncs adds to values the functions in funcs, converting them to reflect.Values.
func addFuncs(values map[string]reflect.Value, funcMap FuncMap) {
	for name, fn := range funcMap {
		v := reflect.ValueOf(fn)
		if v.Kind() != reflect.Func {
			panic("value for " + name + " not a function")
		}
		if !goodFunc(v.Type()) {
			panic(fmt.Errorf("can't handle multiple results from method/function %q", name))
		}
		values[name] = v
	}
}

// goodFunc checks that the function or method has the right result signature.
func goodFunc(typ reflect.Type) bool {
	// We allow functions with 1 result or 2 results where the second is an os.Error.
	switch {
	case typ.NumOut() == 1:
		return true
	case typ.NumOut() == 2 && typ.Out(1) == osErrorType:
		return true
	}
	return false
}

// findFunction looks for a function in the template, set, and global map.
func findFunction(name string, tmpl *Template, set *Set) (reflect.Value, bool) {
	if tmpl != nil {
		if fn := tmpl.funcs[name]; fn.IsValid() {
			return fn, true
		}
	}
	if set != nil {
		if fn := set.funcs[name]; fn.IsValid() {
			return fn, true
		}
	}
	if fn := funcs[name]; fn.IsValid() {
		return fn, true
	}
	return reflect.Value{}, false
}

// Indexing.

// index returns the result of indexing its first argument by the following
// arguments.  Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
// indexed item must be a map, slice, or array.
func index(item interface{}, indices ...interface{}) (interface{}, os.Error) {
	v := reflect.ValueOf(item)
	for _, i := range indices {
		index := reflect.ValueOf(i)
		switch v.Kind() {
		case reflect.Array, reflect.Slice:
			var x int64
			switch index.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				x = index.Int()
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
				x = int64(index.Uint())
			default:
				return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
			}
			if x < 0 || x >= int64(v.Len()) {
				return nil, fmt.Errorf("index out of range: %d", x)
			}
			v = v.Index(int(x))
		case reflect.Map:
			if !index.Type().AssignableTo(v.Type().Key()) {
				return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
			}
			v = v.MapIndex(index)
			if !v.IsValid() {
				return nil, fmt.Errorf("index %v not present in map", index.Interface())
			}
		default:
			return nil, fmt.Errorf("can't index item of type %s", index.Type())
		}
	}
	return v.Interface(), nil
}

// Boolean logic.

// and returns the Boolean AND of its arguments.
func and(arg0 interface{}, args ...interface{}) (truth bool) {
	truth, _ = isTrue(reflect.ValueOf(arg0))
	for i := 0; truth && i < len(args); i++ {
		truth, _ = isTrue(reflect.ValueOf(args[i]))
	}
	return
}

// or returns the Boolean OR of its arguments.
func or(arg0 interface{}, args ...interface{}) (truth bool) {
	truth, _ = isTrue(reflect.ValueOf(arg0))
	for i := 0; !truth && i < len(args); i++ {
		truth, _ = isTrue(reflect.ValueOf(args[i]))
	}
	return
}

// not returns the Boolean negation of its argument.
func not(arg interface{}) (truth bool) {
	truth, _ = isTrue(reflect.ValueOf(arg))
	return !truth
}

// HTML escaping.

var (
	htmlQuot = []byte(""") // shorter than """
	htmlApos = []byte("'") // shorter than "'"
	htmlAmp  = []byte("&")
	htmlLt   = []byte("<")
	htmlGt   = []byte(">")
)

// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
func HTMLEscape(w io.Writer, b []byte) {
	last := 0
	for i, c := range b {
		var html []byte
		switch c {
		case '"':
			html = htmlQuot
		case '\'':
			html = htmlApos
		case '&':
			html = htmlAmp
		case '<':
			html = htmlLt
		case '>':
			html = htmlGt
		default:
			continue
		}
		w.Write(b[last:i])
		w.Write(html)
		last = i + 1
	}
	w.Write(b[last:])
}

// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
func HTMLEscapeString(s string) string {
	// Avoid allocation if we can.
	if strings.IndexAny(s, `'"&<>`) < 0 {
		return s
	}
	var b bytes.Buffer
	HTMLEscape(&b, []byte(s))
	return b.String()
}

// HTMLEscaper returns the escaped HTML equivalent of the textual
// representation of its arguments.
func HTMLEscaper(args ...interface{}) string {
	ok := false
	var s string
	if len(args) == 1 {
		s, ok = args[0].(string)
	}
	if !ok {
		s = fmt.Sprint(args...)
	}
	return HTMLEscapeString(s)
}

// JavaScript escaping.

var (
	jsLowUni = []byte(`\u00`)
	hex      = []byte("0123456789ABCDEF")

	jsBackslash = []byte(`\\`)
	jsApos      = []byte(`\'`)
	jsQuot      = []byte(`\"`)
)

// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
func JSEscape(w io.Writer, b []byte) {
	last := 0
	for i := 0; i < len(b); i++ {
		c := b[i]

		if ' ' <= c && c < utf8.RuneSelf && c != '\\' && c != '"' && c != '\'' {
			// fast path: nothing to do
			continue
		}
		w.Write(b[last:i])

		if c < utf8.RuneSelf {
			// Quotes and slashes get quoted.
			// Control characters get written as \u00XX.
			switch c {
			case '\\':
				w.Write(jsBackslash)
			case '\'':
				w.Write(jsApos)
			case '"':
				w.Write(jsQuot)
			default:
				w.Write(jsLowUni)
				t, b := c>>4, c&0x0f
				w.Write(hex[t : t+1])
				w.Write(hex[b : b+1])
			}
		} else {
			// Unicode rune.
			rune, size := utf8.DecodeRune(b[i:])
			if unicode.IsPrint(rune) {
				w.Write(b[i : i+size])
			} else {
				// TODO(dsymonds): Do this without fmt?
				fmt.Fprintf(w, "\\u%04X", rune)
			}
			i += size - 1
		}
		last = i + 1
	}
	w.Write(b[last:])
}

// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
func JSEscapeString(s string) string {
	// Avoid allocation if we can.
	if strings.IndexFunc(s, jsIsSpecial) < 0 {
		return s
	}
	var b bytes.Buffer
	JSEscape(&b, []byte(s))
	return b.String()
}

func jsIsSpecial(rune int) bool {
	switch rune {
	case '\\', '\'', '"':
		return true
	}
	return rune < ' ' || utf8.RuneSelf <= rune
}

// JSEscaper returns the escaped JavaScript equivalent of the textual
// representation of its arguments.
func JSEscaper(args ...interface{}) string {
	ok := false
	var s string
	if len(args) == 1 {
		s, ok = args[0].(string)
	}
	if !ok {
		s = fmt.Sprint(args...)
	}
	return JSEscapeString(s)
}
<|endoftext|>


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

package runtime_test

import (
	. "runtime"
	"sync"
	"testing"
	"time"
	"unsafe"
)

// See stack.h.
const (
	StackGuard = 256
	StackLimit = 128
)

// Test stack split logic by calling functions of every frame size
// from near 0 up to and beyond the default segment size (4k).
// Each of those functions reports its SP + stack limit, and then
// the test (the caller) checks that those make sense.  By not
// doing the actual checking and reporting from the suspect functions,
// we minimize the possibility of crashes during the test itself.
//
// Exhaustive test for http://golang.org/issue/3310.
// The linker used to get a few sizes near the segment size wrong:
//
// --- FAIL: TestStackSplit (0.01 seconds)
// 	stack_test.go:22: after runtime_test.stack3812: sp=0x7f7818d5d078 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3816: sp=0x7f7818d5d078 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3820: sp=0x7f7818d5d070 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3824: sp=0x7f7818d5d070 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3828: sp=0x7f7818d5d068 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3832: sp=0x7f7818d5d068 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3836: sp=0x7f7818d5d060 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3840: sp=0x7f7818d5d060 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3844: sp=0x7f7818d5d058 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3848: sp=0x7f7818d5d058 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3852: sp=0x7f7818d5d050 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3856: sp=0x7f7818d5d050 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3860: sp=0x7f7818d5d048 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3864: sp=0x7f7818d5d048 < limit=0x7f7818d5d080
// FAIL
func TestStackSplit(t *testing.T) {
	for _, f := range splitTests {
		sp, guard := f()
		bottom := guard - StackGuard
		if sp < bottom+StackLimit {
			fun := FuncForPC(**(**uintptr)(unsafe.Pointer(&f)))
			t.Errorf("after %s: sp=%#x < limit=%#x (guard=%#x, bottom=%#x)",
				fun.Name(), sp, bottom+StackLimit, guard, bottom)
		}
	}
}

var Used byte

func use(buf []byte) {
	for _, c := range buf {
		Used += c
	}
}

// TestStackMem measures per-thread stack segment cache behavior.
// The test consumed up to 500MB in the past.
func TestStackMem(t *testing.T) {
	const (
		BatchSize      = 32
		BatchCount     = 256
		ArraySize      = 1024
		RecursionDepth = 128
	)
	if testing.Short() {
		return
	}
	defer GOMAXPROCS(GOMAXPROCS(BatchSize))
	s0 := new(MemStats)
	ReadMemStats(s0)
	for b := 0; b < BatchCount; b++ {
		c := make(chan bool, BatchSize)
		for i := 0; i < BatchSize; i++ {
			go func() {
				var f func(k int, a [ArraySize]byte)
				f = func(k int, a [ArraySize]byte) {
					if k == 0 {
						time.Sleep(time.Millisecond)
						return
					}
					f(k-1, a)
				}
				f(RecursionDepth, [ArraySize]byte{})
				c <- true
			}()
		}
		for i := 0; i < BatchSize; i++ {
			<-c
		}

		// The goroutines have signaled via c that they are ready to exit.
		// Give them a chance to exit by sleeping. If we don't wait, we
		// might not reuse them on the next batch.
		time.Sleep(10 * time.Millisecond)
	}
	s1 := new(MemStats)
	ReadMemStats(s1)
	consumed := s1.StackSys - s0.StackSys
	t.Logf("Consumed %vMB for stack mem", consumed>>20)
	estimate := uint64(8 * BatchSize * ArraySize * RecursionDepth) // 8 is to reduce flakiness.
	if consumed > estimate {
		t.Fatalf("Stack mem: want %v, got %v", estimate, consumed)
	}
	// Due to broken stack memory accounting (http://golang.org/issue/7468),
	// StackInuse can decrease during function execution, so we cast the values to int64.
	inuse := int64(s1.StackInuse) - int64(s0.StackInuse)
	t.Logf("Inuse %vMB for stack mem", inuse>>20)
	if inuse > 4<<20 {
		t.Fatalf("Stack inuse: want %v, got %v", 4<<20, inuse)
	}
}

// Test stack growing in different contexts.
func TestStackGrowth(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode")
	}
	t.Parallel()
	var wg sync.WaitGroup

	// in a normal goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		growStack()
	}()

	// in locked goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		LockOSThread()
		growStack()
		UnlockOSThread()
	}()

	// in finalizer
	wg.Add(1)
	go func() {
		defer wg.Done()
		done := make(chan bool)
		go func() {
			s := new(string)
			SetFinalizer(s, func(ss *string) {
				done <- true
			})
			s = nil
			done <- true
		}()
		<-done
		GC()
		select {
		case <-done:
		case <-time.After(4 * time.Second):
			t.Fatal("finalizer did not run")
		}
	}()

	wg.Wait()
}

// ... and in init
func init() {
	growStack()
}

func growStack() {
	for i := 0; i < 1<<10; i++ {
		x := 0
		growStackIter(&x, i)
		if x != i+1 {
			panic("stack is corrupted")
		}
	}
	GC()
}

// This function is not an anonimous func, so that the compiler can do escape
// analysis and place x on stack (and subsequently stack growth update the pointer).
func growStackIter(p *int, n int) {
	if n == 0 {
		*p = n + 1
		GC()
		return
	}
	*p = n + 1
	x := 0
	growStackIter(&x, n-1)
	if x != n {
		panic("stack is corrupted")
	}
}

func TestStackGrowthCallback(t *testing.T) {
	t.Parallel()
	var wg sync.WaitGroup

	// test stack growth at chan op
	wg.Add(1)
	go func() {
		defer wg.Done()
		c := make(chan int, 1)
		growStackWithCallback(func() {
			c <- 1
			<-c
		})
	}()

	// test stack growth at map op
	wg.Add(1)
	go func() {
		defer wg.Done()
		m := make(map[int]int)
		growStackWithCallback(func() {
			_, _ = m[1]
			m[1] = 1
		})
	}()

	// test stack growth at goroutine creation
	wg.Add(1)
	go func() {
		defer wg.Done()
		growStackWithCallback(func() {
			done := make(chan bool)
			go func() {
				done <- true
			}()
			<-done
		})
	}()

	wg.Wait()
}

func growStackWithCallback(cb func()) {
	var f func(n int)
	f = func(n int) {
		if n == 0 {
			cb()
			return
		}
		f(n - 1)
	}
	for i := 0; i < 1<<10; i++ {
		f(i)
	}
}

// TestDeferPtrs tests the adjustment of Defer's argument pointers (p aka &y)
// during a stack copy.
func set(p *int, x int) {
	*p = x
}
func TestDeferPtrs(t *testing.T) {
	var y int

	defer func() {
		if y != 42 {
			t.Errorf("defer's stack references were not adjusted appropriately")
		}
	}()
	defer set(&y, 42)
	growStack()
}
<commit_msg>runtime: no longer skip stack growth test in short mode<commit_after>// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime_test

import (
	. "runtime"
	"sync"
	"testing"
	"time"
	"unsafe"
)

// See stack.h.
const (
	StackGuard = 256
	StackLimit = 128
)

// Test stack split logic by calling functions of every frame size
// from near 0 up to and beyond the default segment size (4k).
// Each of those functions reports its SP + stack limit, and then
// the test (the caller) checks that those make sense.  By not
// doing the actual checking and reporting from the suspect functions,
// we minimize the possibility of crashes during the test itself.
//
// Exhaustive test for http://golang.org/issue/3310.
// The linker used to get a few sizes near the segment size wrong:
//
// --- FAIL: TestStackSplit (0.01 seconds)
// 	stack_test.go:22: after runtime_test.stack3812: sp=0x7f7818d5d078 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3816: sp=0x7f7818d5d078 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3820: sp=0x7f7818d5d070 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3824: sp=0x7f7818d5d070 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3828: sp=0x7f7818d5d068 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3832: sp=0x7f7818d5d068 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3836: sp=0x7f7818d5d060 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3840: sp=0x7f7818d5d060 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3844: sp=0x7f7818d5d058 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3848: sp=0x7f7818d5d058 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3852: sp=0x7f7818d5d050 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3856: sp=0x7f7818d5d050 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3860: sp=0x7f7818d5d048 < limit=0x7f7818d5d080
// 	stack_test.go:22: after runtime_test.stack3864: sp=0x7f7818d5d048 < limit=0x7f7818d5d080
// FAIL
func TestStackSplit(t *testing.T) {
	for _, f := range splitTests {
		sp, guard := f()
		bottom := guard - StackGuard
		if sp < bottom+StackLimit {
			fun := FuncForPC(**(**uintptr)(unsafe.Pointer(&f)))
			t.Errorf("after %s: sp=%#x < limit=%#x (guard=%#x, bottom=%#x)",
				fun.Name(), sp, bottom+StackLimit, guard, bottom)
		}
	}
}

var Used byte

func use(buf []byte) {
	for _, c := range buf {
		Used += c
	}
}

// TestStackMem measures per-thread stack segment cache behavior.
// The test consumed up to 500MB in the past.
func TestStackMem(t *testing.T) {
	const (
		BatchSize      = 32
		BatchCount     = 256
		ArraySize      = 1024
		RecursionDepth = 128
	)
	if testing.Short() {
		return
	}
	defer GOMAXPROCS(GOMAXPROCS(BatchSize))
	s0 := new(MemStats)
	ReadMemStats(s0)
	for b := 0; b < BatchCount; b++ {
		c := make(chan bool, BatchSize)
		for i := 0; i < BatchSize; i++ {
			go func() {
				var f func(k int, a [ArraySize]byte)
				f = func(k int, a [ArraySize]byte) {
					if k == 0 {
						time.Sleep(time.Millisecond)
						return
					}
					f(k-1, a)
				}
				f(RecursionDepth, [ArraySize]byte{})
				c <- true
			}()
		}
		for i := 0; i < BatchSize; i++ {
			<-c
		}

		// The goroutines have signaled via c that they are ready to exit.
		// Give them a chance to exit by sleeping. If we don't wait, we
		// might not reuse them on the next batch.
		time.Sleep(10 * time.Millisecond)
	}
	s1 := new(MemStats)
	ReadMemStats(s1)
	consumed := s1.StackSys - s0.StackSys
	t.Logf("Consumed %vMB for stack mem", consumed>>20)
	estimate := uint64(8 * BatchSize * ArraySize * RecursionDepth) // 8 is to reduce flakiness.
	if consumed > estimate {
		t.Fatalf("Stack mem: want %v, got %v", estimate, consumed)
	}
	// Due to broken stack memory accounting (http://golang.org/issue/7468),
	// StackInuse can decrease during function execution, so we cast the values to int64.
	inuse := int64(s1.StackInuse) - int64(s0.StackInuse)
	t.Logf("Inuse %vMB for stack mem", inuse>>20)
	if inuse > 4<<20 {
		t.Fatalf("Stack inuse: want %v, got %v", 4<<20, inuse)
	}
}

// Test stack growing in different contexts.
func TestStackGrowth(t *testing.T) {
	t.Parallel()
	var wg sync.WaitGroup

	// in a normal goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		growStack()
	}()

	// in locked goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		LockOSThread()
		growStack()
		UnlockOSThread()
	}()

	// in finalizer
	wg.Add(1)
	go func() {
		defer wg.Done()
		done := make(chan bool)
		go func() {
			s := new(string)
			SetFinalizer(s, func(ss *string) {
				done <- true
			})
			s = nil
			done <- true
		}()
		<-done
		GC()
		select {
		case <-done:
		case <-time.After(4 * time.Second):
			t.Fatal("finalizer did not run")
		}
	}()

	wg.Wait()
}

// ... and in init
func init() {
	growStack()
}

func growStack() {
	for i := 0; i < 1<<10; i++ {
		x := 0
		growStackIter(&x, i)
		if x != i+1 {
			panic("stack is corrupted")
		}
	}
	GC()
}

// This function is not an anonimous func, so that the compiler can do escape
// analysis and place x on stack (and subsequently stack growth update the pointer).
func growStackIter(p *int, n int) {
	if n == 0 {
		*p = n + 1
		GC()
		return
	}
	*p = n + 1
	x := 0
	growStackIter(&x, n-1)
	if x != n {
		panic("stack is corrupted")
	}
}

func TestStackGrowthCallback(t *testing.T) {
	t.Parallel()
	var wg sync.WaitGroup

	// test stack growth at chan op
	wg.Add(1)
	go func() {
		defer wg.Done()
		c := make(chan int, 1)
		growStackWithCallback(func() {
			c <- 1
			<-c
		})
	}()

	// test stack growth at map op
	wg.Add(1)
	go func() {
		defer wg.Done()
		m := make(map[int]int)
		growStackWithCallback(func() {
			_, _ = m[1]
			m[1] = 1
		})
	}()

	// test stack growth at goroutine creation
	wg.Add(1)
	go func() {
		defer wg.Done()
		growStackWithCallback(func() {
			done := make(chan bool)
			go func() {
				done <- true
			}()
			<-done
		})
	}()

	wg.Wait()
}

func growStackWithCallback(cb func()) {
	var f func(n int)
	f = func(n int) {
		if n == 0 {
			cb()
			return
		}
		f(n - 1)
	}
	for i := 0; i < 1<<10; i++ {
		f(i)
	}
}

// TestDeferPtrs tests the adjustment of Defer's argument pointers (p aka &y)
// during a stack copy.
func set(p *int, x int) {
	*p = x
}
func TestDeferPtrs(t *testing.T) {
	var y int

	defer func() {
		if y != 42 {
			t.Errorf("defer's stack references were not adjusted appropriately")
		}
	}()
	defer set(&y, 42)
	growStack()
}
<|endoftext|>


<commit_before>package testutils

import "testing"

func CheckString(exp, obs string, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %s but got %s", exp, obs)
	}
}

func CheckInt(exp, obs int, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

func CheckInt64(exp, obs int64, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

func CheckUint(exp, obs uint, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

func CheckUint64(exp, obs uint64, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

func ExpectTrue(obs bool, message string, t *testing.T) {
	if !obs {
		t.Errorf("Expected true but got false: %s", message)
	}
}

func ExpectFalse(obs bool, message string, t *testing.T) {
	if obs {
		t.Errorf("Expected false but got true: %s", message)
	}
}

func ExpectNil(obs interface{}, message string, t *testing.T) {
	if obs != nil {
		t.Errorf("Expected nil but got: %v. (%s)", obs, message)
	}
}

func CheckErr(err error, t *testing.T) {
	if err != nil {
		t.Error(err.Error())
	}
}

func CheckSlice(exp, obs []int, t *testing.T) {
	if len(exp) != len(obs) {
		t.Errorf("Differing slice lengths: %d vs %d", len(exp), len(obs))
	}
	for i, v := range exp {
		if v != obs[i] {
			t.Errorf("Slices differ in element number %d: %d vs %d", i, v, obs[i])
		}
	}
	t.Logf("Expected: %v\nActual: %v", exp, obs)
}

func CheckByteSlice(exp, obs []byte, t *testing.T) {
	if len(exp) != len(obs) {
		t.Errorf("Differing slice lengths: %d vs %d", len(exp), len(obs))
	}
	for i, v := range exp {
		if v != obs[i] {
			t.Errorf("Slices differ in element number %d: %d vs %d", i, v, obs[i])
		}
	}
	t.Logf("Expected: %v\nActual: %v", exp, obs)
}

func CheckStringSlice(exp, obs []string, t *testing.T) {
	if len(exp) != len(obs) {
		t.Errorf("Differing slice lengths: %d vs %d", len(exp), len(obs))
	}
	for i, v := range exp {
		if v != obs[i] {
			t.Errorf("Slices differ in element number %d: %v vs %v", i, v, obs[i])
		}
	}
	t.Logf("Expected: %v\nActual: %v", exp, obs)
}
<commit_msg>added doc comments for testutils<commit_after>package testutils

import "testing"

// CheckString ensures the given strings are equal
func CheckString(exp, obs string, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %s but got %s", exp, obs)
	}
}

// CheckInt ensures the given ints are equal
func CheckInt(exp, obs int, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

// CheckInt64 ensures the given int64s are equal
func CheckInt64(exp, obs int64, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

// CheckUint ensures the given uints are equal
func CheckUint(exp, obs uint, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

// CheckUint64 ensures the given uint64s are equal
func CheckUint64(exp, obs uint64, t *testing.T) {
	if exp != obs {
		t.Errorf("Expected %v but got %v", exp, obs)
	}
}

// ExpectTrue ensures the given resolved expression is true
func ExpectTrue(obs bool, message string, t *testing.T) {
	if !obs {
		t.Errorf("Expected true but got false: %s", message)
	}
}

// ExpectFalse ensures the given resolved expresion is false
func ExpectFalse(obs bool, message string, t *testing.T) {
	if obs {
		t.Errorf("Expected false but got true: %s", message)
	}
}

// ExpectNil ensures the given expression is nil
func ExpectNil(obs interface{}, message string, t *testing.T) {
	if obs != nil {
		t.Errorf("Expected nil but got: %v. (%s)", obs, message)
	}
}

// CheckErr converts a runtime error into a testing error
func CheckErr(err error, t *testing.T) {
	if err != nil {
		t.Error(err.Error())
	}
}

// CheckSlice ensures that the two int slices are equal
func CheckSlice(exp, obs []int, t *testing.T) {
	if len(exp) != len(obs) {
		t.Errorf("Differing slice lengths: %d vs %d", len(exp), len(obs))
	}
	for i, v := range exp {
		if v != obs[i] {
			t.Errorf("Slices differ in element number %d: %d vs %d", i, v, obs[i])
		}
	}
	t.Logf("Expected: %v\nActual: %v", exp, obs)
}

// CheckByteSlice ensures that the two byte slices are equal
func CheckByteSlice(exp, obs []byte, t *testing.T) {
	if len(exp) != len(obs) {
		t.Errorf("Differing slice lengths: %d vs %d", len(exp), len(obs))
	}
	for i, v := range exp {
		if v != obs[i] {
			t.Errorf("Slices differ in element number %d: %d vs %d", i, v, obs[i])
		}
	}
	t.Logf("Expected: %v\nActual: %v", exp, obs)
}

// CheckStringSlice ensures that the two string slices are equal
func CheckStringSlice(exp, obs []string, t *testing.T) {
	if len(exp) != len(obs) {
		t.Errorf("Differing slice lengths: %d vs %d", len(exp), len(obs))
	}
	for i, v := range exp {
		if v != obs[i] {
			t.Errorf("Slices differ in element number %d: %v vs %v", i, v, obs[i])
		}
	}
	t.Logf("Expected: %v\nActual: %v", exp, obs)
}
<|endoftext|>


<commit_before>package apply2

import (
	"encoding/gob"
	"os"
	"path"

	"github.com/dchest/safefile"
	"github.com/itchio/butler/comm"
	"github.com/itchio/butler/mansion"
	"github.com/itchio/savior/seeksource"
	"github.com/itchio/wharf/eos"
	"github.com/itchio/wharf/eos/option"
	"github.com/itchio/wharf/pools/fspool"
	"github.com/itchio/wharf/pwr/bowl"
	"github.com/itchio/wharf/pwr/patcher"
	"github.com/itchio/wharf/state"
	"github.com/pkg/errors"
)

var args = struct {
	patch *string
	dir   *string
	old   *string
}{}

func Register(ctx *mansion.Context) {
	cmd := ctx.App.Command("apply2", "(Advanced) Use a patch to resumably patch a directory to a new version")
	args.patch = cmd.Arg("patch", "Patch file (.pwr), previously generated with the `diff` command.").Required().String()
	args.old = cmd.Arg("old", "Directory with old files").Required().String()
	args.dir = cmd.Flag("dir", "Directory for patched files and checkpoints").Short('d').Required().String()
	ctx.Register(cmd, do)
}

func do(ctx *mansion.Context) {
	ctx.Must(Do(&Params{
		Patch: *args.patch,
		Old:   *args.old,
		Dir:   *args.dir,
	}))
}

type Params struct {
	Patch string
	Old   string
	Dir   string
}

func Do(params *Params) error {
	patch := params.Patch
	old := params.Old
	dir := params.Dir

	consumer := &state.Consumer{
		OnMessage: func(level string, message string) {
			comm.Logf("[%s] %s", level, message)
		},
	}

	patchReader, err := eos.Open(patch, option.WithConsumer(comm.NewStateConsumer()))
	if err != nil {
		return errors.Wrap(err, "opening patch")
	}

	patchSource := seeksource.FromFile(patchReader)
	_, err = patchSource.Resume(nil)
	if err != nil {
		return errors.Wrap(err, "creating patch source")
	}

	p, err := patcher.New(patchSource, consumer)
	if err != nil {
		return errors.Wrap(err, "creating patcher")
	}

	// comm.StartProgressWithTotalBytes(patchSource.Size())

	var checkpoint *patcher.Checkpoint
	checkpointPath := path.Join(dir, "checkpoint.bwl")

	checkpointFile, err := os.Open(checkpointPath)
	if err != nil {
		if !os.IsNotExist(err) {
			return errors.Wrap(err, "opening checkpoint")
		}
	} else {
		defer checkpointFile.Close()

		checkpoint = &patcher.Checkpoint{}

		dec := gob.NewDecoder(checkpointFile)
		err := dec.Decode(checkpoint)
		if err != nil {
			return errors.Wrap(err, "decoding checkpoint")
		}

		// yay, we have a checkpoint!
	}

	p.SetSaveConsumer(&patcherSaveConsumer{
		shouldSave: func() bool {
			// TODO: patcher checkpoints are big. how often do we actually wanna do this?
			return true
		},
		save: func(c *patcher.Checkpoint) (patcher.AfterSaveAction, error) {
			checkpointFile, err := safefile.Create(checkpointPath, 0644)
			if err != nil {
				return patcher.AfterSaveStop, errors.Wrap(err, "creating checkpoint file")
			}
			defer checkpointFile.Close()

			enc := gob.NewEncoder(checkpointFile)
			err = enc.Encode(c)
			if err != nil {
				return patcher.AfterSaveStop, errors.Wrap(err, "encoding checkpoint")
			}

			err = checkpointFile.Commit()
			if err != nil {
				return patcher.AfterSaveStop, errors.Wrap(err, "committing checkpoint file")
			}

			return patcher.AfterSaveContinue, nil
		},
	})

	targetPool := fspool.New(p.GetTargetContainer(), old)

	bowl, err := bowl.NewFreshBowl(&bowl.FreshBowlParams{
		SourceContainer: p.GetSourceContainer(),
		TargetContainer: p.GetTargetContainer(),
		TargetPool:      targetPool,
		OutputFolder:    dir,
	})
	if err != nil {
		return errors.Wrap(err, "creating fresh bowl")
	}

	err = p.Resume(checkpoint, targetPool, bowl)
	if err != nil {
		return errors.Wrap(err, "patching")
	}
	comm.EndProgress()

	return nil
}

type patcherSaveConsumer struct {
	shouldSave func() bool
	save       func(checkpoint *patcher.Checkpoint) (patcher.AfterSaveAction, error)
}

var _ patcher.SaveConsumer = (*patcherSaveConsumer)(nil)

func (psc *patcherSaveConsumer) ShouldSave() bool {
	return psc.shouldSave()
}

func (psc *patcherSaveConsumer) Save(checkpoint *patcher.Checkpoint) (patcher.AfterSaveAction, error) {
	return psc.save(checkpoint)
}
<commit_msg>apply2 --stop-early flag<commit_after>package apply2

import (
	"encoding/gob"
	"log"
	"os"
	"path"
	"time"

	"github.com/dchest/safefile"
	"github.com/itchio/butler/comm"
	"github.com/itchio/butler/mansion"
	"github.com/itchio/savior/seeksource"
	"github.com/itchio/wharf/eos"
	"github.com/itchio/wharf/eos/option"
	"github.com/itchio/wharf/pools/fspool"
	"github.com/itchio/wharf/pwr/bowl"
	"github.com/itchio/wharf/pwr/patcher"
	"github.com/itchio/wharf/state"
	"github.com/pkg/errors"
)

var args = struct {
	patch     *string
	dir       *string
	old       *string
	stopEarly *bool
}{}

func Register(ctx *mansion.Context) {
	cmd := ctx.App.Command("apply2", "(Advanced) Use a patch to resumably patch a directory to a new version")
	args.patch = cmd.Arg("patch", "Patch file (.pwr), previously generated with the `diff` command.").Required().String()
	args.old = cmd.Arg("old", "Directory with old files").Required().String()
	args.dir = cmd.Flag("dir", "Directory for patched files and checkpoints").Short('d').Required().String()
	args.stopEarly = cmd.Flag("stop-early", "Stop after emitting checkpoint").Bool()
	ctx.Register(cmd, do)
}

func do(ctx *mansion.Context) {
	ctx.Must(Do(&Params{
		Patch:     *args.patch,
		Old:       *args.old,
		Dir:       *args.dir,
		StopEarly: *args.stopEarly,
	}))
}

type Params struct {
	Patch     string
	Old       string
	Dir       string
	StopEarly bool
}

func Do(params *Params) error {
	patch := params.Patch
	old := params.Old
	dir := params.Dir

	consumer := &state.Consumer{
		OnMessage: func(level string, message string) {
			comm.Logf("[%s] %s", level, message)
		},
	}

	patchReader, err := eos.Open(patch, option.WithConsumer(comm.NewStateConsumer()))
	if err != nil {
		return errors.Wrap(err, "opening patch")
	}

	patchSource := seeksource.FromFile(patchReader)
	_, err = patchSource.Resume(nil)
	if err != nil {
		return errors.Wrap(err, "creating patch source")
	}

	p, err := patcher.New(patchSource, consumer)
	if err != nil {
		return errors.Wrap(err, "creating patcher")
	}

	// comm.StartProgressWithTotalBytes(patchSource.Size())

	var checkpoint *patcher.Checkpoint
	checkpointPath := path.Join(dir, "checkpoint.bwl")

	checkpointFile, err := os.Open(checkpointPath)
	if err != nil {
		if !os.IsNotExist(err) {
			return errors.Wrap(err, "opening checkpoint")
		}
	} else {
		defer checkpointFile.Close()

		checkpoint = &patcher.Checkpoint{}

		dec := gob.NewDecoder(checkpointFile)
		err := dec.Decode(checkpoint)
		if err != nil {
			return errors.Wrap(err, "decoding checkpoint")
		}

		// yay, we have a checkpoint!
	}

	lastSaveTime := time.Now()
	saveInterval := 2 * time.Second

	p.SetSaveConsumer(&patcherSaveConsumer{
		shouldSave: func() bool {
			return time.Since(lastSaveTime) > saveInterval
		},
		save: func(c *patcher.Checkpoint) (patcher.AfterSaveAction, error) {
			log.Printf("Saving checkpoint")
			lastSaveTime = time.Now()

			checkpointFile, err := safefile.Create(checkpointPath, 0644)
			if err != nil {
				return patcher.AfterSaveStop, errors.Wrap(err, "creating checkpoint file")
			}
			defer checkpointFile.Close()

			enc := gob.NewEncoder(checkpointFile)
			err = enc.Encode(c)
			if err != nil {
				return patcher.AfterSaveStop, errors.Wrap(err, "encoding checkpoint")
			}

			err = checkpointFile.Commit()
			if err != nil {
				return patcher.AfterSaveStop, errors.Wrap(err, "committing checkpoint file")
			}

			if params.StopEarly {
				return patcher.AfterSaveStop, nil
			}
			return patcher.AfterSaveContinue, nil
		},
	})

	targetPool := fspool.New(p.GetTargetContainer(), old)

	bowl, err := bowl.NewFreshBowl(&bowl.FreshBowlParams{
		SourceContainer: p.GetSourceContainer(),
		TargetContainer: p.GetTargetContainer(),
		TargetPool:      targetPool,
		OutputFolder:    dir,
	})
	if err != nil {
		return errors.Wrap(err, "creating fresh bowl")
	}

	err = p.Resume(checkpoint, targetPool, bowl)
	if err != nil {
		if errors.Cause(err) == patcher.ErrStop {
			comm.EndProgress()
			comm.Statf("Stopped early!")
			return nil
		}
		return errors.Wrap(err, "patching")
	}
	comm.EndProgress()

	return nil
}

type patcherSaveConsumer struct {
	shouldSave func() bool
	save       func(checkpoint *patcher.Checkpoint) (patcher.AfterSaveAction, error)
}

var _ patcher.SaveConsumer = (*patcherSaveConsumer)(nil)

func (psc *patcherSaveConsumer) ShouldSave() bool {
	return psc.shouldSave()
}

func (psc *patcherSaveConsumer) Save(checkpoint *patcher.Checkpoint) (patcher.AfterSaveAction, error) {
	return psc.save(checkpoint)
}
<|endoftext|>