<commit_before>// Position weight matrix search
//
// based on algorithm by Deborah Toledo Flores
package pwm

// Copyright ©2011 Dan Kortschak <dan.kortschak@adelaide.edu.au>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

import (
	"github.com/kortschak/biogo/bio"
	"github.com/kortschak/biogo/feat"
	"github.com/kortschak/biogo/seq"
	"github.com/kortschak/biogo/util"
	"math"
	"sort"
	"strconv"
)

var (
	valid  [256]bool
	LookUp util.CTL
)

func init() {
	m := make(map[int]int)

	for i, v := range bio.N {
		m[int(v)] = i % 4
	}

	LookUp = *util.NewCTL(m)

	Valid(bio.N)
}

func Valid(alphabet []byte) {
	for i := range valid {
		valid[i] = false
	}
	for _, v := range alphabet {
		valid[v] = true
	}
}

type probs struct {
	score      float64
	freqs      []int
	occurrence int
}

type probTable []*probs

func (self probTable) Len() int { return len(self) }

func (self probTable) Less(i, j int) bool { return self[i].score > self[j].score }

func (self *probTable) Swap(i, j int) { (*self)[i], (*self)[j] = (*self)[j], (*self)[i] }

type PWM struct {
	matrix      [][]float64
	lookAhead   []float64
	table       probTable
	minScore    float64
	FloatFormat byte
	Precision   int
}

func New(matrix [][]float64) (m *PWM) { // try this and also matrix []map[byte]float64 for speed comparison
	m = &PWM{
		matrix:      matrix,
		lookAhead:   make([]float64, len(matrix)),
		minScore:    math.MaxFloat64,
		FloatFormat: bio.FloatFormat,
		Precision:   bio.Precision,
	}

	var maxVal, maxScore float64

	for i := len(matrix) - 1; i >= 0; i-- {
		maxVal = 0
		for _, v := range matrix[i] {
			if v > maxVal {
				maxVal = v
			}
		}
		maxScore += maxVal
		m.lookAhead[i] = maxScore
	}

	for i := range matrix {
		for j := range matrix[i] {
			matrix[i][j] /= maxScore
		}
		m.lookAhead[i] /= maxScore
	}

	return
}

func (self *PWM) genTable(minScore, score float64, position int, motif []byte) {
	for i, s := range self.matrix[position] {
		motif[position] = byte(i)
		if position < len(self.matrix)-1 {
			if minScore-(score+s) > self.lookAhead[position+1] { // will not be able to achieve minScore
				continue
			}
			self.genTable(minScore, score+s, position+1, motif)
		} else {
			if score+s < minScore { // will not be able to achieve minScore
				continue
			}
			// count frequencies of states in current motif
			freqs := make([]int, 4)
			for _, j := range motif {
				freqs[j]++
			}
			found := false
			for j := len(self.table) - 1; j >= 0; j-- {
				table := self.table[j]
				if table.score != score+s {
					continue // if using insertion sort, if table.score > score+s then we can found = false and break
				}
				match := true
				for k := range freqs {
					if freqs[k] != table.freqs[k] {
						match = false
						break
					}
				}
				if match {
					table.occurrence++
					found = true
					break
				}
			}

			if !found {
				self.table = append(self.table, &probs{score: score + s, freqs: freqs, occurrence: 1}) // use a insertion sort (based on score) ? will make search quicker
			}
		}
	}

}

func (self *PWM) Search(sequence *seq.Seq, start, end int, minScore float64) (scores []*feat.Feature) { // return this as an array of features
	if minScore < self.minScore {
		self.table = make(probTable, 0)
		self.genTable(minScore, 0, 0, make([]byte, len(self.matrix)))
		sort.Sort(&self.table)
		/*
			for _, e := range self.table {
				fmt.Printf("%f\t", e.score)
				for c, f := range e.freqs {
					if f > 0 {
						fmt.Printf("'%c':%d ", [4]byte{'A','C','G','T'}[c], f)
					}
				}
				fmt.Printf("%d\n", e.occurrence)
			}
		*/
	}

	length := len(self.matrix)

	freqs := make([]float64, 4)
	zeros := make([]float64, 4)

	diff := 1 / float64(length)
LOOP:
	for position := start; position+length < end; position++ {
		// determine the score for this position
		score := float64(0)
		for i := 0; i < length; i++ {
			if base := LookUp.ValueToCode[sequence.Seq[position+i]]; base < 0 || minScore-score > self.lookAhead[i] { // not valid base or will not be able to achieve minScore
				continue LOOP
			} else {
				score += self.matrix[i][base]
			}
		}

		if score < minScore {
			continue
		}

		// calculate base frequencies for window
		copy(freqs, zeros)
		for i := position; i < position+length; i++ {
			if base := LookUp.ValueToCode[sequence.Seq[i]]; base >= 0 {
				freqs[base] += diff
			} else { // probability for this position will be meaningless - if N is tolerated, include N in valid alphabet - make special case?
				continue LOOP
			}
		}

		// descend probability function summing probabilities
		prob := float64(0)
		sp := float64(0)
		for _, e := range self.table {
			sp = 1
			if e.score < score {
				break
			}
			for i, f := range freqs {
				sp *= math.Pow(f, float64(e.freqs[i]))
			}
			sp *= float64(e.occurrence)
			prob += sp
		}

		scores = append(scores, &feat.Feature{
			Location:   sequence.ID,
			Start:      position + 1,
			End:        position + length,
			Score:      score,
			Attributes: string(sequence.Seq[position:position+length]) + " " + strconv.FormatFloat(prob, self.FloatFormat, self.Precision, 64),
			Strand:     sequence.Strand,
			Moltype:    sequence.Moltype,
			Frame:      -1,
		})
	}

	return
}
<commit_msg>Regression from 9f066<commit_after>// Position weight matrix search
//
// based on algorithm by Deborah Toledo Flores
package pwm

// Copyright ©2011 Dan Kortschak <dan.kortschak@adelaide.edu.au>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

import (
	"github.com/kortschak/biogo/bio"
	"github.com/kortschak/biogo/feat"
	"github.com/kortschak/biogo/seq"
	"github.com/kortschak/biogo/util"
	"math"
	"sort"
	"strconv"
)

var (
	valid  [256]bool
	LookUp util.CTL
)

func init() {
	m := make(map[int]int)

	for i, v := range bio.N {
		m[int(v)] = i % 4
	}

	LookUp = *util.NewCTL(m)

	Valid(bio.N)
}

func Valid(alphabet []byte) {
	for i := range valid {
		valid[i] = false
	}
	for _, v := range alphabet {
		valid[v] = true
	}
}

type probs struct {
	score      float64
	freqs      []int
	occurrence int
}

type probTable []*probs

func (self probTable) Len() int { return len(self) }

func (self probTable) Less(i, j int) bool { return self[i].score > self[j].score }

func (self *probTable) Swap(i, j int) { (*self)[i], (*self)[j] = (*self)[j], (*self)[i] }

type PWM struct {
	matrix      [][]float64
	lookAhead   []float64
	table       probTable
	minScore    float64
	FloatFormat byte
	Precision   int
}

func New(matrix [][]float64) (m *PWM) { // try this and also matrix []map[byte]float64 for speed comparison
	m = &PWM{
		matrix:      matrix,
		lookAhead:   make([]float64, len(matrix)),
		minScore:    math.MaxFloat64,
		FloatFormat: bio.FloatFormat,
		Precision:   bio.Precision,
	}

	var maxVal, maxScore float64

	for i := len(matrix) - 1; i >= 0; i-- {
		maxVal = 0
		for _, v := range matrix[i] {
			if v > maxVal {
				maxVal = v
			}
		}
		maxScore += maxVal
		m.lookAhead[i] = maxScore
	}

	for i := range matrix {
		for j := range matrix[i] {
			matrix[i][j] /= maxScore
		}
		m.lookAhead[i] /= maxScore
	}

	return
}

func (self *PWM) genTable(minScore, score float64, position int, motif []byte) {
	for i, s := range self.matrix[position] {
		motif[position] = byte(i)
		if position < len(self.matrix)-1 {
			if minScore-(score+s) > self.lookAhead[position+1] { // will not be able to achieve minScore
				continue
			}
			self.genTable(minScore, score+s, position+1, motif)
		} else {
			if score+s < minScore { // will not be able to achieve minScore
				continue
			}
			// count frequencies of states in current motif
			freqs := make([]int, 4)
			for _, j := range motif {
				freqs[j]++
			}
			found := false
			for j := len(self.table) - 1; j >= 0; j-- {
				table := self.table[j]
				if table.score != score+s {
					continue // if using insertion sort, if table.score > score+s then we can found = false and break
				}
				match := true
				for k := range freqs {
					if freqs[k] != table.freqs[k] {
						match = false
						break
					}
				}
				if match {
					table.occurrence++
					found = true
					break
				}
			}

			if !found {
				self.table = append(self.table, &probs{score: score + s, freqs: freqs, occurrence: 1}) // use a insertion sort (based on score) ? will make search quicker
			}
		}
	}

}

func (self *PWM) Search(sequence *seq.Seq, start, end int, minScore float64) (scores []*feat.Feature) { // return this as an array of features
	if minScore < self.minScore {
		self.table = make(probTable, 0)
		self.genTable(minScore, 0, 0, make([]byte, len(self.matrix)))
		sort.Sort(&self.table)
		/*
			for _, e := range self.table {
				fmt.Printf("%f\t", e.score)
				for c, f := range e.freqs {
					if f > 0 {
						fmt.Printf("'%c':%d ", [4]byte{'A','C','G','T'}[c], f)
					}
				}
				fmt.Printf("%d\n", e.occurrence)
			}
		*/
	}

	length := len(self.matrix)

	freqs := make([]float64, 4)
	zeros := make([]float64, 4)

	diff := 1 / float64(length)
LOOP:
	for position := start; position+length < end; position++ {
		// determine the score for this position
		score := float64(0)
		for i := 0; i < length; i++ {
			if base := LookUp.ValueToCode[sequence.Seq[position+i]]; base < 0 || minScore-score > self.lookAhead[i] { // not valid base or will not be able to achieve minScore
				continue LOOP
			} else {
				score += self.matrix[i][base]
			}
		}

		if score < minScore {
			continue
		}

		// calculate base frequencies for window
		copy(freqs, zeros)
		for i := position; i < position+length; i++ {
			if base := LookUp.ValueToCode[sequence.Seq[i]]; base >= 0 {
				freqs[base] += diff
			} else { // probability for this position will be meaningless - if N is tolerated, include N in valid alphabet - make special case?
				continue LOOP
			}
		}

		// descend probability function summing probabilities
		prob := float64(0)
		sp := float64(0)
		for _, e := range self.table {
			sp = 1
			if e.score < score {
				break
			}
			for i, f := range freqs {
				sp *= math.Pow(f, float64(e.freqs[i]))
			}
			sp *= float64(e.occurrence)
			prob += sp
		}

		scores = append(scores, &feat.Feature{
			Location:   sequence.ID,
			Start:      position + 1,
			End:        position + length,
			Score:      &score,
			Attributes: string(sequence.Seq[position:position+length]) + " " + strconv.FormatFloat(prob, self.FloatFormat, self.Precision, 64),
			Strand:     sequence.Strand,
			Moltype:    sequence.Moltype,
			Frame:      -1,
		})
	}

	return
}
<|endoftext|>


<commit_before>package optimus

// Table is a representation of a table of data.
type Table interface {
	// Rows returns a channel that provides the Rows in the table.
	Rows() <-chan Row
	// Err returns the first non-EOF error that was encountered by the Table.
	Err() error
	// Stop signifies that a Table should stop sending Rows down its channel.
	// A Table is also responsible for calling Stop on any upstream Tables it knows about.
	// Stop should be idempotent. It's expected that Stop will never be called by a consumer of a
	// Table unless that consumer is also a Table. It can be used to Stop all upstream Tables in
	// the event of an error that needs to halt the pipeline.
	Stop()
}

// Row is a representation of a line of data in a Table.
type Row map[string]interface{}

// TransformFunc is a function that can be applied to a Table to transform it. It should receive the
// Rows from in and may send any number of Rows to out. It should not return until it has finished
// all work (received all the Rows it's going to receive, sent all the Rows it's going to send).
type TransformFunc func(in <-chan Row, out chan<- Row) error

// Transform returns a new Table that provides all the Rows of the input Table transformed with the TransformFunc.
func Transform(source Table, transform TransformFunc) Table {
	return newTransformedTable(source, transform)
}

type transformedTable struct {
	source  Table
	err     error
	rows    chan Row
	stopped bool
}

func (t transformedTable) Rows() <-chan Row {
	return t.rows
}

func (t transformedTable) Err() error {
	return t.err
}

func (t *transformedTable) Stop() {
	if t.stopped {
		return
	}
	t.stopped = true
	t.source.Stop()
}

func drain(c <-chan Row) {
	for _ = range c {
		// Drain everything left in the channel
	}
}

func (t *transformedTable) start(transform TransformFunc) {
	// A level of indirection is necessary between the i/o channels and the TransformFunc so that
	// the TransformFunc doesn't need to know about the stop state of any of the Tables.
	in := make(chan Row)
	out := make(chan Row)
	errChan := make(chan error)
	doneChan := make(chan struct{})

	stop := func() {
		if t.stopped {
			return
		}
		t.Stop()
		drain(t.source.Rows())
		drain(out)
		close(t.rows)
	}
	defer stop()

	go func() {
		defer close(errChan)
		defer close(out)
		if err := transform(in, out); err != nil {
			errChan <- err
		}
	}()
	go func() {
		defer func() {
			doneChan <- struct{}{}
		}()
		for row := range out {
			if t.stopped {
				continue
			}
			t.rows <- row
		}
	}()

	go func() {
		defer func() {
			doneChan <- struct{}{}
		}()
		defer close(in)
		for row := range t.source.Rows() {
			if t.stopped {
				continue
			}
			in <- row
		}
	}()
	for err := range errChan {
		stop()
		t.err = err
	}
	// Wait for all channels to finish
	<-doneChan // Once to make sure we've consumed the output of the TransformFunc
	<-doneChan // Once to make sure we've consumed the output of the source Table
	if t.source.Err() != nil {
		t.err = t.source.Err()
	}
}

func newTransformedTable(source Table, transform TransformFunc) Table {
	table := &transformedTable{
		source: source,
		rows:   make(chan Row),
	}
	go table.start(transform)
	return table
}
<commit_msg>explanatory comments<commit_after>package optimus

// Table is a representation of a table of data.
type Table interface {
	// Rows returns a channel that provides the Rows in the table.
	Rows() <-chan Row
	// Err returns the first non-EOF error that was encountered by the Table.
	Err() error
	// Stop signifies that a Table should stop sending Rows down its channel.
	// A Table is also responsible for calling Stop on any upstream Tables it knows about.
	// Stop should be idempotent. It's expected that Stop will never be called by a consumer of a
	// Table unless that consumer is also a Table. It can be used to Stop all upstream Tables in
	// the event of an error that needs to halt the pipeline.
	Stop()
}

// Row is a representation of a line of data in a Table.
type Row map[string]interface{}

// TransformFunc is a function that can be applied to a Table to transform it. It should receive the
// Rows from in and may send any number of Rows to out. It should not return until it has finished
// all work (received all the Rows it's going to receive, sent all the Rows it's going to send).
type TransformFunc func(in <-chan Row, out chan<- Row) error

// Transform returns a new Table that provides all the Rows of the input Table transformed with the TransformFunc.
func Transform(source Table, transform TransformFunc) Table {
	return newTransformedTable(source, transform)
}

type transformedTable struct {
	source  Table
	err     error
	rows    chan Row
	stopped bool
}

func (t transformedTable) Rows() <-chan Row {
	return t.rows
}

func (t transformedTable) Err() error {
	return t.err
}

func (t *transformedTable) Stop() {
	if t.stopped {
		return
	}
	t.stopped = true
	t.source.Stop()
}

func drain(c <-chan Row) {
	for _ = range c {
		// Drain everything left in the channel
	}
}

func (t *transformedTable) start(transform TransformFunc) {
	// A level of indirection is necessary between the i/o channels and the TransformFunc so that
	// the TransformFunc doesn't need to know about the stop state of any of the Tables.
	in := make(chan Row)
	out := make(chan Row)
	errChan := make(chan error)
	doneChan := make(chan struct{})

	stop := func() {
		if t.stopped {
			return
		}
		t.Stop()
		drain(t.source.Rows())
		drain(out)
		close(t.rows)
	}
	defer stop()

	// Once the transform function has returned, close out and error channels
	go func() {
		defer close(errChan)
		defer close(out)
		if err := transform(in, out); err != nil {
			errChan <- err
		}
	}()
	// Copy from the TransformFunc's out channel to the Table's out channel, then signal done
	go func() {
		defer func() {
			doneChan <- struct{}{}
		}()
		for row := range out {
			if t.stopped {
				continue
			}
			t.rows <- row
		}
	}()

	// Copy from the Table's source to the TransformFunc's in channel, then signal done
	go func() {
		defer func() {
			doneChan <- struct{}{}
		}()
		defer close(in)
		for row := range t.source.Rows() {
			if t.stopped {
				continue
			}
			in <- row
		}
	}()
	for err := range errChan {
		stop()
		t.err = err
	}
	// Wait for all channels to finish
	<-doneChan // Once to make sure we've consumed the output of the TransformFunc
	<-doneChan // Once to make sure we've consumed the output of the source Table
	if t.source.Err() != nil {
		t.err = t.source.Err()
	}
}

func newTransformedTable(source Table, transform TransformFunc) Table {
	table := &transformedTable{
		source: source,
		rows:   make(chan Row),
	}
	go table.start(transform)
	return table
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/thomaso-mirodin/go-shorten/storage"
)

type Options struct {
	BindHost string `long:"host"    default:"0.0.0.0"   env:"HOST"`
	BindPort string `long:"port"    default:"8080"      env:"PORT"`

	StorageType string `long:"storage-type" default:"Inmem" ini-name:"storage_type" env:"STORAGE_TYPE"`
	// StorageConfig string `long:"storage-config" ini-name:"storage_config"`

	// S3 Config options
	S3 struct {
		BucketName string `long:"s3-bucket" default:"go-shorten"    env:"S3_BUCKET"`
	} `group:"S3 Storage Options"`

	// Inmem Config options
	Inmem struct {
		RandLength int `long:"inmem-length" default:"8" env:"INMEM_LENGTH"`
	} `group:"Inmem Storage Options"`

	// Filesystem Config options
	Filesystem struct {
		RootPath string `long:"root-path" default:"./url-storage" env:"ROOT_PATH"`
	} `group:"Filesystem Storage Options"`

	Regex struct {
		Remaps map[string]string `long:"regex-remap" env:"REGEX_REMAP"`
	} `group:"Regex Storage Options"`
}

// createStorageFromOption takes an Option struct and based on the StorageType field constructs a storage.Storage and returns it.
func createStorageFromOption(opts *Options) (storage.Storage, error) {
	switch opts.StorageType {
	case "Inmem":
		log.Printf("Setting up an Inmem Storage layer with short code length of '%d'", opts.Inmem.RandLength)

		return storage.NewInmem(opts.Inmem.RandLength)
	case "S3":
		log.Println("Setting up an S3 Storage layer")

		if len(opts.S3.BucketName) == 0 {
			log.Fatalf("BucketName has be something (currently has zero length)")
		}

		return storage.NewS3(nil, opts.S3.BucketName)
	case "Filesystem":
		log.Println("Setting up a Filesystem storage layer with root: %v", opts.Filesystem.RootPath)

		return storage.NewFilesystem(opts.Filesystem.RootPath)
	case "Regex":
		log.Printf("Setting up a Regex storage with %v remaps", opts.Regex.Remaps)

		return storage.NewRegexFromList(opts.Regex.Remaps)
	default:
		validTypes := make([]string, len(storage.SupportedStorageTypes))

		i := 0
		for k := range storage.SupportedStorageTypes {
			validTypes[i] = k
			i++
		}

		return nil, fmt.Errorf("Unsupported storage-type: '%s', valid ones are: '%v'", opts.StorageType, strings.Join(validTypes, "', '"))
	}
}
<commit_msg>Add ReadOnly Multistorage to options<commit_after>package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/google/shlex"
	flags "github.com/jessevdk/go-flags"
	"github.com/pkg/errors"
	"github.com/thomaso-mirodin/go-shorten/storage"
	"github.com/thomaso-mirodin/go-shorten/storage/multistorage"
)

type Options struct {
	BindHost string `long:"host"    default:"0.0.0.0"   env:"HOST"`
	BindPort string `long:"port"    default:"8080"      env:"PORT"`

	StorageType string `long:"storage-type" default:"Inmem" ini-name:"storage_type" env:"STORAGE_TYPE"`
	// StorageConfig string `long:"storage-config" ini-name:"storage_config"`

	// S3 Config options
	S3 struct {
		BucketName string `long:"s3-bucket" default:"go-shorten"    env:"S3_BUCKET"`
	} `group:"S3 Storage Options"`

	// Inmem Config options
	Inmem struct {
		RandLength int `long:"inmem-length" default:"8" env:"INMEM_LENGTH"`
	} `group:"Inmem Storage Options"`

	// Filesystem Config options
	Filesystem struct {
		RootPath string `long:"root-path" default:"./url-storage" env:"ROOT_PATH"`
	} `group:"Filesystem Storage Options"`

	Regex struct {
		Remaps map[string]string `long:"regex-remap" env:"REGEX_REMAP"`
	} `group:"Regex Storage Options"`

	Multistorage struct {
		StorageArgs []string `long:"multi-sub-args" env:"MULTI_SUB_ARGS"`
	} `group:"Multi Storage Options"`
}

// createStorageFromOption takes an Option struct and based on the StorageType field constructs a storage.Storage and returns it.
func createStorageFromOption(opts *Options) (storage.Storage, error) {
	switch opts.StorageType {
	case "Inmem":
		log.Printf("Setting up an Inmem Storage layer with short code length of '%d'", opts.Inmem.RandLength)

		return storage.NewInmem(opts.Inmem.RandLength)
	case "S3":
		log.Println("Setting up an S3 Storage layer")

		if len(opts.S3.BucketName) == 0 {
			log.Fatalf("BucketName has be something (currently empty)")
		}

		return storage.NewS3(nil, opts.S3.BucketName)
	case "Filesystem":
		log.Printf("Setting up a Filesystem storage layer with root: %v", opts.Filesystem.RootPath)

		return storage.NewFilesystem(opts.Filesystem.RootPath)
	case "Regex":
		log.Printf("Setting up a Regex storage with %v remaps", opts.Regex.Remaps)

		return storage.NewRegexFromList(opts.Regex.Remaps)
	case "Multistorage":
		log.Printf("Setting up a Multilayer Storage layer with children: %q", opts)
		log.Println("WARNING: Multilayer currently only works in a READ ONLY mode")

		storages := make([]storage.NamedStorage, 0, len(opts.Multistorage.StorageArgs))
		for i, rawArgs := range opts.Multistorage.StorageArgs {
			subArgs, err := shlex.Split(rawArgs)
			if err != nil {
				return nil, errors.Wrapf(err, "failed to split arguments for argument #%d", i)
			}

			var subOpt Options
			_, err = flags.ParseArgs(&subOpt, subArgs)
			if err != nil {
				return nil, errors.Wrapf(err, "failed to cli parse sub argument #%d", i)
			}

			store, err := createStorageFromOption(&subOpt)
			if err != nil {
				return nil, errors.Wrapf(err, "failed to create storage #%d from args", i)
			}

			nstore, ok := store.(storage.NamedStorage)
			if !ok {
				return nil, errors.New("MultiStorage only supports NamedStorage backends")
			}

			storages = append(storages, nstore)
		}

		return multistorage.Simple(storages...)
	default:
		validTypes := make([]string, len(storage.SupportedStorageTypes))

		i := 0
		for k := range storage.SupportedStorageTypes {
			validTypes[i] = k
			i++
		}

		return nil, fmt.Errorf("Unsupported storage-type: '%s', valid ones are: '%v'", opts.StorageType, strings.Join(validTypes, "', '"))
	}
}
<|endoftext|>


<commit_before>package dhcp6

import (
	"bytes"
	"encoding/binary"
	"errors"
	"sort"
	"time"
)

var (
	// errInvalidElapsedTime is returned when a valid duration cannot be parsed
	// from OptionElapsedTime, because too many or too few bytes are present.
	errInvalidElapsedTime = errors.New("invalid option value for OptionElapsedTime")
)

// Options is a map of OptionCode keys with a slice of byte slice values.
// Its methods can be used to easily check for and parse additional
// information from a client request.  If raw data is needed, the map
// can be accessed directly.
type Options map[OptionCode][][]byte

// Add adds a new OptionCode key and value byte slice to the Options map.
func (o Options) Add(key OptionCode, value []byte) {
	o[key] = append(o[key], value)
}

// Get attempts to retrieve the first value specified by an OptionCode
// key.  If a value is found, get returns the value and boolean true.
// If it is not found, or the value slice is entirely empty, Get
// returns nil and boolean false.
func (o Options) Get(key OptionCode) ([]byte, bool) {
	// Empty map has no key/value pairs
	if len(o) == 0 {
		return nil, false
	}

	// Check for value by key
	v, ok := o[key]
	if !ok || len(v) == 0 {
		return nil, false
	}

	return v[0], true
}

// ClientID returns the Client Identifier Option value, described in RFC 3315,
// Section 22.2.  The DUID returned allows unique identification of a client
// to a server.  The boolean return value indicates if OptionClientID was
// present in the Options map.  The error return value indicates if a known,
// valid DUID type could be parsed from the option.
func (o Options) ClientID() (DUID, bool, error) {
	v, ok := o.Get(OptionClientID)
	if !ok {
		return nil, false, nil
	}

	d, err := parseDUID(v)
	return d, true, err
}

// ServerID returns the Server Identifier Option value, described in RFC 3315,
// Section 22.3.  The DUID returned allows unique identification of a server
// to a client.  The boolean return value indicates if OptionServerID was
// present in the Options map.  The error return value indicates if a known,
// valid DUID type could be parsed from the option.
func (o Options) ServerID() (DUID, bool, error) {
	v, ok := o.Get(OptionServerID)
	if !ok {
		return nil, false, nil
	}

	d, err := parseDUID(v)
	return d, true, err
}

// IANA returns the Identity Association for Non-temporary Address Option
// value, described in RFC 3315, Section 22.4.  Multiple IANA values may
// be present in a single DHCP request.  The boolean return value indicates if
// OptionIANA was present in the Options map.  The error return value
// indicates if one or more valid IANAs could not be parsed from the option.
func (o Options) IANA() ([]IANA, bool, error) {
	// Client may send multiple IANA option requests, so we must
	// access the map directly
	vv, ok := o[OptionIANA]
	if !ok {
		return nil, false, nil
	}

	// Parse each IA_NA value
	iana := make([]IANA, len(vv), len(vv))
	for i := range vv {
		ia, err := parseIANA(vv[i])
		if err != nil {
			return nil, true, err
		}

		iana[i] = ia
	}

	return iana, true, nil
}

// IAAddr returns the Identity Association Address Option value, described in
// RFC 3315, Section 22.6.  The IAAddr option must always appear enscapsulated
// in the Options map of a IANA or IATA option.  Multiple IAAddr values may be
// present in a single DHCP request.  The boolean return value indicates if
// OptionIAAddr was present in the Options map.  The error return value
// indicates if one or more valid IAAddrs could be be parsed from the option.
func (o Options) IAAddr() ([]IAAddr, bool, error) {
	// Client may send multiple IAAddr option requests, so we must
	// access the map directly
	vv, ok := o[OptionIAAddr]
	if !ok {
		return nil, false, nil
	}

	// Parse each IAAddr value
	iaaddr := make([]IAAddr, len(vv), len(vv))
	for i := range vv {
		iaa, err := parseIAAddr(vv[i])
		if err != nil {
			return nil, true, err
		}

		iaaddr[i] = iaa
	}

	return iaaddr, true, nil
}

// ElapsedTime returns the Elapsed Time Option value, described in RFC 3315,
// Section 22.9.  The time.Duration returned reports the time elapsed during
// a DHCP transaction, as reported by a client.  The boolean return value
// indicates if OptionElapsedTime was present in the Options map.  The error
// return value indicates if a valid duration could be parsed from the option.
func (o Options) ElapsedTime() (time.Duration, bool, error) {
	v, ok := o.Get(OptionElapsedTime)
	if !ok {
		return 0, false, nil
	}

	// Data must be exactly two bytes
	if len(v) != 2 {
		return 0, false, errInvalidElapsedTime
	}

	// Time is reported in hundredths of seconds, so we convert
	// it to a more manageable milliseconds
	return time.Duration(binary.BigEndian.Uint16(v)) * 10 * time.Millisecond, true, nil
}

// byOptionCode implements sort.Interface for []option.
type byOptionCode []option

func (b byOptionCode) Len() int               { return len(b) }
func (b byOptionCode) Less(i int, j int) bool { return b[i].Code < b[j].Code }
func (b byOptionCode) Swap(i int, j int)      { b[i], b[j] = b[j], b[i] }

// enumerate returns an ordered slice of option data from the Options map,
// for use with sending responses to clients.
func (o Options) enumerate() []option {
	options := make([]option, 0)

	// Send all values for a given key
	for k, v := range o {
		for _, vv := range v {
			options = append(options, option{
				Code: k,
				Data: vv,
			})
		}
	}

	sort.Sort(byOptionCode(options))
	return options
}

// parseOptions returns a slice of option code and values from an input byte
// slice.  It is used with various different types to enable parsing of both
// top-level options, and options embedded within other options.
func parseOptions(b []byte) []option {
	var length int
	var options []option

	buf := bytes.NewBuffer(b)

	for buf.Len() > 4 {
		// 2 bytes: option code
		o := option{}
		o.Code = OptionCode(binary.BigEndian.Uint16(buf.Next(2)))

		// 2 bytes: option length
		length = int(binary.BigEndian.Uint16(buf.Next(2)))

		// If length indicated is zero, skip to next iteration
		if length == 0 {
			continue
		}

		// N bytes: option data
		o.Data = buf.Next(length)

		// If option data has less bytes than indicated by length,
		// discard the option
		if len(o.Data) < length {
			continue
		}

		options = append(options, o)
	}

	return options
}
<commit_msg>options: simplify zero value for []option<commit_after>package dhcp6

import (
	"bytes"
	"encoding/binary"
	"errors"
	"sort"
	"time"
)

var (
	// errInvalidElapsedTime is returned when a valid duration cannot be parsed
	// from OptionElapsedTime, because too many or too few bytes are present.
	errInvalidElapsedTime = errors.New("invalid option value for OptionElapsedTime")
)

// Options is a map of OptionCode keys with a slice of byte slice values.
// Its methods can be used to easily check for and parse additional
// information from a client request.  If raw data is needed, the map
// can be accessed directly.
type Options map[OptionCode][][]byte

// Add adds a new OptionCode key and value byte slice to the Options map.
func (o Options) Add(key OptionCode, value []byte) {
	o[key] = append(o[key], value)
}

// Get attempts to retrieve the first value specified by an OptionCode
// key.  If a value is found, get returns the value and boolean true.
// If it is not found, or the value slice is entirely empty, Get
// returns nil and boolean false.
func (o Options) Get(key OptionCode) ([]byte, bool) {
	// Empty map has no key/value pairs
	if len(o) == 0 {
		return nil, false
	}

	// Check for value by key
	v, ok := o[key]
	if !ok || len(v) == 0 {
		return nil, false
	}

	return v[0], true
}

// ClientID returns the Client Identifier Option value, described in RFC 3315,
// Section 22.2.  The DUID returned allows unique identification of a client
// to a server.  The boolean return value indicates if OptionClientID was
// present in the Options map.  The error return value indicates if a known,
// valid DUID type could be parsed from the option.
func (o Options) ClientID() (DUID, bool, error) {
	v, ok := o.Get(OptionClientID)
	if !ok {
		return nil, false, nil
	}

	d, err := parseDUID(v)
	return d, true, err
}

// ServerID returns the Server Identifier Option value, described in RFC 3315,
// Section 22.3.  The DUID returned allows unique identification of a server
// to a client.  The boolean return value indicates if OptionServerID was
// present in the Options map.  The error return value indicates if a known,
// valid DUID type could be parsed from the option.
func (o Options) ServerID() (DUID, bool, error) {
	v, ok := o.Get(OptionServerID)
	if !ok {
		return nil, false, nil
	}

	d, err := parseDUID(v)
	return d, true, err
}

// IANA returns the Identity Association for Non-temporary Address Option
// value, described in RFC 3315, Section 22.4.  Multiple IANA values may
// be present in a single DHCP request.  The boolean return value indicates if
// OptionIANA was present in the Options map.  The error return value
// indicates if one or more valid IANAs could not be parsed from the option.
func (o Options) IANA() ([]IANA, bool, error) {
	// Client may send multiple IANA option requests, so we must
	// access the map directly
	vv, ok := o[OptionIANA]
	if !ok {
		return nil, false, nil
	}

	// Parse each IA_NA value
	iana := make([]IANA, len(vv), len(vv))
	for i := range vv {
		ia, err := parseIANA(vv[i])
		if err != nil {
			return nil, true, err
		}

		iana[i] = ia
	}

	return iana, true, nil
}

// IAAddr returns the Identity Association Address Option value, described in
// RFC 3315, Section 22.6.  The IAAddr option must always appear enscapsulated
// in the Options map of a IANA or IATA option.  Multiple IAAddr values may be
// present in a single DHCP request.  The boolean return value indicates if
// OptionIAAddr was present in the Options map.  The error return value
// indicates if one or more valid IAAddrs could be be parsed from the option.
func (o Options) IAAddr() ([]IAAddr, bool, error) {
	// Client may send multiple IAAddr option requests, so we must
	// access the map directly
	vv, ok := o[OptionIAAddr]
	if !ok {
		return nil, false, nil
	}

	// Parse each IAAddr value
	iaaddr := make([]IAAddr, len(vv), len(vv))
	for i := range vv {
		iaa, err := parseIAAddr(vv[i])
		if err != nil {
			return nil, true, err
		}

		iaaddr[i] = iaa
	}

	return iaaddr, true, nil
}

// ElapsedTime returns the Elapsed Time Option value, described in RFC 3315,
// Section 22.9.  The time.Duration returned reports the time elapsed during
// a DHCP transaction, as reported by a client.  The boolean return value
// indicates if OptionElapsedTime was present in the Options map.  The error
// return value indicates if a valid duration could be parsed from the option.
func (o Options) ElapsedTime() (time.Duration, bool, error) {
	v, ok := o.Get(OptionElapsedTime)
	if !ok {
		return 0, false, nil
	}

	// Data must be exactly two bytes
	if len(v) != 2 {
		return 0, false, errInvalidElapsedTime
	}

	// Time is reported in hundredths of seconds, so we convert
	// it to a more manageable milliseconds
	return time.Duration(binary.BigEndian.Uint16(v)) * 10 * time.Millisecond, true, nil
}

// byOptionCode implements sort.Interface for []option.
type byOptionCode []option

func (b byOptionCode) Len() int               { return len(b) }
func (b byOptionCode) Less(i int, j int) bool { return b[i].Code < b[j].Code }
func (b byOptionCode) Swap(i int, j int)      { b[i], b[j] = b[j], b[i] }

// enumerate returns an ordered slice of option data from the Options map,
// for use with sending responses to clients.
func (o Options) enumerate() []option {
	// Send all values for a given key
	var options []option
	for k, v := range o {
		for _, vv := range v {
			options = append(options, option{
				Code: k,
				Data: vv,
			})
		}
	}

	sort.Sort(byOptionCode(options))
	return options
}

// parseOptions returns a slice of option code and values from an input byte
// slice.  It is used with various different types to enable parsing of both
// top-level options, and options embedded within other options.
func parseOptions(b []byte) []option {
	var length int
	var options []option

	buf := bytes.NewBuffer(b)

	for buf.Len() > 4 {
		// 2 bytes: option code
		o := option{}
		o.Code = OptionCode(binary.BigEndian.Uint16(buf.Next(2)))

		// 2 bytes: option length
		length = int(binary.BigEndian.Uint16(buf.Next(2)))

		// If length indicated is zero, skip to next iteration
		if length == 0 {
			continue
		}

		// N bytes: option data
		o.Data = buf.Next(length)

		// If option data has less bytes than indicated by length,
		// discard the option
		if len(o.Data) < length {
			continue
		}

		options = append(options, o)
	}

	return options
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////
// Package: easygen
// Purpose: Easy to use universal code/text generator
// Authors: Tong Sun (c) 2015-16, All rights reserved
////////////////////////////////////////////////////////////////////////////

/*

Package easygen is an easy to use universal code/text generator library.

It can be used as a text or html generator for arbitrary purposes with arbitrary data and templates.

It can be used as a code generator, or anything that is structurally repetitive. Some command line parameter handling code generator are provided as examples, including the Go's built-in flag package, and the viper & cobra package.

Many examples have been provided to showcase its functionality, and different ways to use it.

*/
package easygen

import (
	"bytes"
	"fmt"
	ht "html/template"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	tt "text/template"

	"gopkg.in/yaml.v2"
)

////////////////////////////////////////////////////////////////////////////
// Constant and data type/structure definitions

// common type for a *(text|html).Template value
type template interface {
	Execute(wr io.Writer, data interface{}) error
	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
	Name() string
}

////////////////////////////////////////////////////////////////////////////
// Global variables definitions

////////////////////////////////////////////////////////////////////////////
// Function definitions

// Generate2 will produce output according to the given template and driving data files, specified via fileNameTempl and fileName (for data) respectively
func Generate2(HTML bool, fileNameTempl string, fileName string) string {
	Opts.TemplateFile = fileNameTempl
	ret := Generate(HTML, fileName)
	Opts.TemplateFile = ""
	return ret
}

// Generate0 will produce output according from driving data without a template file, using the string from strTempl as the template
func Generate0(HTML bool, strTempl string, fileName string) string {
	Opts.TemplateStr = strTempl
	ret := Generate(HTML, fileName)
	Opts.TemplateStr = ""
	return ret
}

// Generate will produce output from the template according to the corresponding driving data, fileName is for both template and data file name
func Generate(HTML bool, fileName string) string {
	var templates []string

	// Allow to use fileName with and without the @Opts.ExtYaml suffix.
	if _, err := os.Stat(fileName); os.IsNotExist(err) {
		fileName += Opts.ExtYaml
	}

	// Allow to use @Opts.TemplateFile without the @Opts.ExtTmpl suffix.
	if len(Opts.TemplateFile) > 0 {
		for _, template := range strings.Split(Opts.TemplateFile, ",") {
			if _, err := os.Stat(template); os.IsNotExist(err) {
				template += Opts.ExtTmpl
			}
			templates = append(templates, template)
		}
	} else if idx := strings.LastIndex(fileName, "."); idx > 0 {
		templates = []string{fileName[:idx] + Opts.ExtTmpl}
	} else {
		templates = []string{fileName + Opts.ExtTmpl}
	}

	source, err := ioutil.ReadFile(fileName)
	checkError(err)

	m := make(map[interface{}]interface{})

	err = yaml.Unmarshal(source, &m)
	checkError(err)

	env := make(map[string]string)
	for _, e := range os.Environ() {
		sep := strings.Index(e, "=")
		env[e[0:sep]] = e[sep+1:]
	}
	m["ENV"] = env
	//fmt.Printf("] %+v\n", m)

	buf := new(bytes.Buffer)
	for _, template := range templates {
		t, err := ParseFiles(HTML, template)
		checkError(err)

		err = t.Execute(buf, m)
		checkError(err)
	}
	return buf.String()
}

// ParseFiles wraps parsing text or HTML template files into a single
// function, dictated by the first parameter "HTML".
// By Matt Harden @gmail.com
func ParseFiles(HTML bool, filenames ...string) (template, error) {
	var tname string

	if len(Opts.TemplateStr) > 0 {
		if HTML {
			tname = "HT"
		} else {
			tname = "TT"
		}
	} else if len(filenames) == 0 {
		return nil, fmt.Errorf("ParseFiles called without template filename")
	} else {
		tname = filepath.Base(filenames[0])
	}

	if HTML {
		// use html template
		htmlTemplate := ht.New(tname).Funcs(ht.FuncMap{
			"minus1": minus1,
			"cls2lc": cls2lc.String,
			"cls2uc": cls2uc.String,
			"cls2ss": cls2ss.String,
			"ck2lc":  ck2lc.String,
			"ck2uc":  ck2uc.String,
			"ck2ls":  ck2ls.String,
			"ck2ss":  ck2ss.String,
			"clc2ss": clc2ss.String,
			"cuc2ss": cuc2ss.String,
		})
		if len(Opts.TemplateStr) > 0 {
			return htmlTemplate.Parse(Opts.TemplateStr)
		}
		return htmlTemplate.ParseFiles(filenames...)
	}

	// use text template
	textTemplate := tt.New(tname).Funcs(tt.FuncMap{
		"eqf":      strings.EqualFold,
		"split":    strings.Fields,
		"minus1":   minus1,
		"replace":  replace,
		"replacec": replacec,
		"cls2lc":   cls2lc.String,
		"cls2uc":   cls2uc.String,
		"cls2ss":   cls2ss.String,
		"ck2lc":    ck2lc.String,
		"ck2uc":    ck2uc.String,
		"ck2ls":    ck2ls.String,
		"ck2ss":    ck2ss.String,
		"clc2ss":   clc2ss.String,
		"cuc2ss":   cuc2ss.String,
	})

	if len(Opts.TemplateStr) > 0 {
		return textTemplate.Parse(Opts.TemplateStr)
	}
	return textTemplate.ParseFiles(filenames...)
}

// Exit if error occurs
func checkError(err error) {
	if err != nil {
		fmt.Printf("[%s] Fatal error - %s\n", progname, err)
		os.Exit(1)
	}
}
<commit_msg>fix: when reporting error, report on stderr; since stdout is used for program output<commit_after>////////////////////////////////////////////////////////////////////////////
// Package: easygen
// Purpose: Easy to use universal code/text generator
// Authors: Tong Sun (c) 2015-16, All rights reserved
////////////////////////////////////////////////////////////////////////////

/*

Package easygen is an easy to use universal code/text generator library.

It can be used as a text or html generator for arbitrary purposes with arbitrary data and templates.

It can be used as a code generator, or anything that is structurally repetitive. Some command line parameter handling code generator are provided as examples, including the Go's built-in flag package, and the viper & cobra package.

Many examples have been provided to showcase its functionality, and different ways to use it.

*/
package easygen

import (
	"bytes"
	"fmt"
	ht "html/template"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	tt "text/template"

	"gopkg.in/yaml.v2"
)

////////////////////////////////////////////////////////////////////////////
// Constant and data type/structure definitions

// common type for a *(text|html).Template value
type template interface {
	Execute(wr io.Writer, data interface{}) error
	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
	Name() string
}

////////////////////////////////////////////////////////////////////////////
// Global variables definitions

////////////////////////////////////////////////////////////////////////////
// Function definitions

// Generate2 will produce output according to the given template and driving data files, specified via fileNameTempl and fileName (for data) respectively
func Generate2(HTML bool, fileNameTempl string, fileName string) string {
	Opts.TemplateFile = fileNameTempl
	ret := Generate(HTML, fileName)
	Opts.TemplateFile = ""
	return ret
}

// Generate0 will produce output according from driving data without a template file, using the string from strTempl as the template
func Generate0(HTML bool, strTempl string, fileName string) string {
	Opts.TemplateStr = strTempl
	ret := Generate(HTML, fileName)
	Opts.TemplateStr = ""
	return ret
}

// Generate will produce output from the template according to the corresponding driving data, fileName is for both template and data file name
func Generate(HTML bool, fileName string) string {
	var templates []string

	// Allow to use fileName with and without the @Opts.ExtYaml suffix.
	if _, err := os.Stat(fileName); os.IsNotExist(err) {
		fileName += Opts.ExtYaml
	}

	// Allow to use @Opts.TemplateFile without the @Opts.ExtTmpl suffix.
	if len(Opts.TemplateFile) > 0 {
		for _, template := range strings.Split(Opts.TemplateFile, ",") {
			if _, err := os.Stat(template); os.IsNotExist(err) {
				template += Opts.ExtTmpl
			}
			templates = append(templates, template)
		}
	} else if idx := strings.LastIndex(fileName, "."); idx > 0 {
		templates = []string{fileName[:idx] + Opts.ExtTmpl}
	} else {
		templates = []string{fileName + Opts.ExtTmpl}
	}

	source, err := ioutil.ReadFile(fileName)
	checkError(err)

	m := make(map[interface{}]interface{})

	err = yaml.Unmarshal(source, &m)
	checkError(err)

	env := make(map[string]string)
	for _, e := range os.Environ() {
		sep := strings.Index(e, "=")
		env[e[0:sep]] = e[sep+1:]
	}
	m["ENV"] = env
	//fmt.Printf("] %+v\n", m)

	buf := new(bytes.Buffer)
	for _, template := range templates {
		t, err := ParseFiles(HTML, template)
		checkError(err)

		err = t.Execute(buf, m)
		checkError(err)
	}
	return buf.String()
}

// ParseFiles wraps parsing text or HTML template files into a single
// function, dictated by the first parameter "HTML".
// By Matt Harden @gmail.com
func ParseFiles(HTML bool, filenames ...string) (template, error) {
	var tname string

	if len(Opts.TemplateStr) > 0 {
		if HTML {
			tname = "HT"
		} else {
			tname = "TT"
		}
	} else if len(filenames) == 0 {
		return nil, fmt.Errorf("ParseFiles called without template filename")
	} else {
		tname = filepath.Base(filenames[0])
	}

	if HTML {
		// use html template
		htmlTemplate := ht.New(tname).Funcs(ht.FuncMap{
			"minus1": minus1,
			"cls2lc": cls2lc.String,
			"cls2uc": cls2uc.String,
			"cls2ss": cls2ss.String,
			"ck2lc":  ck2lc.String,
			"ck2uc":  ck2uc.String,
			"ck2ls":  ck2ls.String,
			"ck2ss":  ck2ss.String,
			"clc2ss": clc2ss.String,
			"cuc2ss": cuc2ss.String,
		})
		if len(Opts.TemplateStr) > 0 {
			return htmlTemplate.Parse(Opts.TemplateStr)
		}
		return htmlTemplate.ParseFiles(filenames...)
	}

	// use text template
	textTemplate := tt.New(tname).Funcs(tt.FuncMap{
		"eqf":      strings.EqualFold,
		"split":    strings.Fields,
		"minus1":   minus1,
		"replace":  replace,
		"replacec": replacec,
		"cls2lc":   cls2lc.String,
		"cls2uc":   cls2uc.String,
		"cls2ss":   cls2ss.String,
		"ck2lc":    ck2lc.String,
		"ck2uc":    ck2uc.String,
		"ck2ls":    ck2ls.String,
		"ck2ss":    ck2ss.String,
		"clc2ss":   clc2ss.String,
		"cuc2ss":   cuc2ss.String,
	})

	if len(Opts.TemplateStr) > 0 {
		return textTemplate.Parse(Opts.TemplateStr)
	}
	return textTemplate.ParseFiles(filenames...)
}

// Exit if error occurs
func checkError(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "[%s] Fatal error - %s\n", progname, err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package colonycore

import (
	"github.com/eaciit/orm/v1"
)

type Menu struct {
	orm.ModelBase
	ID string `json:"_id",bson:"_id"`

	AccessId  string `json:"AccessId",bson:"AccessId"`
	Title     string `json:"title",bson:"title"`
	Childrens []Menu `json:"childrens",bson:"childrens"`
	Link      string `json:"link",bson:"link"`
}

func (a *Menu) TableName() string {
	return "menu"
}

func (a *Menu) RecordID() interface{} {
	return a.ID
}
<commit_msg>change the name<commit_after>package colonycore

import (
	"github.com/eaciit/orm/v1"
)

type Menu struct {
	orm.ModelBase
	ID string `json:"_id",bson:"_id"`

	AccessId  string `json:"AccessId",bson:"AccessId"`
	Title     string `json:"title",bson:"title"`
	Childrens []Menu `json:"childrens",bson:"childrens"`
	Link      string `json:"link",bson:"link"`
}

func (a *Menu) TableName() string {
	return "menus"
}

func (a *Menu) RecordID() interface{} {
	return a.ID
}
<|endoftext|>


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

// THIS FILE IS DEPRECATED!!!
// Please edit the new "jiri" tool in release/go/src/v.io/jiri.

package main

import (
	"os"
	"os/exec"
)

// main calls "jiri" tool with whatever arguments it was called with.
func main() {
	args := os.Args[1:]
	cmd := exec.Command("jiri", args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	if err := cmd.Run(); err != nil {
		// The jiri tool should have reported an error in its output.  Don't
		// print an error here because it can be confusing and makes it harder
		// to spot the real error.
		os.Exit(1)
	}
}
<commit_msg>TBR: v23 tool will set JIRI_ROOT to $V23_ROOT.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// THIS FILE IS DEPRECATED!!!
// Please edit the new "jiri" tool in release/go/src/v.io/jiri.

package main

import (
	"os"
	"os/exec"
)

// main calls "jiri" tool with whatever arguments it was called with.
func main() {
	args := os.Args[1:]
	cmd := exec.Command("jiri", args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin

	// If JIRI_ROOT is not set, set it to $V23_ROOT.
	jiriRoot := os.Getenv("JIRI_ROOT")
	if jiriRoot == "" {
		if err := os.Setenv("JIRI_ROOT", os.Getenv("V23_ROOT")); err != nil {
			panic(err)
		}
	}

	if err := cmd.Run(); err != nil {
		// The jiri tool should have reported an error in its output.  Don't
		// print an error here because it can be confusing and makes it harder
		// to spot the real error.
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>// eos stands for 'enhanced os', it mostly supplies 'eos.Open', which supports
// the 'itchfs://' scheme to access remote files
package eos

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

	"github.com/go-errors/errors"
	"github.com/itchio/httpkit/httpfile"
	"github.com/itchio/wharf/eos/option"
)

var debugHttpFile = os.Getenv("HTTPFILE_DEBUG") == "1"

type File interface {
	io.Reader
	io.Closer
	io.ReaderAt
	io.Seeker

	Stat() (os.FileInfo, error)
}

type Handler interface {
	Scheme() string
	MakeResource(u *url.URL) (httpfile.GetURLFunc, httpfile.NeedsRenewalFunc, error)
}

var handlers = make(map[string]Handler)

func RegisterHandler(h Handler) error {
	scheme := h.Scheme()

	if handlers[scheme] != nil {
		return fmt.Errorf("already have a handler for %s:", scheme)
	}

	handlers[h.Scheme()] = h
	return nil
}

func DeregisterHandler(h Handler) {
	delete(handlers, h.Scheme())
}

type simpleHTTPResource struct {
	url string
}

func (shr *simpleHTTPResource) GetURL() (string, error) {
	return shr.url, nil
}

func (shr *simpleHTTPResource) NeedsRenewal(res *http.Response, body []byte) bool {
	return false
}

func Open(name string, opts ...option.Option) (File, error) {
	settings := option.DefaultSettings()

	for _, opt := range opts {
		opt.Apply(settings)
	}

	if name == "/dev/null" {
		return &emptyFile{}, nil
	}

	u, err := url.Parse(name)
	if err != nil {
		return nil, errors.Wrap(err, 1)
	}

	switch u.Scheme {
	case "http", "https":
		res := &simpleHTTPResource{name}
		hf, err := httpfile.New(res.GetURL, res.NeedsRenewal, &httpfile.Settings{
			Client: settings.HTTPClient,
		})

		if err != nil {
			return nil, err
		}

		if debugHttpFile {
			hf.Log = func(msg string) {
				fmt.Fprintf(os.Stderr, "[hf] %s\n", msg)
			}
		}

		return hf, nil
	default:
		handler := handlers[u.Scheme]
		if handler == nil {
			return os.Open(name)
		}

		getURL, needsRenewal, err := handler.MakeResource(u)
		if err != nil {
			return nil, errors.Wrap(err, 1)
		}

		hf, err := httpfile.New(getURL, needsRenewal, &httpfile.Settings{
			Client: settings.HTTPClient,
		})

		if err != nil {
			return nil, err
		}

		if debugHttpFile {
			hf.Log = func(msg string) {
				fmt.Fprintf(os.Stderr, "[hf] %s\n", msg)
			}
		}

		return hf, nil
	}
}

func Redact(name string) string {
	u, err := url.Parse(name)
	if err != nil {
		return name
	}

	return u.Path
}
<commit_msg>Handle HTTPFILE_DEBUG=2 (or higher) properly<commit_after>// eos stands for 'enhanced os', it mostly supplies 'eos.Open', which supports
// the 'itchfs://' scheme to access remote files
package eos

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"strconv"

	"github.com/go-errors/errors"
	"github.com/itchio/httpkit/httpfile"
	"github.com/itchio/wharf/eos/option"
)

var httpFileLogLevel = os.Getenv("HTTPFILE_DEBUG")

type File interface {
	io.Reader
	io.Closer
	io.ReaderAt
	io.Seeker

	Stat() (os.FileInfo, error)
}

type Handler interface {
	Scheme() string
	MakeResource(u *url.URL) (httpfile.GetURLFunc, httpfile.NeedsRenewalFunc, error)
}

var handlers = make(map[string]Handler)

func RegisterHandler(h Handler) error {
	scheme := h.Scheme()

	if handlers[scheme] != nil {
		return fmt.Errorf("already have a handler for %s:", scheme)
	}

	handlers[h.Scheme()] = h
	return nil
}

func DeregisterHandler(h Handler) {
	delete(handlers, h.Scheme())
}

type simpleHTTPResource struct {
	url string
}

func (shr *simpleHTTPResource) GetURL() (string, error) {
	return shr.url, nil
}

func (shr *simpleHTTPResource) NeedsRenewal(res *http.Response, body []byte) bool {
	return false
}

func Open(name string, opts ...option.Option) (File, error) {
	settings := option.DefaultSettings()

	for _, opt := range opts {
		opt.Apply(settings)
	}

	if name == "/dev/null" {
		return &emptyFile{}, nil
	}

	u, err := url.Parse(name)
	if err != nil {
		return nil, errors.Wrap(err, 1)
	}

	switch u.Scheme {
	case "http", "https":
		res := &simpleHTTPResource{name}
		hf, err := httpfile.New(res.GetURL, res.NeedsRenewal, &httpfile.Settings{
			Client: settings.HTTPClient,
		})

		if err != nil {
			return nil, err
		}

		setupHttpFileDebug(hf)

		return hf, nil
	default:
		handler := handlers[u.Scheme]
		if handler == nil {
			return os.Open(name)
		}

		getURL, needsRenewal, err := handler.MakeResource(u)
		if err != nil {
			return nil, errors.Wrap(err, 1)
		}

		hf, err := httpfile.New(getURL, needsRenewal, &httpfile.Settings{
			Client: settings.HTTPClient,
		})

		if err != nil {
			return nil, err
		}

		setupHttpFileDebug(hf)

		return hf, nil
	}
}

func Redact(name string) string {
	u, err := url.Parse(name)
	if err != nil {
		return name
	}

	return u.Path
}

func setupHttpFileDebug(hf *httpfile.HTTPFile) {
	if httpFileLogLevel != "" {
		hf.Log = func(msg string) {
			fmt.Fprintf(os.Stderr, "[hf] %s\n", msg)
		}
		numericLevel, err := strconv.ParseInt(httpFileLogLevel, 10, 64)
		if err == nil {
			hf.LogLevel = int(numericLevel)
		}
	}
}
<|endoftext|>


<commit_before>// Package equaler gives a simple interface to compare objects of arbitrary types.
package equaler

// Equaler is a simple interface that is used to determing the equality of two
// variables
type Equaler interface {
	Equal(interface{}) bool
}

type eFalse struct{}

func (eFalse) Equal(interface{}) bool {
	return false
}

func (eFalse) String() string {
	return "Equaler - False"
}

type eThis struct{}

func (eThis) Equal(e interface{}) bool {
	_, ok := e.(eThis)
	return ok
}

func (eThis) String() string {
	return "Equaler - This"
}

var (
	// EFalse represents an Equaler that never matches, even against itself
	EFalse Equaler = eFalse{}
	// EThis represents an Equaler that only and always matches itself
	EThis Equaler = eThis{}
)
<commit_msg>updated to vanity urls<commit_after>// Package equaler gives a simple interface to compare objects of arbitrary types.
package equaler // import "vimagination.zapto.org/equaler"

// Equaler is a simple interface that is used to determing the equality of two
// variables
type Equaler interface {
	Equal(interface{}) bool
}

type eFalse struct{}

func (eFalse) Equal(interface{}) bool {
	return false
}

func (eFalse) String() string {
	return "Equaler - False"
}

type eThis struct{}

func (eThis) Equal(e interface{}) bool {
	_, ok := e.(eThis)
	return ok
}

func (eThis) String() string {
	return "Equaler - This"
}

var (
	// EFalse represents an Equaler that never matches, even against itself
	EFalse Equaler = eFalse{}
	// EThis represents an Equaler that only and always matches itself
	EThis Equaler = eThis{}
)
<|endoftext|>


<commit_before>// Package errwrap implements methods to formalize error wrapping in Go.
//
// All of the top-level functions that take an `error` are built to be able
// to take any error, not just wrapped errors. This allows you to use errwrap
// without having to type-check and type-cast everywhere.
package errwrap

import (
	"errors"
	"reflect"
	"strings"
)

// WalkFunc is the callback called for Walk.
type WalkFunc func(error)

// Wrap defines that outer wraps inner, returning an error type that
// can be cleanly used with the other methods in this package, such as
// Contains, GetAll, etc.
//
// This function won't modify the error message at all (the outer message
// will be used).
func Wrap(outer, inner error) error {
	return &wrappedError{
		Outer: outer,
		Inner: inner,
	}
}

// Wrapf wraps an error with a formatting message. This is similar to using
// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
// errors, you should replace it with this.
//
// format is the format of the error message. The string '{{err}}' will
// be replaced with the original error message.
func Wrapf(format string, err error) error {
	outerMsg := "<nil>"
	if err != nil {
		outerMsg = err.Error()
	}

	outer := errors.New(strings.Replace(
		format, "{{err}}", outerMsg, -1))

	return Wrap(outer, err)
}

// Contains checks if the given error contains an error with the
// message msg. If err is not a wrapped error, this will always return
// false unless the error itself happens to match this msg.
func Contains(err error, msg string) bool {
	return len(GetAll(err, msg)) > 0
}

// ContainsType checks if the given error contains an error with
// the same concrete type as v. If err is not a wrapped error, this will
// check the err itself.
func ContainsType(err error, v interface{}) bool {
	return len(GetAllType(err, v)) > 0
}

// GetAll gets all the errors that might be wrapped in err with the
// given message. The order of the errors is such that the outermost
// matching error (the most recent wrap) is index zero, and so on.
func GetAll(err error, msg string) []error {
	var result []error

	Walk(err, func(err error) {
		if err.Error() == msg {
			result = append(result, err)
		}
	})

	return result
}

// GetAllType gets all the errors that are the same type as v.
//
// The order of the return value is the same as described in GetAll.
func GetAllType(err error, v interface{}) []error {
	var result []error

	var search string
	if v != nil {
		search = reflect.TypeOf(v).String()
	}
	Walk(err, func(err error) {
		var needle string
		if err != nil {
			needle = reflect.TypeOf(err).String()
		}

		if needle == search {
			result = append(result, err)
		}
	})

	return result
}

// Walk walks all the wrapped errors in err and calls the callback. If
// err isn't a wrapped error, this will be called once for err. If err
// is a wrapped error, the callback will be called for both the wrapper
// that implements error as well as the wrapped error itself.
func Walk(err error, cb WalkFunc) {
	if err == nil {
		return
	}

	switch e := err.(type) {
	case *wrappedError:
		cb(e.Outer)
		Walk(e.Inner, cb)
	default:
		cb(err)
	}
}

// wrappedError is an implementation of error that has both the
// outer and inner errors.
type wrappedError struct {
	Outer error
	Inner error
}

func (w *wrappedError) Error() string {
	return w.Outer.Error()
}
<commit_msg>Get and GetType<commit_after>// Package errwrap implements methods to formalize error wrapping in Go.
//
// All of the top-level functions that take an `error` are built to be able
// to take any error, not just wrapped errors. This allows you to use errwrap
// without having to type-check and type-cast everywhere.
package errwrap

import (
	"errors"
	"reflect"
	"strings"
)

// WalkFunc is the callback called for Walk.
type WalkFunc func(error)

// Wrap defines that outer wraps inner, returning an error type that
// can be cleanly used with the other methods in this package, such as
// Contains, GetAll, etc.
//
// This function won't modify the error message at all (the outer message
// will be used).
func Wrap(outer, inner error) error {
	return &wrappedError{
		Outer: outer,
		Inner: inner,
	}
}

// Wrapf wraps an error with a formatting message. This is similar to using
// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
// errors, you should replace it with this.
//
// format is the format of the error message. The string '{{err}}' will
// be replaced with the original error message.
func Wrapf(format string, err error) error {
	outerMsg := "<nil>"
	if err != nil {
		outerMsg = err.Error()
	}

	outer := errors.New(strings.Replace(
		format, "{{err}}", outerMsg, -1))

	return Wrap(outer, err)
}

// Contains checks if the given error contains an error with the
// message msg. If err is not a wrapped error, this will always return
// false unless the error itself happens to match this msg.
func Contains(err error, msg string) bool {
	return len(GetAll(err, msg)) > 0
}

// ContainsType checks if the given error contains an error with
// the same concrete type as v. If err is not a wrapped error, this will
// check the err itself.
func ContainsType(err error, v interface{}) bool {
	return len(GetAllType(err, v)) > 0
}

// Get is the same as GetAll but returns the deepest matching error.
func Get(err error, msg string) error {
	es := GetAll(err, msg)
	if len(es) > 0 {
		return es[len(es)-1]
	}

	return nil
}

// GetType is the same as GetAllType but returns the deepest matching error.
func GetType(err error, v interface{}) error {
	es := GetAllType(err, v)
	if len(es) > 0 {
		return es[len(es)-1]
	}

	return nil
}

// GetAll gets all the errors that might be wrapped in err with the
// given message. The order of the errors is such that the outermost
// matching error (the most recent wrap) is index zero, and so on.
func GetAll(err error, msg string) []error {
	var result []error

	Walk(err, func(err error) {
		if err.Error() == msg {
			result = append(result, err)
		}
	})

	return result
}

// GetAllType gets all the errors that are the same type as v.
//
// The order of the return value is the same as described in GetAll.
func GetAllType(err error, v interface{}) []error {
	var result []error

	var search string
	if v != nil {
		search = reflect.TypeOf(v).String()
	}
	Walk(err, func(err error) {
		var needle string
		if err != nil {
			needle = reflect.TypeOf(err).String()
		}

		if needle == search {
			result = append(result, err)
		}
	})

	return result
}

// Walk walks all the wrapped errors in err and calls the callback. If
// err isn't a wrapped error, this will be called once for err. If err
// is a wrapped error, the callback will be called for both the wrapper
// that implements error as well as the wrapped error itself.
func Walk(err error, cb WalkFunc) {
	if err == nil {
		return
	}

	switch e := err.(type) {
	case *wrappedError:
		cb(e.Outer)
		Walk(e.Inner, cb)
	default:
		cb(err)
	}
}

// wrappedError is an implementation of error that has both the
// outer and inner errors.
type wrappedError struct {
	Outer error
	Inner error
}

func (w *wrappedError) Error() string {
	return w.Outer.Error()
}
<|endoftext|>


<commit_before>// Tideland Go Library - Etc
//
// Copyright (C) 2016 Frank Mueller / Tideland / Oldenburg / Germany
//
// All rights reserved. Use of this source code is governed
// by the new BSD license.

package etc

//--------------------
// IMPORTS
//--------------------

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"regexp"
	"strings"
	"time"

	"github.com/tideland/golib/collections"
	"github.com/tideland/golib/errors"
	"github.com/tideland/golib/sml"
	"github.com/tideland/golib/stringex"
)

//--------------------
// GLOBAL
//--------------------

// key is to address a configuration inside a context.
type key int

var (
	etcKey    key = 0
	etcRoot       = []string{"etc"}
	defaulter     = stringex.NewDefaulter("etc", true)
)

//--------------------
// VALUE
//--------------------

// value helps to use the stringex.Defaulter.
type value struct {
	path    []string
	changer collections.KeyStringValueChanger
}

// Value retrieves the value or an error. It implements
// the Valuer interface.
func (v *value) Value() (string, error) {
	sv, err := v.changer.Value()
	if err != nil {
		return "", errors.New(ErrInvalidPath, errorMessages, pathToString(v.path))
	}
	return sv, nil
}

//--------------------
// ETC
//--------------------

// Application is used to apply values to a configurtation.
type Application map[string]string

// Etc contains the read etc configuration and provides access to
// it. ThetcRoot node "etc" is automatically preceded to the path.
// The node name have to consist out of 'a' to 'z', '0' to '9', and
// '-'. The nodes of a path are separated by '/'.
type Etc interface {
	fmt.Stringer

	// HasPath checks if the configurations has the defined path
	// regardles of the value or possible subconfigurations.
	HasPath(path string) bool

	// ValueAsString retrieves the string value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsString(path, dv string) string

	// ValueAsBool retrieves the bool value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsBool(path string, dv bool) bool

	// ValueAsInt retrieves the int value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsInt(path string, dv int) int

	// ValueAsFloat64 retrieves the float64 value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsFloat64(path string, dv float64) float64

	// ValueAsTime retrieves the string value at a given path and
	// interprets it as time with the passed format. If it
	// doesn't exist the default value dv is returned.
	ValueAsTime(path, layout string, dv time.Time) time.Time

	// ValueAsDuration retrieves the duration value at a given path.
	// If it doesn't exist the default value dv is returned.
	ValueAsDuration(path string, dv time.Duration) time.Duration

	// Spit produces a subconfiguration below the passed path.
	// The last path part will be the new root, all values below
	// that configuration node will be below the created root.
	Split(path string) (Etc, error)

	// Dunp creates a map of paths and their values to apply
	// them into other configurations.
	Dump() (Application, error)

	// Apply creates a new configuration by adding of overwriting
	// the passed values. The keys of the map have to be slash
	// separated configuration paths without the leading "etc".
	Apply(appl Application) (Etc, error)
}

// etc implements the Etc interface.
type etc struct {
	values collections.KeyStringValueTree
}

// Read reads the SML source of the configuration from a
// reader, parses it, and returns the etc instance.
func Read(source io.Reader) (Etc, error) {
	builder := sml.NewKeyStringValueTreeBuilder()
	err := sml.ReadSML(source, builder)
	if err != nil {
		return nil, errors.Annotate(err, ErrIllegalSourceFormat, errorMessages)
	}
	values, err := builder.Tree()
	if err != nil {
		return nil, errors.Annotate(err, ErrIllegalSourceFormat, errorMessages)
	}
	if err = values.At("etc").Error(); err != nil {
		return nil, errors.Annotate(err, ErrIllegalSourceFormat, errorMessages)
	}
	cfg := &etc{
		values: values,
	}
	if err = cfg.postProcess(); err != nil {
		return nil, errors.Annotate(err, ErrCannotPostProcess, errorMessages)
	}
	return cfg, nil
}

// ReadString reads the SML source of the configuration from a
// string, parses it, and returns the etc instance.
func ReadString(source string) (Etc, error) {
	return Read(strings.NewReader(source))
}

// ReadFile reads the SML source of a configuration file,
// parses it, and returns the etc instance.
func ReadFile(filename string) (Etc, error) {
	source, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, errors.Annotate(err, ErrCannotReadFile, errorMessages, filename)
	}
	return ReadString(string(source))
}

// HasPath implements the Etc interface.
func (e *etc) HasPath(path string) bool {
	fullPath := makeFullPath(path)
	changer := e.values.At(fullPath...)
	return changer.Error() == nil
}

// ValueAsString implements the Etc interface.
func (e *etc) ValueAsString(path, dv string) string {
	value := e.valueAt(path)
	return defaulter.AsString(value, dv)
}

// ValueAsBool implements the Etc interface.
func (e *etc) ValueAsBool(path string, dv bool) bool {
	value := e.valueAt(path)
	return defaulter.AsBool(value, dv)
}

// ValueAsInt implements the Etc interface.
func (e *etc) ValueAsInt(path string, dv int) int {
	value := e.valueAt(path)
	return defaulter.AsInt(value, dv)
}

// ValueAsFloat64 implements the Etc interface.
func (e *etc) ValueAsFloat64(path string, dv float64) float64 {
	value := e.valueAt(path)
	return defaulter.AsFloat64(value, dv)
}

// ValueAsTime implements the Etc interface.
func (e *etc) ValueAsTime(path, format string, dv time.Time) time.Time {
	value := e.valueAt(path)
	return defaulter.AsTime(value, format, dv)
}

// ValueAsDuration implements the Etc interface.
func (e *etc) ValueAsDuration(path string, dv time.Duration) time.Duration {
	value := e.valueAt(path)
	return defaulter.AsDuration(value, dv)
}

// Split implements the Etc interface.
func (e *etc) Split(path string) (Etc, error) {
	fullPath := makeFullPath(path)
	values, err := e.values.CopyAt(fullPath...)
	if err != nil {
		return nil, errors.Annotate(err, ErrCannotSplit, errorMessages)
	}
	values.At(fullPath[len(fullPath)-1:]...).SetKey("etc")
	es := &etc{
		values: values,
	}
	return es, nil
}

// Dump implements the Etc interface.
func (e *etc) Dump() (Application, error) {
	appl := Application{}
	err := e.values.DoAllDeep(func(ks []string, v string) error {
		if len(ks) == 1 {
			// Continue on root element.
			return nil
		}
		path := strings.Join(ks[1:], "/")
		appl[path] = v
		return nil
	})
	if err != nil {
		return nil, err
	}
	return appl, nil
}

// Apply implements the Etc interface.
func (e *etc) Apply(appl Application) (Etc, error) {
	ec := &etc{
		values: e.values.Copy(),
	}
	for path, value := range appl {
		fullPath := makeFullPath(path)
		_, err := ec.values.Create(fullPath...).SetValue(value)
		if err != nil {
			return nil, errors.Annotate(err, ErrCannotApply, errorMessages)
		}
	}
	return ec, nil
}

// Apply implements the Stringer interface.
func (e *etc) String() string {
	return fmt.Sprintf("%v", e.values)
}

// valueAt retrieves and encapsulates the value
// at a given path.
func (e *etc) valueAt(path string) *value {
	fullPath := makeFullPath(path)
	changer := e.values.At(fullPath...)
	return &value{fullPath, changer}
}

// postProcess replaces templates formated [path||default]
// with values found at that path or the default.
func (e *etc) postProcess() error {
	re := regexp.MustCompile("\\[.+(||.+)\\]")
	// Find all entries with template.
	changers := e.values.FindAll(func(k, v string) (bool, error) {
		return re.MatchString(v), nil
	})
	// Change the template.
	for _, changer := range changers {
		value, err := changer.Value()
		if err != nil {
			return err
		}
		found := re.FindString(value)
		pathDefault := strings.SplitN(found[1:len(found)-1], "||", 2)
		dv := ""
		if len(pathDefault) > 1 {
			dv = pathDefault[1]
		}
		substitute := e.ValueAsString(pathDefault[0], dv)
		replaced := string.Replace(value, found, substitute, -1)
		_, err =changer.SetValue(replaced)
		if err != nil {
			return err
		}
	}
	return nil
}

//--------------------
// CONTEXT
//--------------------

// NewContext returns a new context that carries a configuration.
func NewContext(ctx context.Context, cfg Etc) context.Context {
	return context.WithValue(ctx, etcKey, cfg)
}

// FromContext returns the configuration stored in ctx, if any.
func FromContext(ctx context.Context) (Etc, bool) {
	cfg, ok := ctx.Value(etcKey).(Etc)
	return cfg, ok
}

//--------------------
// HELPERS
//--------------------

// makeFullPath creates the full path out of a string.
func makeFullPath(path string) []string {
	parts := stringex.SplitMap(path, "/", func(p string) (string, bool) {
		if p == "" {
			return "", false
		}
		return strings.ToLower(p), true
	})
	return append(etcRoot, parts...)
}

// pathToString returns the path in a filesystem like notation.
func pathToString(path []string) string {
	return "/" + strings.Join(path, "/")
}

// EOF
<commit_msg>Minor compiling checks<commit_after>// Tideland Go Library - Etc
//
// Copyright (C) 2016 Frank Mueller / Tideland / Oldenburg / Germany
//
// All rights reserved. Use of this source code is governed
// by the new BSD license.

package etc

//--------------------
// IMPORTS
//--------------------

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"regexp"
	"strings"
	"time"

	"github.com/tideland/golib/collections"
	"github.com/tideland/golib/errors"
	"github.com/tideland/golib/sml"
	"github.com/tideland/golib/stringex"
)

//--------------------
// GLOBAL
//--------------------

// key is to address a configuration inside a context.
type key int

var (
	etcKey    key = 0
	etcRoot       = []string{"etc"}
	defaulter     = stringex.NewDefaulter("etc", true)
)

//--------------------
// VALUE
//--------------------

// value helps to use the stringex.Defaulter.
type value struct {
	path    []string
	changer collections.KeyStringValueChanger
}

// Value retrieves the value or an error. It implements
// the Valuer interface.
func (v *value) Value() (string, error) {
	sv, err := v.changer.Value()
	if err != nil {
		return "", errors.New(ErrInvalidPath, errorMessages, pathToString(v.path))
	}
	return sv, nil
}

//--------------------
// ETC
//--------------------

// Application is used to apply values to a configurtation.
type Application map[string]string

// Etc contains the read etc configuration and provides access to
// it. ThetcRoot node "etc" is automatically preceded to the path.
// The node name have to consist out of 'a' to 'z', '0' to '9', and
// '-'. The nodes of a path are separated by '/'.
type Etc interface {
	fmt.Stringer

	// HasPath checks if the configurations has the defined path
	// regardles of the value or possible subconfigurations.
	HasPath(path string) bool

	// ValueAsString retrieves the string value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsString(path, dv string) string

	// ValueAsBool retrieves the bool value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsBool(path string, dv bool) bool

	// ValueAsInt retrieves the int value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsInt(path string, dv int) int

	// ValueAsFloat64 retrieves the float64 value at a given path. If it
	// doesn't exist the default value dv is returned.
	ValueAsFloat64(path string, dv float64) float64

	// ValueAsTime retrieves the string value at a given path and
	// interprets it as time with the passed format. If it
	// doesn't exist the default value dv is returned.
	ValueAsTime(path, layout string, dv time.Time) time.Time

	// ValueAsDuration retrieves the duration value at a given path.
	// If it doesn't exist the default value dv is returned.
	ValueAsDuration(path string, dv time.Duration) time.Duration

	// Spit produces a subconfiguration below the passed path.
	// The last path part will be the new root, all values below
	// that configuration node will be below the created root.
	Split(path string) (Etc, error)

	// Dunp creates a map of paths and their values to apply
	// them into other configurations.
	Dump() (Application, error)

	// Apply creates a new configuration by adding of overwriting
	// the passed values. The keys of the map have to be slash
	// separated configuration paths without the leading "etc".
	Apply(appl Application) (Etc, error)
}

// etc implements the Etc interface.
type etc struct {
	values collections.KeyStringValueTree
}

// Read reads the SML source of the configuration from a
// reader, parses it, and returns the etc instance.
func Read(source io.Reader) (Etc, error) {
	builder := sml.NewKeyStringValueTreeBuilder()
	err := sml.ReadSML(source, builder)
	if err != nil {
		return nil, errors.Annotate(err, ErrIllegalSourceFormat, errorMessages)
	}
	values, err := builder.Tree()
	if err != nil {
		return nil, errors.Annotate(err, ErrIllegalSourceFormat, errorMessages)
	}
	if err = values.At("etc").Error(); err != nil {
		return nil, errors.Annotate(err, ErrIllegalSourceFormat, errorMessages)
	}
	cfg := &etc{
		values: values,
	}
	if err = cfg.postProcess(); err != nil {
		return nil, errors.Annotate(err, ErrCannotPostProcess, errorMessages)
	}
	return cfg, nil
}

// ReadString reads the SML source of the configuration from a
// string, parses it, and returns the etc instance.
func ReadString(source string) (Etc, error) {
	return Read(strings.NewReader(source))
}

// ReadFile reads the SML source of a configuration file,
// parses it, and returns the etc instance.
func ReadFile(filename string) (Etc, error) {
	source, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, errors.Annotate(err, ErrCannotReadFile, errorMessages, filename)
	}
	return ReadString(string(source))
}

// HasPath implements the Etc interface.
func (e *etc) HasPath(path string) bool {
	fullPath := makeFullPath(path)
	changer := e.values.At(fullPath...)
	return changer.Error() == nil
}

// ValueAsString implements the Etc interface.
func (e *etc) ValueAsString(path, dv string) string {
	value := e.valueAt(path)
	return defaulter.AsString(value, dv)
}

// ValueAsBool implements the Etc interface.
func (e *etc) ValueAsBool(path string, dv bool) bool {
	value := e.valueAt(path)
	return defaulter.AsBool(value, dv)
}

// ValueAsInt implements the Etc interface.
func (e *etc) ValueAsInt(path string, dv int) int {
	value := e.valueAt(path)
	return defaulter.AsInt(value, dv)
}

// ValueAsFloat64 implements the Etc interface.
func (e *etc) ValueAsFloat64(path string, dv float64) float64 {
	value := e.valueAt(path)
	return defaulter.AsFloat64(value, dv)
}

// ValueAsTime implements the Etc interface.
func (e *etc) ValueAsTime(path, format string, dv time.Time) time.Time {
	value := e.valueAt(path)
	return defaulter.AsTime(value, format, dv)
}

// ValueAsDuration implements the Etc interface.
func (e *etc) ValueAsDuration(path string, dv time.Duration) time.Duration {
	value := e.valueAt(path)
	return defaulter.AsDuration(value, dv)
}

// Split implements the Etc interface.
func (e *etc) Split(path string) (Etc, error) {
	fullPath := makeFullPath(path)
	values, err := e.values.CopyAt(fullPath...)
	if err != nil {
		return nil, errors.Annotate(err, ErrCannotSplit, errorMessages)
	}
	values.At(fullPath[len(fullPath)-1:]...).SetKey("etc")
	es := &etc{
		values: values,
	}
	return es, nil
}

// Dump implements the Etc interface.
func (e *etc) Dump() (Application, error) {
	appl := Application{}
	err := e.values.DoAllDeep(func(ks []string, v string) error {
		if len(ks) == 1 {
			// Continue on root element.
			return nil
		}
		path := strings.Join(ks[1:], "/")
		appl[path] = v
		return nil
	})
	if err != nil {
		return nil, err
	}
	return appl, nil
}

// Apply implements the Etc interface.
func (e *etc) Apply(appl Application) (Etc, error) {
	ec := &etc{
		values: e.values.Copy(),
	}
	for path, value := range appl {
		fullPath := makeFullPath(path)
		_, err := ec.values.Create(fullPath...).SetValue(value)
		if err != nil {
			return nil, errors.Annotate(err, ErrCannotApply, errorMessages)
		}
	}
	return ec, nil
}

// Apply implements the Stringer interface.
func (e *etc) String() string {
	return fmt.Sprintf("%v", e.values)
}

// valueAt retrieves and encapsulates the value
// at a given path.
func (e *etc) valueAt(path string) *value {
	fullPath := makeFullPath(path)
	changer := e.values.At(fullPath...)
	return &value{fullPath, changer}
}

// postProcess replaces templates formated [path||default]
// with values found at that path or the default.
func (e *etc) postProcess() error {
	re := regexp.MustCompile("\\[.+(||.+)\\]")
	// Find all entries with template.
	changers := e.values.FindAll(func(k, v string) (bool, error) {
		return re.MatchString(v), nil
	})
	// Change the template.
	for _, changer := range changers {
		value, err := changer.Value()
		if err != nil {
			return err
		}
		found := re.FindString(value)
		pathDefault := strings.SplitN(found[1:len(found)-1], "||", 2)
		dv := ""
		if len(pathDefault) > 1 {
			dv = pathDefault[1]
		}
		substitute := e.ValueAsString(pathDefault[0], dv)
		replaced := strings.Replace(value, found, substitute, -1)
		_, err =changer.SetValue(replaced)
		if err != nil {
			return err
		}
	}
	return nil
}

//--------------------
// CONTEXT
//--------------------

// NewContext returns a new context that carries a configuration.
func NewContext(ctx context.Context, cfg Etc) context.Context {
	return context.WithValue(ctx, etcKey, cfg)
}

// FromContext returns the configuration stored in ctx, if any.
func FromContext(ctx context.Context) (Etc, bool) {
	cfg, ok := ctx.Value(etcKey).(Etc)
	return cfg, ok
}

//--------------------
// HELPERS
//--------------------

// makeFullPath creates the full path out of a string.
func makeFullPath(path string) []string {
	parts := stringex.SplitMap(path, "/", func(p string) (string, bool) {
		if p == "" {
			return "", false
		}
		return strings.ToLower(p), true
	})
	return append(etcRoot, parts...)
}

// pathToString returns the path in a filesystem like notation.
func pathToString(path []string) string {
	return "/" + strings.Join(path, "/")
}

// EOF
<|endoftext|>


<commit_before>package egoscale

// Version of the library
const Version = "0.13.1"
<commit_msg>prepare release<commit_after>package egoscale

// Version of the library
const Version = "0.13.2"
<|endoftext|>


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

package ach

// Version Number
const Version = "v1.4.0-dev"
<commit_msg>release v1.4.0-rc1<commit_after>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package ach

// Version Number
const Version = "v1.4.0-rc1"
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"strings"
)

// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	appMajor uint = 0
	appMinor uint = 4
	appPatch uint = 0

	// appPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	appPreRelease = "beta"
)

// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild foo' if needed.  It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild string

// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
	// Start with the major, minor, and path versions.
	version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)

	// Append pre-release version if there is one.  The hyphen called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the pre-release string.  The pre-release version
	// is not appended if it contains invalid characters.
	preRelease := normalizeVerString(appPreRelease)
	if preRelease != "" {
		version = fmt.Sprintf("%s-%s", version, preRelease)
	}

	// Append build metadata if there is any.  The plus called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the build metadata string.  The build metadata
	// string is not appended if it contains invalid characters.
	build := normalizeVerString(appBuild)
	if build != "" {
		version = fmt.Sprintf("%s+%s", version, build)
	}

	return version
}

// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings.  In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
	result := bytes.Buffer{}
	for _, r := range str {
		if strings.ContainsRune(semanticAlphabet, r) {
			_, err := result.WriteRune(r)
			// Writing to a bytes.Buffer panics on OOM, and all
			// errors are unexpected.
			if err != nil {
				panic(err)
			}
		}
	}
	return result.String()
}
<commit_msg>Bump for v0.5.0<commit_after>// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"strings"
)

// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	appMajor uint = 0
	appMinor uint = 5
	appPatch uint = 0

	// appPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	appPreRelease = "beta"
)

// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild foo' if needed.  It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild string

// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
	// Start with the major, minor, and path versions.
	version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)

	// Append pre-release version if there is one.  The hyphen called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the pre-release string.  The pre-release version
	// is not appended if it contains invalid characters.
	preRelease := normalizeVerString(appPreRelease)
	if preRelease != "" {
		version = fmt.Sprintf("%s-%s", version, preRelease)
	}

	// Append build metadata if there is any.  The plus called for
	// by the semantic versioning spec is automatically appended and should
	// not be contained in the build metadata string.  The build metadata
	// string is not appended if it contains invalid characters.
	build := normalizeVerString(appBuild)
	if build != "" {
		version = fmt.Sprintf("%s+%s", version, build)
	}

	return version
}

// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings.  In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
	result := bytes.Buffer{}
	for _, r := range str {
		if strings.ContainsRune(semanticAlphabet, r) {
			_, err := result.WriteRune(r)
			// Writing to a bytes.Buffer panics on OOM, and all
			// errors are unexpected.
			if err != nil {
				panic(err)
			}
		}
	}
	return result.String()
}
<|endoftext|>


<commit_before>package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string
var GitDescribe string

// The main version number that is being run at the moment.
const Version = "0.1.2"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = ""
<commit_msg>Update version to 0.2.0-dev<commit_after>package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string
var GitDescribe string

// The main version number that is being run at the moment.
const Version = "0.2.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "dev"
<|endoftext|>


<commit_before>package main

const VERSION = "0.11.0-alpha5"
<commit_msg>:+1: Bump up the version to 0.11.0-alpha6<commit_after>package main

const VERSION = "0.11.0-alpha6"
<|endoftext|>


<commit_before>package bimg

const Version = "0.1.4"
<commit_msg>feat(version): bump<commit_after>package bimg

const Version = "0.1.5"
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

// VersionInfo identifies the version of the TChannel library.
// Due to lack of proper package management, this version string will
// be maintained manually.
const VersionInfo = "1.12.0"
<commit_msg>Back to development<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

// VersionInfo identifies the version of the TChannel library.
// Due to lack of proper package management, this version string will
// be maintained manually.
const VersionInfo = "1.12.0-dev"
<|endoftext|>


<commit_before>package soko

const Version = "0.1.0.rc"
<commit_msg>Bump version to rc2<commit_after>package soko

const Version = "0.1.0.rc2"
<|endoftext|>


<commit_before>package sorg

const (
	// Release is the asset version of the site. Bump when any assets are
	// updated to blow away any browser caches.
	Release = "57"
)
<commit_msg>Bump assets version<commit_after>package sorg

const (
	// Release is the asset version of the site. Bump when any assets are
	// updated to blow away any browser caches.
	Release = "58"
)
<|endoftext|>