<commit_before>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge 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.

// Gauge 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 Gauge.  If not, see <http://www.gnu.org/licenses/>.

package version

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

// CurrentGaugeVersion represents the current version of Gauge
var CurrentGaugeVersion = &Version{0, 8, 5}

// BuildMetadata represents build information of current release (e.g, nightly build information)
var BuildMetadata = ""

type Version struct {
	Major int
	Minor int
	Patch int
}

type VersionSupport struct {
	Minimum string
	Maximum string
}

func ParseVersion(versionText string) (*Version, error) {
	splits := strings.Split(versionText, ".")
	if len(splits) != 3 {
		return nil, fmt.Errorf("Incorrect Version format. Version should be in the form 1.5.7")
	}
	Major, err := strconv.Atoi(splits[0])
	if err != nil {
		return nil, VersionError("major", splits[0], err)
	}
	Minor, err := strconv.Atoi(splits[1])
	if err != nil {
		return nil, VersionError("minor", splits[1], err)
	}
	Patch, err := strconv.Atoi(splits[2])
	if err != nil {
		return nil, VersionError("patch", splits[2], err)
	}

	return &Version{Major, Minor, Patch}, nil
}

func VersionError(level, text string, err error) error {
	return fmt.Errorf("Error parsing %s Version %s to integer. %s", level, text, err.Error())
}

func (Version *Version) IsBetween(lower *Version, greater *Version) bool {
	return Version.IsGreaterThanEqualTo(lower) && Version.IsLesserThanEqualTo(greater)
}

func (Version *Version) IsLesserThan(version1 *Version) bool {
	return CompareVersions(Version, version1, LesserThanFunc)
}

func (Version *Version) IsGreaterThan(version1 *Version) bool {
	return CompareVersions(Version, version1, GreaterThanFunc)
}

func (Version *Version) IsLesserThanEqualTo(version1 *Version) bool {
	return Version.IsLesserThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsGreaterThanEqualTo(version1 *Version) bool {
	return Version.IsGreaterThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsEqualTo(version1 *Version) bool {
	return IsEqual(Version.Major, version1.Major) && IsEqual(Version.Minor, version1.Minor) && IsEqual(Version.Patch, version1.Patch)
}

func CompareVersions(first *Version, second *Version, compareFunc func(int, int) bool) bool {
	if compareFunc(first.Major, second.Major) {
		return true
	} else if IsEqual(first.Major, second.Major) {
		if compareFunc(first.Minor, second.Minor) {
			return true
		} else if IsEqual(first.Minor, second.Minor) {
			if compareFunc(first.Patch, second.Patch) {
				return true
			}
			return false
		}
	}
	return false
}

func LesserThanFunc(first, second int) bool {
	return first < second
}

func GreaterThanFunc(first, second int) bool {
	return first > second
}

func IsEqual(first, second int) bool {
	return first == second
}

func (Version *Version) String() string {
	return fmt.Sprintf("%d.%d.%d", Version.Major, Version.Minor, Version.Patch)
}

// FullVersion returns the CurrentGaugeVersion including build metadata.
func FullVersion() string {
	var metadata string
	if BuildMetadata != "" {
		metadata = fmt.Sprintf(".%s", BuildMetadata)
	}
	return fmt.Sprintf("%s%s", CurrentGaugeVersion.String(), metadata)
}

type byDecreasingVersion []*Version

func (a byDecreasingVersion) Len() int      { return len(a) }
func (a byDecreasingVersion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byDecreasingVersion) Less(i, j int) bool {
	return a[i].IsGreaterThan(a[j])
}

func GetLatestVersion(versions []*Version) *Version {
	sort.Sort(byDecreasingVersion(versions))
	return versions[0]
}

func CheckCompatibility(currentVersion *Version, versionSupport *VersionSupport) error {
	minSupportVersion, err := ParseVersion(versionSupport.Minimum)
	if err != nil {
		return fmt.Errorf("Invalid minimum support version %s. : %s. ", versionSupport.Minimum, err.Error())
	}
	if versionSupport.Maximum != "" {
		maxSupportVersion, err := ParseVersion(versionSupport.Maximum)
		if err != nil {
			return fmt.Errorf("Invalid maximum support version %s. : %s. ", versionSupport.Maximum, err.Error())
		}
		if currentVersion.IsBetween(minSupportVersion, maxSupportVersion) {
			return nil
		}
		return fmt.Errorf("Version %s is not between %s and %s", currentVersion, minSupportVersion, maxSupportVersion)
	}

	if minSupportVersion.IsLesserThanEqualTo(currentVersion) {
		return nil
	}
	return fmt.Errorf("Incompatible version. Minimum support version %s is higher than current version %s", minSupportVersion, currentVersion)
}
<commit_msg>bumping version -> 0.8.6<commit_after>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge 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.

// Gauge 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 Gauge.  If not, see <http://www.gnu.org/licenses/>.

package version

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

// CurrentGaugeVersion represents the current version of Gauge
var CurrentGaugeVersion = &Version{0, 8, 6}

// BuildMetadata represents build information of current release (e.g, nightly build information)
var BuildMetadata = ""

type Version struct {
	Major int
	Minor int
	Patch int
}

type VersionSupport struct {
	Minimum string
	Maximum string
}

func ParseVersion(versionText string) (*Version, error) {
	splits := strings.Split(versionText, ".")
	if len(splits) != 3 {
		return nil, fmt.Errorf("Incorrect Version format. Version should be in the form 1.5.7")
	}
	Major, err := strconv.Atoi(splits[0])
	if err != nil {
		return nil, VersionError("major", splits[0], err)
	}
	Minor, err := strconv.Atoi(splits[1])
	if err != nil {
		return nil, VersionError("minor", splits[1], err)
	}
	Patch, err := strconv.Atoi(splits[2])
	if err != nil {
		return nil, VersionError("patch", splits[2], err)
	}

	return &Version{Major, Minor, Patch}, nil
}

func VersionError(level, text string, err error) error {
	return fmt.Errorf("Error parsing %s Version %s to integer. %s", level, text, err.Error())
}

func (Version *Version) IsBetween(lower *Version, greater *Version) bool {
	return Version.IsGreaterThanEqualTo(lower) && Version.IsLesserThanEqualTo(greater)
}

func (Version *Version) IsLesserThan(version1 *Version) bool {
	return CompareVersions(Version, version1, LesserThanFunc)
}

func (Version *Version) IsGreaterThan(version1 *Version) bool {
	return CompareVersions(Version, version1, GreaterThanFunc)
}

func (Version *Version) IsLesserThanEqualTo(version1 *Version) bool {
	return Version.IsLesserThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsGreaterThanEqualTo(version1 *Version) bool {
	return Version.IsGreaterThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsEqualTo(version1 *Version) bool {
	return IsEqual(Version.Major, version1.Major) && IsEqual(Version.Minor, version1.Minor) && IsEqual(Version.Patch, version1.Patch)
}

func CompareVersions(first *Version, second *Version, compareFunc func(int, int) bool) bool {
	if compareFunc(first.Major, second.Major) {
		return true
	} else if IsEqual(first.Major, second.Major) {
		if compareFunc(first.Minor, second.Minor) {
			return true
		} else if IsEqual(first.Minor, second.Minor) {
			if compareFunc(first.Patch, second.Patch) {
				return true
			}
			return false
		}
	}
	return false
}

func LesserThanFunc(first, second int) bool {
	return first < second
}

func GreaterThanFunc(first, second int) bool {
	return first > second
}

func IsEqual(first, second int) bool {
	return first == second
}

func (Version *Version) String() string {
	return fmt.Sprintf("%d.%d.%d", Version.Major, Version.Minor, Version.Patch)
}

// FullVersion returns the CurrentGaugeVersion including build metadata.
func FullVersion() string {
	var metadata string
	if BuildMetadata != "" {
		metadata = fmt.Sprintf(".%s", BuildMetadata)
	}
	return fmt.Sprintf("%s%s", CurrentGaugeVersion.String(), metadata)
}

type byDecreasingVersion []*Version

func (a byDecreasingVersion) Len() int      { return len(a) }
func (a byDecreasingVersion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byDecreasingVersion) Less(i, j int) bool {
	return a[i].IsGreaterThan(a[j])
}

func GetLatestVersion(versions []*Version) *Version {
	sort.Sort(byDecreasingVersion(versions))
	return versions[0]
}

func CheckCompatibility(currentVersion *Version, versionSupport *VersionSupport) error {
	minSupportVersion, err := ParseVersion(versionSupport.Minimum)
	if err != nil {
		return fmt.Errorf("Invalid minimum support version %s. : %s. ", versionSupport.Minimum, err.Error())
	}
	if versionSupport.Maximum != "" {
		maxSupportVersion, err := ParseVersion(versionSupport.Maximum)
		if err != nil {
			return fmt.Errorf("Invalid maximum support version %s. : %s. ", versionSupport.Maximum, err.Error())
		}
		if currentVersion.IsBetween(minSupportVersion, maxSupportVersion) {
			return nil
		}
		return fmt.Errorf("Version %s is not between %s and %s", currentVersion, minSupportVersion, maxSupportVersion)
	}

	if minSupportVersion.IsLesserThanEqualTo(currentVersion) {
		return nil
	}
	return fmt.Errorf("Incompatible version. Minimum support version %s is higher than current version %s", minSupportVersion, currentVersion)
}
<|endoftext|>


<commit_before>// The version package implements version parsing.
// It also acts as guardian of the current client Juju version number.
package version

import (
	"fmt"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

// The presence and format of this constant is very important.
// The debian/rules build recipe uses this value for the version
// number of the release package.
const version = "1.9.6"

// Current gives the current version of the system.  If the file
// "FORCE-VERSION" is present in the same directory as the running
// binary, it will override this.
var Current = Binary{
	Number: MustParse(version),
	Series: readSeries("/etc/lsb-release"), // current Ubuntu release name.
	Arch:   ubuntuArch(runtime.GOARCH),
}

func init() {
	toolsDir := filepath.Dir(os.Args[0])
	v, err := ioutil.ReadFile(filepath.Join(toolsDir, "FORCE-VERSION"))
	if err != nil {
		if os.IsNotExist(err) {
			return
		}
		panic(fmt.Errorf("version: cannot read forced version: %v", err))
	}
	Current.Number = MustParse(strings.TrimSpace(string(v)))
}

// Number represents a juju version.  When bugs are fixed the patch
// number is incremented; when new features are added the minor number
// is incremented and patch is reset; and when compatibility is broken
// the major version is incremented and minor and patch are reset.  The
// build number is automatically assigned and has no well defined
// sequence.  If the build number is greater than zero or any of the
// other numbers are odd, it indicates that the release is still in
// development.
type Number struct {
	Major int
	Minor int
	Patch int
	Build int
}

// Binary specifies a binary version of juju.
type Binary struct {
	Number
	Series string
	Arch   string
}

func (v Binary) String() string {
	return fmt.Sprintf("%v-%s-%s", v.Number, v.Series, v.Arch)
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Binary) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Binary) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := ParseBinary(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

var (
	binaryPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$`)
	numberPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?$`)
)

// MustParse parses a version and panics if it does
// not parse correctly.
func MustParse(s string) Number {
	v, err := Parse(s)
	if err != nil {
		panic(err)
	}
	return v
}

// MustParseBinary parses a binary version and panics if it does
// not parse correctly.
func MustParseBinary(s string) Binary {
	v, err := ParseBinary(s)
	if err != nil {
		panic(err)
	}
	return v
}

// ParseBinary parses a binary version of the form "1.2.3-series-arch".
func ParseBinary(s string) (Binary, error) {
	m := binaryPat.FindStringSubmatch(s)
	if m == nil {
		return Binary{}, fmt.Errorf("invalid binary version %q", s)
	}
	var v Binary
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	v.Series = m[5]
	v.Arch = m[6]
	return v, nil
}

// Parse parses the version, which is of the form 1.2.3
// giving the major, minor and release versions
// respectively.
func Parse(s string) (Number, error) {
	m := numberPat.FindStringSubmatch(s)
	if m == nil {
		return Number{}, fmt.Errorf("invalid version %q", s)
	}
	var v Number
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	return v, nil
}

// atoi is the same as strconv.Atoi but assumes that
// the string has been verified to be a valid integer.
func atoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return n
}

func (v Number) String() string {
	s := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	if v.Build > 0 {
		s += fmt.Sprintf(".%d", v.Build)
	}
	return s
}

// Less returns whether v is semantically earlier in the
// version sequence than w.
func (v Number) Less(w Number) bool {
	switch {
	case v.Major != w.Major:
		return v.Major < w.Major
	case v.Minor != w.Minor:
		return v.Minor < w.Minor
	case v.Patch != w.Patch:
		return v.Patch < w.Patch
	case v.Build != w.Build:
		return v.Build < w.Build
	}
	return false
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Number) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Number) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := Parse(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

func isOdd(x int) bool {
	return x%2 != 0
}

// IsDev returns whether the version represents a development
// version. A version with an odd-numbered major, minor
// or patch version is considered to be a development version.
func (v Number) IsDev() bool {
	return isOdd(v.Major) || isOdd(v.Minor) || isOdd(v.Patch) || v.Build > 0
}

func readSeries(releaseFile string) string {
	data, err := ioutil.ReadFile(releaseFile)
	if err != nil {
		return "unknown"
	}
	for _, line := range strings.Split(string(data), "\n") {
		const p = "DISTRIB_CODENAME="
		if strings.HasPrefix(line, p) {
			return strings.Trim(line[len(p):], "\t '\"")
		}
	}
	return "unknown"
}

func ubuntuArch(arch string) string {
	if arch == "386" {
		arch = "i386"
	}
	return arch
}
<commit_msg>set development version to 1.9.7<commit_after>// The version package implements version parsing.
// It also acts as guardian of the current client Juju version number.
package version

import (
	"fmt"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

// The presence and format of this constant is very important.
// The debian/rules build recipe uses this value for the version
// number of the release package.
const version = "1.9.7"

// Current gives the current version of the system.  If the file
// "FORCE-VERSION" is present in the same directory as the running
// binary, it will override this.
var Current = Binary{
	Number: MustParse(version),
	Series: readSeries("/etc/lsb-release"), // current Ubuntu release name.
	Arch:   ubuntuArch(runtime.GOARCH),
}

func init() {
	toolsDir := filepath.Dir(os.Args[0])
	v, err := ioutil.ReadFile(filepath.Join(toolsDir, "FORCE-VERSION"))
	if err != nil {
		if os.IsNotExist(err) {
			return
		}
		panic(fmt.Errorf("version: cannot read forced version: %v", err))
	}
	Current.Number = MustParse(strings.TrimSpace(string(v)))
}

// Number represents a juju version.  When bugs are fixed the patch
// number is incremented; when new features are added the minor number
// is incremented and patch is reset; and when compatibility is broken
// the major version is incremented and minor and patch are reset.  The
// build number is automatically assigned and has no well defined
// sequence.  If the build number is greater than zero or any of the
// other numbers are odd, it indicates that the release is still in
// development.
type Number struct {
	Major int
	Minor int
	Patch int
	Build int
}

// Binary specifies a binary version of juju.
type Binary struct {
	Number
	Series string
	Arch   string
}

func (v Binary) String() string {
	return fmt.Sprintf("%v-%s-%s", v.Number, v.Series, v.Arch)
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Binary) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Binary) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := ParseBinary(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

var (
	binaryPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$`)
	numberPat = regexp.MustCompile(`^(\d{1,9})\.(\d{1,9})\.(\d{1,9})(\.\d{1,9})?$`)
)

// MustParse parses a version and panics if it does
// not parse correctly.
func MustParse(s string) Number {
	v, err := Parse(s)
	if err != nil {
		panic(err)
	}
	return v
}

// MustParseBinary parses a binary version and panics if it does
// not parse correctly.
func MustParseBinary(s string) Binary {
	v, err := ParseBinary(s)
	if err != nil {
		panic(err)
	}
	return v
}

// ParseBinary parses a binary version of the form "1.2.3-series-arch".
func ParseBinary(s string) (Binary, error) {
	m := binaryPat.FindStringSubmatch(s)
	if m == nil {
		return Binary{}, fmt.Errorf("invalid binary version %q", s)
	}
	var v Binary
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	v.Series = m[5]
	v.Arch = m[6]
	return v, nil
}

// Parse parses the version, which is of the form 1.2.3
// giving the major, minor and release versions
// respectively.
func Parse(s string) (Number, error) {
	m := numberPat.FindStringSubmatch(s)
	if m == nil {
		return Number{}, fmt.Errorf("invalid version %q", s)
	}
	var v Number
	v.Major = atoi(m[1])
	v.Minor = atoi(m[2])
	v.Patch = atoi(m[3])
	if m[4] != "" {
		v.Build = atoi(m[4][1:])
	}
	return v, nil
}

// atoi is the same as strconv.Atoi but assumes that
// the string has been verified to be a valid integer.
func atoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	return n
}

func (v Number) String() string {
	s := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	if v.Build > 0 {
		s += fmt.Sprintf(".%d", v.Build)
	}
	return s
}

// Less returns whether v is semantically earlier in the
// version sequence than w.
func (v Number) Less(w Number) bool {
	switch {
	case v.Major != w.Major:
		return v.Major < w.Major
	case v.Minor != w.Minor:
		return v.Minor < w.Minor
	case v.Patch != w.Patch:
		return v.Patch < w.Patch
	case v.Build != w.Build:
		return v.Build < w.Build
	}
	return false
}

// GetBSON turns v into a bson.Getter so it can be saved directly
// on a MongoDB database with mgo.
func (v Number) GetBSON() (interface{}, error) {
	return v.String(), nil
}

// SetBSON turns v into a bson.Setter so it can be loaded directly
// from a MongoDB database with mgo.
func (vp *Number) SetBSON(raw bson.Raw) error {
	var s string
	err := raw.Unmarshal(&s)
	if err != nil {
		return err
	}
	v, err := Parse(s)
	if err != nil {
		return err
	}
	*vp = v
	return nil
}

func isOdd(x int) bool {
	return x%2 != 0
}

// IsDev returns whether the version represents a development
// version. A version with an odd-numbered major, minor
// or patch version is considered to be a development version.
func (v Number) IsDev() bool {
	return isOdd(v.Major) || isOdd(v.Minor) || isOdd(v.Patch) || v.Build > 0
}

func readSeries(releaseFile string) string {
	data, err := ioutil.ReadFile(releaseFile)
	if err != nil {
		return "unknown"
	}
	for _, line := range strings.Split(string(data), "\n") {
		const p = "DISTRIB_CODENAME="
		if strings.HasPrefix(line, p) {
			return strings.Trim(line[len(p):], "\t '\"")
		}
	}
	return "unknown"
}

func ubuntuArch(arch string) string {
	if arch == "386" {
		arch = "i386"
	}
	return arch
}
<|endoftext|>


<commit_before>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge 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.

// Gauge 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 Gauge.  If not, see <http://www.gnu.org/licenses/>.

package version

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

// CurrentGaugeVersion represents the current version of Gauge
var CurrentGaugeVersion = &Version{0, 9, 1}

// BuildMetadata represents build information of current release (e.g, nightly build information)
var BuildMetadata = ""

type Version struct {
	Major int
	Minor int
	Patch int
}

type VersionSupport struct {
	Minimum string
	Maximum string
}

func ParseVersion(versionText string) (*Version, error) {
	splits := strings.Split(versionText, ".")
	if len(splits) != 3 {
		return nil, fmt.Errorf("Incorrect Version format. Version should be in the form 1.5.7")
	}
	Major, err := strconv.Atoi(splits[0])
	if err != nil {
		return nil, VersionError("major", splits[0], err)
	}
	Minor, err := strconv.Atoi(splits[1])
	if err != nil {
		return nil, VersionError("minor", splits[1], err)
	}
	Patch, err := strconv.Atoi(splits[2])
	if err != nil {
		return nil, VersionError("patch", splits[2], err)
	}

	return &Version{Major, Minor, Patch}, nil
}

func VersionError(level, text string, err error) error {
	return fmt.Errorf("Error parsing %s Version %s to integer. %s", level, text, err.Error())
}

func (Version *Version) IsBetween(lower *Version, greater *Version) bool {
	return Version.IsGreaterThanEqualTo(lower) && Version.IsLesserThanEqualTo(greater)
}

func (Version *Version) IsLesserThan(version1 *Version) bool {
	return CompareVersions(Version, version1, LesserThanFunc)
}

func (Version *Version) IsGreaterThan(version1 *Version) bool {
	return CompareVersions(Version, version1, GreaterThanFunc)
}

func (Version *Version) IsLesserThanEqualTo(version1 *Version) bool {
	return Version.IsLesserThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsGreaterThanEqualTo(version1 *Version) bool {
	return Version.IsGreaterThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsEqualTo(version1 *Version) bool {
	return IsEqual(Version.Major, version1.Major) && IsEqual(Version.Minor, version1.Minor) && IsEqual(Version.Patch, version1.Patch)
}

func CompareVersions(first *Version, second *Version, compareFunc func(int, int) bool) bool {
	if compareFunc(first.Major, second.Major) {
		return true
	} else if IsEqual(first.Major, second.Major) {
		if compareFunc(first.Minor, second.Minor) {
			return true
		} else if IsEqual(first.Minor, second.Minor) {
			if compareFunc(first.Patch, second.Patch) {
				return true
			}
			return false
		}
	}
	return false
}

func LesserThanFunc(first, second int) bool {
	return first < second
}

func GreaterThanFunc(first, second int) bool {
	return first > second
}

func IsEqual(first, second int) bool {
	return first == second
}

func (Version *Version) String() string {
	return fmt.Sprintf("%d.%d.%d", Version.Major, Version.Minor, Version.Patch)
}

// FullVersion returns the CurrentGaugeVersion including build metadata.
func FullVersion() string {
	var metadata string
	if BuildMetadata != "" {
		metadata = fmt.Sprintf(".%s", BuildMetadata)
	}
	return fmt.Sprintf("%s%s", CurrentGaugeVersion.String(), metadata)
}

type byDecreasingVersion []*Version

func (a byDecreasingVersion) Len() int      { return len(a) }
func (a byDecreasingVersion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byDecreasingVersion) Less(i, j int) bool {
	return a[i].IsGreaterThan(a[j])
}

func GetLatestVersion(versions []*Version) *Version {
	sort.Sort(byDecreasingVersion(versions))
	return versions[0]
}

func CheckCompatibility(currentVersion *Version, versionSupport *VersionSupport) error {
	minSupportVersion, err := ParseVersion(versionSupport.Minimum)
	if err != nil {
		return fmt.Errorf("Invalid minimum support version %s. : %s. ", versionSupport.Minimum, err.Error())
	}
	if versionSupport.Maximum != "" {
		maxSupportVersion, err := ParseVersion(versionSupport.Maximum)
		if err != nil {
			return fmt.Errorf("Invalid maximum support version %s. : %s. ", versionSupport.Maximum, err.Error())
		}
		if currentVersion.IsBetween(minSupportVersion, maxSupportVersion) {
			return nil
		}
		return fmt.Errorf("Version %s is not between %s and %s", currentVersion, minSupportVersion, maxSupportVersion)
	}

	if minSupportVersion.IsLesserThanEqualTo(currentVersion) {
		return nil
	}
	return fmt.Errorf("Incompatible version. Minimum support version %s is higher than current version %s", minSupportVersion, currentVersion)
}
<commit_msg>bump up version to 0.9.2<commit_after>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge 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.

// Gauge 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 Gauge.  If not, see <http://www.gnu.org/licenses/>.

package version

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

// CurrentGaugeVersion represents the current version of Gauge
var CurrentGaugeVersion = &Version{0, 9, 2}

// BuildMetadata represents build information of current release (e.g, nightly build information)
var BuildMetadata = ""

type Version struct {
	Major int
	Minor int
	Patch int
}

type VersionSupport struct {
	Minimum string
	Maximum string
}

func ParseVersion(versionText string) (*Version, error) {
	splits := strings.Split(versionText, ".")
	if len(splits) != 3 {
		return nil, fmt.Errorf("Incorrect Version format. Version should be in the form 1.5.7")
	}
	Major, err := strconv.Atoi(splits[0])
	if err != nil {
		return nil, VersionError("major", splits[0], err)
	}
	Minor, err := strconv.Atoi(splits[1])
	if err != nil {
		return nil, VersionError("minor", splits[1], err)
	}
	Patch, err := strconv.Atoi(splits[2])
	if err != nil {
		return nil, VersionError("patch", splits[2], err)
	}

	return &Version{Major, Minor, Patch}, nil
}

func VersionError(level, text string, err error) error {
	return fmt.Errorf("Error parsing %s Version %s to integer. %s", level, text, err.Error())
}

func (Version *Version) IsBetween(lower *Version, greater *Version) bool {
	return Version.IsGreaterThanEqualTo(lower) && Version.IsLesserThanEqualTo(greater)
}

func (Version *Version) IsLesserThan(version1 *Version) bool {
	return CompareVersions(Version, version1, LesserThanFunc)
}

func (Version *Version) IsGreaterThan(version1 *Version) bool {
	return CompareVersions(Version, version1, GreaterThanFunc)
}

func (Version *Version) IsLesserThanEqualTo(version1 *Version) bool {
	return Version.IsLesserThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsGreaterThanEqualTo(version1 *Version) bool {
	return Version.IsGreaterThan(version1) || Version.IsEqualTo(version1)
}

func (Version *Version) IsEqualTo(version1 *Version) bool {
	return IsEqual(Version.Major, version1.Major) && IsEqual(Version.Minor, version1.Minor) && IsEqual(Version.Patch, version1.Patch)
}

func CompareVersions(first *Version, second *Version, compareFunc func(int, int) bool) bool {
	if compareFunc(first.Major, second.Major) {
		return true
	} else if IsEqual(first.Major, second.Major) {
		if compareFunc(first.Minor, second.Minor) {
			return true
		} else if IsEqual(first.Minor, second.Minor) {
			if compareFunc(first.Patch, second.Patch) {
				return true
			}
			return false
		}
	}
	return false
}

func LesserThanFunc(first, second int) bool {
	return first < second
}

func GreaterThanFunc(first, second int) bool {
	return first > second
}

func IsEqual(first, second int) bool {
	return first == second
}

func (Version *Version) String() string {
	return fmt.Sprintf("%d.%d.%d", Version.Major, Version.Minor, Version.Patch)
}

// FullVersion returns the CurrentGaugeVersion including build metadata.
func FullVersion() string {
	var metadata string
	if BuildMetadata != "" {
		metadata = fmt.Sprintf(".%s", BuildMetadata)
	}
	return fmt.Sprintf("%s%s", CurrentGaugeVersion.String(), metadata)
}

type byDecreasingVersion []*Version

func (a byDecreasingVersion) Len() int      { return len(a) }
func (a byDecreasingVersion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byDecreasingVersion) Less(i, j int) bool {
	return a[i].IsGreaterThan(a[j])
}

func GetLatestVersion(versions []*Version) *Version {
	sort.Sort(byDecreasingVersion(versions))
	return versions[0]
}

func CheckCompatibility(currentVersion *Version, versionSupport *VersionSupport) error {
	minSupportVersion, err := ParseVersion(versionSupport.Minimum)
	if err != nil {
		return fmt.Errorf("Invalid minimum support version %s. : %s. ", versionSupport.Minimum, err.Error())
	}
	if versionSupport.Maximum != "" {
		maxSupportVersion, err := ParseVersion(versionSupport.Maximum)
		if err != nil {
			return fmt.Errorf("Invalid maximum support version %s. : %s. ", versionSupport.Maximum, err.Error())
		}
		if currentVersion.IsBetween(minSupportVersion, maxSupportVersion) {
			return nil
		}
		return fmt.Errorf("Version %s is not between %s and %s", currentVersion, minSupportVersion, maxSupportVersion)
	}

	if minSupportVersion.IsLesserThanEqualTo(currentVersion) {
		return nil
	}
	return fmt.Errorf("Incompatible version. Minimum support version %s is higher than current version %s", minSupportVersion, currentVersion)
}
<|endoftext|>


<commit_before>package version

// Version is the version of the build.
const Version = "0.1.30"
<commit_msg>version: bump v0.1.31-dev<commit_after>package version

// Version is the version of the build.
const Version = "0.1.31-dev"
<|endoftext|>


<commit_before><commit_msg>fix names: s/fd/r/<commit_after><|endoftext|>


<commit_before><commit_msg>typo fix. release version<commit_after><|endoftext|>


<commit_before><commit_msg>Import net/http/httputil/reverseproxy from Go code base<commit_after><|endoftext|>


<commit_before>package main

import "fmt"

func main() {

	marry := human{"marry"}
	//marry := &human{"marry"}
	Speak(marry)
}

type Speaker interface {
	speak() string
}

type human struct {
	Name string
}

func (h *human) speak() string {
	return fmt.Sprintf("my name is %s\n", h.Name)
}

func Speak(s Speaker) {
	fmt.Println(s.speak())
}
<commit_msg>delete main<commit_after><|endoftext|>


<commit_before>package vmware

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// Player5LinuxDriver is a driver that can run VMware Player 5 on Linux.
type Player5LinuxDriver struct {
	AppPath          string
	VdiskManagerPath string
	QemuImgPath      string
	VmrunPath        string
}

func (d *Player5LinuxDriver) CompactDisk(diskPath string) error {
	if d.QemuImgPath != "" {
		return d.qemuCompactDisk(diskPath)
	}

	defragCmd := exec.Command(d.VdiskManagerPath, "-d", diskPath)
	if _, _, err := runAndLog(defragCmd); err != nil {
		return err
	}

	shrinkCmd := exec.Command(d.VdiskManagerPath, "-k", diskPath)
	if _, _, err := runAndLog(shrinkCmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) qemuCompactDisk(diskPath string) error {
	cmd := exec.Command(d.QemuImgPath, "convert", "-f", "vmdk", "-O", "vmdk", "-o", "compat6", diskPath, diskPath+".new")
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	if err := os.Remove(diskPath); err != nil {
		return err
	}

	if err := os.Rename(diskPath+".new", diskPath); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) CreateDisk(output string, size string) error {
	var cmd *exec.Cmd
	if d.QemuImgPath != "" {
		cmd = exec.Command(d.QemuImgPath, "create", "-f", "vmdk", "-o", "compat6", output, size)
	} else {
		cmd = exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", "lsilogic", "-t", "1", output)
	}
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) IsRunning(vmxPath string) (bool, error) {
	vmxPath, err := filepath.Abs(vmxPath)
	if err != nil {
		return false, err
	}

	cmd := exec.Command(d.VmrunPath, "-T", "player", "list")
	stdout, _, err := runAndLog(cmd)
	if err != nil {
		return false, err
	}

	for _, line := range strings.Split(stdout, "\n") {
		if line == vmxPath {
			return true, nil
		}
	}

	return false, nil
}

func (d *Player5LinuxDriver) Start(vmxPath string, headless bool) error {
	guiArgument := "gui"
	if headless {
		guiArgument = "nogui"
	}

	cmd := exec.Command(d.VmrunPath, "-T", "player", "start", vmxPath, guiArgument)
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) Stop(vmxPath string) error {
	cmd := exec.Command(d.VmrunPath, "-T", "player", "stop", vmxPath, "hard")
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) Verify() error {
	if err := d.findApp(); err != nil {
		return fmt.Errorf("VMware Player application ('vmplayer') not found in path.")
	}

	if err := d.findVmrun(); err != nil {
		return fmt.Errorf("Critical application 'vmrun' not found in path.")
	}

	if err := d.findVdiskManager(); err != nil {
		if err := d.findQemuImg(); err != nil {
			return fmt.Errorf("Neither 'vmware-vdiskmanager', not 'qemu-img' found in path.")
		}
	}

	return nil
}

func (d *Player5LinuxDriver) findApp() error {
	path, err := exec.LookPath("vmplayer")
	if err != nil {
		return err
	}
	d.AppPath = path
	return nil
}

func (d *Player5LinuxDriver) findVdiskManager() error {
	path, err := exec.LookPath("vmware-vdiskmanager")
	if err != nil {
		return err
	}
	d.VdiskManagerPath = path
	return nil
}

func (d *Player5LinuxDriver) findQemuImg() error {
	path, err := exec.LookPath("qemu-img")
	if err != nil {
		return err
	}
	d.QemuImgPath = path
	return nil
}

func (d *Player5LinuxDriver) findVmrun() error {
	path, err := exec.LookPath("vmrun")
	if err != nil {
		return err
	}
	d.VmrunPath = path
	return nil
}

func (d *Player5LinuxDriver) ToolsIsoPath(flavor string) string {
	return "/usr/lib/vmware/isoimages/" + flavor + ".iso"
}

func (d *Player5LinuxDriver) DhcpLeasesPath(device string) string {
	return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases"
}
<commit_msg>builder/vmware: error message tweaking for Player driver<commit_after>package vmware

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// Player5LinuxDriver is a driver that can run VMware Player 5 on Linux.
type Player5LinuxDriver struct {
	AppPath          string
	VdiskManagerPath string
	QemuImgPath      string
	VmrunPath        string
}

func (d *Player5LinuxDriver) CompactDisk(diskPath string) error {
	if d.QemuImgPath != "" {
		return d.qemuCompactDisk(diskPath)
	}

	defragCmd := exec.Command(d.VdiskManagerPath, "-d", diskPath)
	if _, _, err := runAndLog(defragCmd); err != nil {
		return err
	}

	shrinkCmd := exec.Command(d.VdiskManagerPath, "-k", diskPath)
	if _, _, err := runAndLog(shrinkCmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) qemuCompactDisk(diskPath string) error {
	cmd := exec.Command(d.QemuImgPath, "convert", "-f", "vmdk", "-O", "vmdk", "-o", "compat6", diskPath, diskPath+".new")
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	if err := os.Remove(diskPath); err != nil {
		return err
	}

	if err := os.Rename(diskPath+".new", diskPath); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) CreateDisk(output string, size string) error {
	var cmd *exec.Cmd
	if d.QemuImgPath != "" {
		cmd = exec.Command(d.QemuImgPath, "create", "-f", "vmdk", "-o", "compat6", output, size)
	} else {
		cmd = exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", "lsilogic", "-t", "1", output)
	}
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) IsRunning(vmxPath string) (bool, error) {
	vmxPath, err := filepath.Abs(vmxPath)
	if err != nil {
		return false, err
	}

	cmd := exec.Command(d.VmrunPath, "-T", "player", "list")
	stdout, _, err := runAndLog(cmd)
	if err != nil {
		return false, err
	}

	for _, line := range strings.Split(stdout, "\n") {
		if line == vmxPath {
			return true, nil
		}
	}

	return false, nil
}

func (d *Player5LinuxDriver) Start(vmxPath string, headless bool) error {
	guiArgument := "gui"
	if headless {
		guiArgument = "nogui"
	}

	cmd := exec.Command(d.VmrunPath, "-T", "player", "start", vmxPath, guiArgument)
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) Stop(vmxPath string) error {
	cmd := exec.Command(d.VmrunPath, "-T", "player", "stop", vmxPath, "hard")
	if _, _, err := runAndLog(cmd); err != nil {
		return err
	}

	return nil
}

func (d *Player5LinuxDriver) Verify() error {
	if err := d.findApp(); err != nil {
		return fmt.Errorf("VMware Player application ('vmplayer') not found in path.")
	}

	if err := d.findVmrun(); err != nil {
		return fmt.Errorf("Critical application 'vmrun' not found in path.")
	}

	if err := d.findVdiskManager(); err != nil {
		if err := d.findQemuImg(); err != nil {
			return fmt.Errorf(
				"Neither 'vmware-vdiskmanager', nor 'qemu-img' found in path.\n" +
					"One of these is required to configure disks for VMware Player.")
		}
	}

	return nil
}

func (d *Player5LinuxDriver) findApp() error {
	path, err := exec.LookPath("vmplayer")
	if err != nil {
		return err
	}
	d.AppPath = path
	return nil
}

func (d *Player5LinuxDriver) findVdiskManager() error {
	path, err := exec.LookPath("vmware-vdiskmanager")
	if err != nil {
		return err
	}
	d.VdiskManagerPath = path
	return nil
}

func (d *Player5LinuxDriver) findQemuImg() error {
	path, err := exec.LookPath("qemu-img")
	if err != nil {
		return err
	}
	d.QemuImgPath = path
	return nil
}

func (d *Player5LinuxDriver) findVmrun() error {
	path, err := exec.LookPath("vmrun")
	if err != nil {
		return err
	}
	d.VmrunPath = path
	return nil
}

func (d *Player5LinuxDriver) ToolsIsoPath(flavor string) string {
	return "/usr/lib/vmware/isoimages/" + flavor + ".iso"
}

func (d *Player5LinuxDriver) DhcpLeasesPath(device string) string {
	return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases"
}
<|endoftext|>


<commit_before>package vmware

import (
	"fmt"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/packer"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

// This step cleans up the VMX by removing or changing this prior to
// being ready for use.
//
// Uses:
//   ui     packer.Ui
//   vmx_path string
//
// Produces:
//   <nothing>
type stepCleanVMX struct{}

func (s stepCleanVMX) Run(state map[string]interface{}) multistep.StepAction {
	if _, ok := state["floppy_path"]; !ok {
		return multistep.ActionContinue
	}

	ui := state["ui"].(packer.Ui)
	vmxPath := state["vmx_path"].(string)

	vmxData, err := s.readVMX(vmxPath)
	if err != nil {
		state["error"] = fmt.Errorf("Error reading VMX: %s", err)
		return multistep.ActionHalt
	}

	// Delete the floppy0 entries so the floppy is no longer mounted
	ui.Say("Unmounting floppy from VMX...")
	for k, _ := range vmxData {
		if strings.HasPrefix(k, "floppy0.") {
			log.Printf("Deleting key: %s", k)
			delete(vmxData, k)
		}
	}
	vmxData["floppy0.present"] = "FALSE"

	// Rewrite the VMX
	if err := WriteVMX(vmxPath, vmxData); err != nil {
		state["error"] = fmt.Errorf("Error writing VMX: %s", err)
		return multistep.ActionHalt
	}

	return multistep.ActionContinue
}

func (stepCleanVMX) Cleanup(map[string]interface{}) {}

func (stepCleanVMX) readVMX(vmxPath string) (map[string]string, error) {
	vmxF, err := os.Open(vmxPath)
	if err != nil {
		return nil, err
	}
	defer vmxF.Close()

	vmxBytes, err := ioutil.ReadAll(vmxF)
	if err != nil {
		return nil, err
	}

	return ParseVMX(string(vmxBytes)), nil
}
<commit_msg>Remove ISO from ide1 in stepCleanVMX<commit_after>package vmware

import (
	"fmt"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/packer"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

// This step cleans up the VMX by removing or changing this prior to
// being ready for use.
//
// Uses:
//   ui     packer.Ui
//   vmx_path string
//
// Produces:
//   <nothing>
type stepCleanVMX struct{}

func (s stepCleanVMX) Run(state map[string]interface{}) multistep.StepAction {

	ui := state["ui"].(packer.Ui)
	vmxPath := state["vmx_path"].(string)

	vmxData, err := s.readVMX(vmxPath)
	if err != nil {
		state["error"] = fmt.Errorf("Error reading VMX: %s", err)
		return multistep.ActionHalt
	}

	if _, ok := state["floppy_path"]; ok {
		// Delete the floppy0 entries so the floppy is no longer mounted
		ui.Say("Unmounting floppy from VMX...")
		for k, _ := range vmxData {
			if strings.HasPrefix(k, "floppy0.") {
				log.Printf("Deleting key: %s", k)
				delete(vmxData, k)
			}
		}
		vmxData["floppy0.present"] = "FALSE"
	}

	// Change the CD-ROM device back to auto-detect, ejecting the iso
	ui.Say("Detatching ISO from CD-ROM device...")
	vmxData["ide1:0.fileName"] = "auto detect"
	vmxData["ide1:0.deviceType"] = "cdrom-raw"

	// Rewrite the VMX
	if err := WriteVMX(vmxPath, vmxData); err != nil {
		state["error"] = fmt.Errorf("Error writing VMX: %s", err)
		return multistep.ActionHalt
	}

	return multistep.ActionContinue
}

func (stepCleanVMX) Cleanup(map[string]interface{}) {}

func (stepCleanVMX) readVMX(vmxPath string) (map[string]string, error) {
	vmxF, err := os.Open(vmxPath)
	if err != nil {
		return nil, err
	}
	defer vmxF.Close()

	vmxBytes, err := ioutil.ReadAll(vmxF)
	if err != nil {
		return nil, err
	}

	return ParseVMX(string(vmxBytes)), nil
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"
	"os/exec"
	"reflect"

	"github.com/gobuffalo/buffalo/meta"
	"github.com/gobuffalo/buffalo/runtime"
	"github.com/gobuffalo/envy"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

// infoCmd represents the info command
var infoCmd = &cobra.Command{
	Use:   "info",
	Short: "Prints off diagnostic information useful for debugging.",
	RunE: func(cmd *cobra.Command, args []string) error {
		bb := os.Stdout

		bb.WriteString(fmt.Sprintf("### Buffalo Version\n%s\n", runtime.Version))

		bb.WriteString("\n### App Information\n")
		app := meta.New(".")
		rv := reflect.ValueOf(app)
		rt := rv.Type()

		for i := 0; i < rt.NumField(); i++ {
			f := rt.Field(i)
			bb.WriteString(fmt.Sprintf("%s=%v\n", f.Name, rv.FieldByName(f.Name).Interface()))
		}

		return runInfoCmds()
	},
}

type infoCommand struct {
	Name      string
	PathName  string
	Cmd       *exec.Cmd
	InfoLabel string
}

func runInfoCmds() error {

	commands := []infoCommand{
		{"Go", envy.Get("GO_BIN", "go"), exec.Command(envy.Get("GO_BIN", "go"), "version"), "\n### Go Version\n"},
		{"Go", envy.Get("GO_BIN", "go"), exec.Command(envy.Get("GO_BIN", "go"), "env"), "\n### Go Env\n"},
		{"Node", "node", exec.Command("node", "--version"), "\n### Node Version\n"},
		{"NPM", "npm", exec.Command("npm", "--version"), "\n### NPM Version\n"},
		{"Yarn", "yarn", exec.Command("yarn", "--version"), "\n### Yarn Version\n"},
		{"PostgreSQL", "pg_ctl", exec.Command("pg_ctl", "--version"), "\n### PostgreSQL Version\n"},
		{"MySQL", "mysql", exec.Command("mysql", "--version"), "\n### MySQL Version\n"},
		{"SQLite", "sqlite3", exec.Command("sqlite3", "--version"), "\n### SQLite Version\n"},
		{"dep", "dep", exec.Command("dep", "version"), "\n### Dep Version\n"},
		{"dep", "dep", exec.Command("dep", "status"), "\n### Dep Status\n"},
	}

	for _, cmd := range commands {
		err := execIfExists(cmd)
		if err != nil {
			return errors.WithStack(err)
		}
	}

	return nil
}

func execIfExists(infoCmd infoCommand) error {
	bb := os.Stdout
	bb.WriteString(infoCmd.InfoLabel)

	if infoCmd.Name == "dep" {
		if _, err := os.Stat("Gopkg.toml"); err != nil {
			bb.WriteString("could not find a Gopkg.toml file\n")
			return nil
		}
	}

	if _, err := exec.LookPath(infoCmd.PathName); err != nil {
		bb.WriteString(fmt.Sprintf("%s Not Found\n", infoCmd.Name))
		return nil
	}

	infoCmd.Cmd.Stdout = bb
	infoCmd.Cmd.Stderr = bb

	err := infoCmd.Cmd.Run()
	return err
}

func init() {
	decorate("info", RootCmd)
	RootCmd.AddCommand(infoCmd)
}
<commit_msg>Always display the version of pop/plush/other libraries used sort of (#1194)<commit_after>package cmd

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"reflect"

	"github.com/gobuffalo/buffalo/meta"
	"github.com/gobuffalo/buffalo/runtime"
	"github.com/gobuffalo/envy"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

// infoCmd represents the info command
var infoCmd = &cobra.Command{
	Use:   "info",
	Short: "Prints off diagnostic information useful for debugging.",
	RunE: func(cmd *cobra.Command, args []string) error {
		bb := os.Stdout

		bb.WriteString(fmt.Sprintf("### Buffalo Version\n%s\n", runtime.Version))

		bb.WriteString("\n### App Information\n")
		app := meta.New(".")
		rv := reflect.ValueOf(app)
		rt := rv.Type()

		for i := 0; i < rt.NumField(); i++ {
			f := rt.Field(i)
			bb.WriteString(fmt.Sprintf("%s=%v\n", f.Name, rv.FieldByName(f.Name).Interface()))
		}

		if err := runInfoCmds(); err != nil {
			return errors.WithStack(err)
		}
		return infoGoMod()
	},
}

type infoCommand struct {
	Name      string
	PathName  string
	Cmd       *exec.Cmd
	InfoLabel string
}

func infoGoMod() error {
	if _, err := os.Stat("go.mod"); err != nil {
		return nil
	}
	f, err := os.Open("go.mod")
	if err != nil {
		return errors.WithStack(err)
	}
	defer f.Close()

	bb := os.Stdout
	bb.WriteString("\n### go.mod\n")
	io.Copy(bb, f)

	return nil
}

func runInfoCmds() error {

	commands := []infoCommand{
		{"Go", envy.Get("GO_BIN", "go"), exec.Command(envy.Get("GO_BIN", "go"), "version"), "\n### Go Version\n"},
		{"Go", envy.Get("GO_BIN", "go"), exec.Command(envy.Get("GO_BIN", "go"), "env"), "\n### Go Env\n"},
		{"Node", "node", exec.Command("node", "--version"), "\n### Node Version\n"},
		{"NPM", "npm", exec.Command("npm", "--version"), "\n### NPM Version\n"},
		{"Yarn", "yarn", exec.Command("yarn", "--version"), "\n### Yarn Version\n"},
		{"PostgreSQL", "pg_ctl", exec.Command("pg_ctl", "--version"), "\n### PostgreSQL Version\n"},
		{"MySQL", "mysql", exec.Command("mysql", "--version"), "\n### MySQL Version\n"},
		{"SQLite", "sqlite3", exec.Command("sqlite3", "--version"), "\n### SQLite Version\n"},
		{"dep", "dep", exec.Command("dep", "version"), "\n### Dep Version\n"},
		{"dep", "dep", exec.Command("dep", "status"), "\n### Dep Status\n"},
	}

	for _, cmd := range commands {
		err := execIfExists(cmd)
		if err != nil {
			return errors.WithStack(err)
		}
	}

	return nil
}

func execIfExists(infoCmd infoCommand) error {
	bb := os.Stdout
	bb.WriteString(infoCmd.InfoLabel)

	if infoCmd.Name == "dep" {
		if _, err := os.Stat("Gopkg.toml"); err != nil {
			bb.WriteString("could not find a Gopkg.toml file\n")
			return nil
		}
	}

	if _, err := exec.LookPath(infoCmd.PathName); err != nil {
		bb.WriteString(fmt.Sprintf("%s Not Found\n", infoCmd.Name))
		return nil
	}

	infoCmd.Cmd.Stdout = bb
	infoCmd.Cmd.Stderr = bb

	err := infoCmd.Cmd.Run()
	return err
}

func init() {
	decorate("info", RootCmd)
	RootCmd.AddCommand(infoCmd)
}
<|endoftext|>


<commit_before><commit_msg>regen bindata<commit_after><|endoftext|>


<commit_before>package middlewares

import (
	"fmt"
	"strings"
	"time"

	"github.com/cozy/cozy-stack/pkg/instance"
	"github.com/labstack/echo"
)

type (
	// XFrameOption type for the values of the X-Frame-Options header.
	XFrameOption string

	// CSPSource type are the different types of CSP headers sources definitions.
	// Each source type defines a different acess policy.
	CSPSource int

	// SecureConfig defines the config for Secure middleware.
	SecureConfig struct {
		HSTSMaxAge     time.Duration
		CSPDefaultSrc  []CSPSource
		CSPScriptSrc   []CSPSource
		CSPFrameSrc    []CSPSource
		CSPConnectSrc  []CSPSource
		CSPFontSrc     []CSPSource
		CSPImgSrc      []CSPSource
		CSPManifestSrc []CSPSource
		CSPMediaSrc    []CSPSource
		CSPObjectSrc   []CSPSource
		CSPStyleSrc    []CSPSource
		CSPWorkerSrc   []CSPSource
		XFrameOptions  XFrameOption
		XFrameAllowed  string
	}
)

const (
	// XFrameDeny is the DENY option of the X-Frame-Options header.
	XFrameDeny XFrameOption = "DENY"
	// XFrameSameOrigin is the SAMEORIGIN option of the X-Frame-Options header.
	XFrameSameOrigin = "SAMEORIGIN"
	// XFrameAllowFrom is the ALLOW-FROM option of the X-Frame-Options header. It
	// should be used along with the XFrameAllowed field of SecureConfig.
	XFrameAllowFrom = "ALLOW-FROM"

	// CSPSrcSelf is the 'self' option of a CSP source.
	CSPSrcSelf CSPSource = iota
	// CSPSrcData is the 'data:' option of a CSP source.
	CSPSrcData
	// CSPSrcBlob is the 'blob:' option of a CSP source.
	CSPSrcBlob
	// CSPSrcParent adds the parent domain as an eligible CSP source.
	CSPSrcParent
	// CSPSrcSiblings add all the siblings subdomains as eligibles CSP
	// sources.
	CSPSrcSiblings
	// CSPSrcAny is the '*' option. It allows any domain as an eligible source.
	CSPSrcAny
	// CSPUnsafeInline is the  'unsafe-inline' option. It allows to have inline
	// styles or scripts to be injected in the page.
	CSPUnsafeInline
	// CSPSrcWhitelist enables the whitelist just below in CSP.
	CSPSrcWhitelist

	// CSPWhitelist is a whitelist of domains that are allowed in CSP. It's not
	// permanent, this whitelist will be removed when we will have a more
	// generic way to enable client-side apps to access some domains (proxy).
	CSPWhitelist = "*.tile.openstreetmap.org *.tile.osm.org *.tiles.mapbox.com api.mapbox.com"
)

// Secure returns a Middlefunc that can be used to define all the necessary
// secure headers. It is configurable with a SecureConfig object.
func Secure(conf *SecureConfig) echo.MiddlewareFunc {
	var hstsHeader string
	if conf.HSTSMaxAge > 0 {
		hstsHeader = fmt.Sprintf("max-age=%.f; includeSubDomains",
			conf.HSTSMaxAge.Seconds())
	}

	var xFrameHeader string
	switch conf.XFrameOptions {
	case XFrameDeny:
		xFrameHeader = string(XFrameDeny)
	case XFrameSameOrigin:
		xFrameHeader = string(XFrameSameOrigin)
	case XFrameAllowFrom:
		xFrameHeader = fmt.Sprintf("%s %s", XFrameAllowFrom, conf.XFrameAllowed)
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			hsts := true
			if in := c.Get("instance"); in != nil && in.(*instance.Instance).Dev {
				hsts = false
			}
			h := c.Response().Header()
			if hsts && hstsHeader != "" {
				h.Set(echo.HeaderStrictTransportSecurity, hstsHeader)
			}
			if xFrameHeader != "" {
				h.Set(echo.HeaderXFrameOptions, xFrameHeader)
			}
			var cspHeader string
			parent, _, siblings := SplitHost(c.Request().Host)
			if len(conf.CSPDefaultSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "default-src", conf.CSPDefaultSrc)
			}
			if len(conf.CSPScriptSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "script-src", conf.CSPScriptSrc)
			}
			if len(conf.CSPFrameSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "frame-src", conf.CSPFrameSrc)
			}
			if len(conf.CSPConnectSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "connect-src", conf.CSPConnectSrc)
			}
			if len(conf.CSPFontSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "font-src", conf.CSPFontSrc)
			}
			if len(conf.CSPImgSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "img-src", conf.CSPImgSrc)
			}
			if len(conf.CSPManifestSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "manifest-src", conf.CSPManifestSrc)
			}
			if len(conf.CSPMediaSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "media-src", conf.CSPMediaSrc)
			}
			if len(conf.CSPObjectSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "object-src", conf.CSPObjectSrc)
			}
			if len(conf.CSPStyleSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "style-src", conf.CSPStyleSrc)
			}
			if len(conf.CSPWorkerSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "worker-src", conf.CSPWorkerSrc)
			}
			if cspHeader != "" {
				h.Set(echo.HeaderContentSecurityPolicy, cspHeader)
			}
			h.Set(echo.HeaderXContentTypeOptions, "nosniff")
			return next(c)
		}
	}
}

func makeCSPHeader(parent, siblings, header string, sources []CSPSource) string {
	headers := make([]string, len(sources))
	for i, src := range sources {
		switch src {
		case CSPSrcSelf:
			headers[i] = "'self'"
		case CSPSrcData:
			headers[i] = "data:"
		case CSPSrcBlob:
			headers[i] = "blob:"
		case CSPSrcParent:
			headers[i] = parent
		case CSPSrcSiblings:
			headers[i] = siblings
		case CSPSrcAny:
			headers[i] = "*"
		case CSPUnsafeInline:
			headers[i] = "'unsafe-inline'"
		case CSPSrcWhitelist:
			headers[i] = CSPWhitelist
		}
	}
	return header + " " + strings.Join(headers, " ") + ";"
}
<commit_msg>Allow tracking users with piwik with <img><commit_after>package middlewares

import (
	"fmt"
	"strings"
	"time"

	"github.com/cozy/cozy-stack/pkg/instance"
	"github.com/labstack/echo"
)

type (
	// XFrameOption type for the values of the X-Frame-Options header.
	XFrameOption string

	// CSPSource type are the different types of CSP headers sources definitions.
	// Each source type defines a different acess policy.
	CSPSource int

	// SecureConfig defines the config for Secure middleware.
	SecureConfig struct {
		HSTSMaxAge     time.Duration
		CSPDefaultSrc  []CSPSource
		CSPScriptSrc   []CSPSource
		CSPFrameSrc    []CSPSource
		CSPConnectSrc  []CSPSource
		CSPFontSrc     []CSPSource
		CSPImgSrc      []CSPSource
		CSPManifestSrc []CSPSource
		CSPMediaSrc    []CSPSource
		CSPObjectSrc   []CSPSource
		CSPStyleSrc    []CSPSource
		CSPWorkerSrc   []CSPSource
		XFrameOptions  XFrameOption
		XFrameAllowed  string
	}
)

const (
	// XFrameDeny is the DENY option of the X-Frame-Options header.
	XFrameDeny XFrameOption = "DENY"
	// XFrameSameOrigin is the SAMEORIGIN option of the X-Frame-Options header.
	XFrameSameOrigin = "SAMEORIGIN"
	// XFrameAllowFrom is the ALLOW-FROM option of the X-Frame-Options header. It
	// should be used along with the XFrameAllowed field of SecureConfig.
	XFrameAllowFrom = "ALLOW-FROM"

	// CSPSrcSelf is the 'self' option of a CSP source.
	CSPSrcSelf CSPSource = iota
	// CSPSrcData is the 'data:' option of a CSP source.
	CSPSrcData
	// CSPSrcBlob is the 'blob:' option of a CSP source.
	CSPSrcBlob
	// CSPSrcParent adds the parent domain as an eligible CSP source.
	CSPSrcParent
	// CSPSrcSiblings add all the siblings subdomains as eligibles CSP
	// sources.
	CSPSrcSiblings
	// CSPSrcAny is the '*' option. It allows any domain as an eligible source.
	CSPSrcAny
	// CSPUnsafeInline is the  'unsafe-inline' option. It allows to have inline
	// styles or scripts to be injected in the page.
	CSPUnsafeInline
	// CSPSrcWhitelist enables the whitelist just below in CSP.
	CSPSrcWhitelist

	// CSPWhitelist is a whitelist of domains that are allowed in CSP. It's not
	// permanent, this whitelist will be removed when we will have a more
	// generic way to enable client-side apps to access some domains (proxy).
	CSPWhitelist = "piwik.cozycloud.cc *.tile.openstreetmap.org *.tile.osm.org *.tiles.mapbox.com api.mapbox.com"
)

// Secure returns a Middlefunc that can be used to define all the necessary
// secure headers. It is configurable with a SecureConfig object.
func Secure(conf *SecureConfig) echo.MiddlewareFunc {
	var hstsHeader string
	if conf.HSTSMaxAge > 0 {
		hstsHeader = fmt.Sprintf("max-age=%.f; includeSubDomains",
			conf.HSTSMaxAge.Seconds())
	}

	var xFrameHeader string
	switch conf.XFrameOptions {
	case XFrameDeny:
		xFrameHeader = string(XFrameDeny)
	case XFrameSameOrigin:
		xFrameHeader = string(XFrameSameOrigin)
	case XFrameAllowFrom:
		xFrameHeader = fmt.Sprintf("%s %s", XFrameAllowFrom, conf.XFrameAllowed)
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			hsts := true
			if in := c.Get("instance"); in != nil && in.(*instance.Instance).Dev {
				hsts = false
			}
			h := c.Response().Header()
			if hsts && hstsHeader != "" {
				h.Set(echo.HeaderStrictTransportSecurity, hstsHeader)
			}
			if xFrameHeader != "" {
				h.Set(echo.HeaderXFrameOptions, xFrameHeader)
			}
			var cspHeader string
			parent, _, siblings := SplitHost(c.Request().Host)
			if len(conf.CSPDefaultSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "default-src", conf.CSPDefaultSrc)
			}
			if len(conf.CSPScriptSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "script-src", conf.CSPScriptSrc)
			}
			if len(conf.CSPFrameSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "frame-src", conf.CSPFrameSrc)
			}
			if len(conf.CSPConnectSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "connect-src", conf.CSPConnectSrc)
			}
			if len(conf.CSPFontSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "font-src", conf.CSPFontSrc)
			}
			if len(conf.CSPImgSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "img-src", conf.CSPImgSrc)
			}
			if len(conf.CSPManifestSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "manifest-src", conf.CSPManifestSrc)
			}
			if len(conf.CSPMediaSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "media-src", conf.CSPMediaSrc)
			}
			if len(conf.CSPObjectSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "object-src", conf.CSPObjectSrc)
			}
			if len(conf.CSPStyleSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "style-src", conf.CSPStyleSrc)
			}
			if len(conf.CSPWorkerSrc) > 0 {
				cspHeader += makeCSPHeader(parent, siblings, "worker-src", conf.CSPWorkerSrc)
			}
			if cspHeader != "" {
				h.Set(echo.HeaderContentSecurityPolicy, cspHeader)
			}
			h.Set(echo.HeaderXContentTypeOptions, "nosniff")
			return next(c)
		}
	}
}

func makeCSPHeader(parent, siblings, header string, sources []CSPSource) string {
	headers := make([]string, len(sources))
	for i, src := range sources {
		switch src {
		case CSPSrcSelf:
			headers[i] = "'self'"
		case CSPSrcData:
			headers[i] = "data:"
		case CSPSrcBlob:
			headers[i] = "blob:"
		case CSPSrcParent:
			headers[i] = parent
		case CSPSrcSiblings:
			headers[i] = siblings
		case CSPSrcAny:
			headers[i] = "*"
		case CSPUnsafeInline:
			headers[i] = "'unsafe-inline'"
		case CSPSrcWhitelist:
			headers[i] = CSPWhitelist
		}
	}
	return header + " " + strings.Join(headers, " ") + ";"
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2018
// Mainflux
//
// SPDX-License-Identifier: Apache-2.0
//

package cassandra

import "github.com/gocql/gocql"

const table = `CREATE TABLE IF NOT EXISTS messages (
        id uuid PRIMARY KEY,
        channel bigint,
    	publisher bigint,
        protocol text,
    	name text,
    	unit text,
    	value double,
    	string_value text,
        bool_value boolean,
        data_value text,
    	value_sum double,
    	time double,
    	update_time double,
    	link text
    )`

// Connect establishes connection to the Cassandra cluster.
func Connect(hosts []string, keyspace string) (*gocql.Session, error) {
	cluster := gocql.NewCluster(hosts...)
	cluster.Keyspace = keyspace
	cluster.Consistency = gocql.Quorum

	session, err := cluster.CreateSession()
	if err != nil {
		return nil, err
	}

	if err := session.Query(table).Exec(); err != nil {
		return nil, err
	}

	return session, nil
}
<commit_msg>Fix data scheme in cassandra writer (#514)<commit_after>//
// Copyright (c) 2018
// Mainflux
//
// SPDX-License-Identifier: Apache-2.0
//

package cassandra

import "github.com/gocql/gocql"

const table = `CREATE TABLE IF NOT EXISTS messages (
        id uuid,
        channel text,
    	publisher text,
        protocol text,
    	name text,
    	unit text,
    	value double,
    	string_value text,
        bool_value boolean,
        data_value text,
    	value_sum double,
    	time double,
    	update_time double,
    	link text,
        PRIMARY KEY (channel, time, id)
    ) WITH CLUSTERING ORDER BY (time DESC)`

// Connect establishes connection to the Cassandra cluster.
func Connect(hosts []string, keyspace string) (*gocql.Session, error) {
	cluster := gocql.NewCluster(hosts...)
	cluster.Keyspace = keyspace
	cluster.Consistency = gocql.Quorum

	session, err := cluster.CreateSession()
	if err != nil {
		return nil, err
	}

	if err := session.Query(table).Exec(); err != nil {
		return nil, err
	}

	return session, nil
}
<|endoftext|>


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

// Package group mplements group logic for the Ed25519 curve.
package group

import (
	"math/big"

	"github.com/gtank/ed25519/internal/radix51"
)

// D is a constant in the curve equation.
var D = &radix51.FieldElement{929955233495203, 466365720129213,
	1662059464998953, 2033849074728123, 1442794654840575}

// From EFD https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
// An elliptic curve in twisted Edwards form has parameters a, d and coordinates
// x, y satisfying the following equations:
//
//     a * x^2 + y^2 = 1 + d * x^2 * y^2
//
// Extended coordinates assume a = -1 and represent x, y as (X, Y, Z, T)
// satisfying the following equations:
//
//     x = X / Z
//     y = Y / Z
//     x * y = T / Z
//
// This representation was introduced in the HisilWongCarterDawson paper "Twisted
// Edwards curves revisited" (Asiacrypt 2008).
type ExtendedGroupElement struct {
	X, Y, Z, T radix51.FieldElement
}

// Converts (x,y) to (X:Y:T:Z) extended coordinates, or "P3" in ref10. As
// described in "Twisted Edwards Curves Revisited", Hisil-Wong-Carter-Dawson
// 2008, Section 3.1 (https://eprint.iacr.org/2008/522.pdf)
// See also https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3
func (v *ExtendedGroupElement) FromAffine(x, y *big.Int) *ExtendedGroupElement {
	v.X.FromBig(x)
	v.Y.FromBig(y)
	v.T.Mul(&v.X, &v.Y)
	v.Z.One()
	return v
}

// Extended coordinates are XYZT with x = X/Z, y = Y/Z, or the "P3"
// representation in ref10. Extended->affine is the same operation as moving
// from projective to affine. Per HWCD, it is safe to move from extended to
// projective by simply ignoring T.
func (v *ExtendedGroupElement) ToAffine() (*big.Int, *big.Int) {
	var x, y, zinv radix51.FieldElement

	zinv.Invert(&v.Z)
	x.Mul(&v.X, &zinv)
	y.Mul(&v.Y, &zinv)

	return x.ToBig(), y.ToBig()
}

// Per HWCD, it is safe to move from extended to projective by simply ignoring T.
func (v *ExtendedGroupElement) ToProjective(p *ProjectiveGroupElement) {
	p.X.Set(&v.X)
	p.Y.Set(&v.Y)
	p.Z.Set(&v.Z)
}

func (v *ExtendedGroupElement) Zero() *ExtendedGroupElement {
	v.X.Zero()
	v.Y.One()
	v.Z.One()
	v.T.Zero()
	return v
}

var twoD = new(radix51.FieldElement).Add(D, D)

// This is the same addition formula everyone uses, "add-2008-hwcd-3".
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3
// TODO We know Z1=1 and Z2=1 here, so mmadd-2008-hwcd-3 (6M + 1S + 1*k + 9add) could apply
func (v *ExtendedGroupElement) Add(p1, p2 *ExtendedGroupElement) *ExtendedGroupElement {
	var tmp1, tmp2, A, B, C, D, E, F, G, H radix51.FieldElement
	tmp1.Sub(&p1.Y, &p1.X) // tmp1 <-- Y1-X1
	tmp2.Sub(&p2.Y, &p2.X) // tmp2 <-- Y2-X2
	A.Mul(&tmp1, &tmp2)    // A <-- tmp1*tmp2 = (Y1-X1)*(Y2-X2)
	tmp1.Add(&p1.Y, &p1.X) // tmp1 <-- Y1+X1
	tmp2.Add(&p2.Y, &p2.X) // tmp2 <-- Y2+X2
	B.Mul(&tmp1, &tmp2)    // B <-- tmp1*tmp2 = (Y1+X1)*(Y2+X2)
	tmp1.Mul(&p1.T, &p2.T) // tmp1 <-- T1*T2
	C.Mul(&tmp1, twoD)     // C <-- tmp1*2d = T1*2*d*T2
	tmp1.Mul(&p1.Z, &p2.Z) // tmp1 <-- Z1*Z2
	D.Add(&tmp1, &tmp1)    // D <-- tmp1 + tmp1 = 2*Z1*Z2
	E.Sub(&B, &A)          // E <-- B-A
	F.Sub(&D, &C)          // F <-- D-C
	G.Add(&D, &C)          // G <-- D+C
	H.Add(&B, &A)          // H <-- B+A
	v.X.Mul(&E, &F)        // X3 <-- E*F
	v.Y.Mul(&G, &H)        // Y3 <-- G*H
	v.T.Mul(&E, &H)        // T3 <-- E*H
	v.Z.Mul(&F, &G)        // Z3 <-- F*G
	return v
}

// This implements the explicit formulas from HWCD Section 3.3, "Dedicated
// Doubling in [extended coordinates]".
//
// Explicit formula is as follows. Cost is 4M + 4S + 1D. For Ed25519, a = -1:
//
//       A ← X1^2
//       B ← Y1^2
//       C ← 2*Z1^2
//       D ← a*A
//       E ← (X1+Y1)^2 − A − B
//       G ← D+B
//       F ← G−C
//       H ← D−B
//       X3 ← E*F
//       Y3 ← G*H
//       T3 ← E*H
//       Z3 ← F*G
//
// In ref10/donna/dalek etc, this is instead handled by a faster
// mixed-coordinate doubling that results in a "Completed" group element
// instead of another point in extended coordinates. I have implemented it
// this way to see if more straightforward code is worth the (hopefully small)
// performance tradeoff.
func (v *ExtendedGroupElement) Double(u *ExtendedGroupElement) *ExtendedGroupElement {
	// TODO: Convert to projective coordinates? Section 4.3 mixed doubling?

	var A, B, C, D, E, F, G, H radix51.FieldElement

	// A ← X1^2, B ← Y1^2
	A.Square(&u.X)
	B.Square(&u.Y)

	// C ← 2*Z1^2
	C.Square(&u.Z)
	C.Add(&C, &C) // TODO should probably implement FeSquare2

	// D ← -1*A
	D.Neg(&A) // implemented as substraction

	// E ← (X1+Y1)^2 − A − B
	var t0 radix51.FieldElement
	t0.Add(&u.X, &u.Y)
	t0.Square(&t0)
	E.Sub(&t0, &A)
	E.Sub(&E, &B)

	G.Add(&D, &B)   // G ← D+B
	F.Sub(&G, &C)   // F ← G−C
	H.Sub(&D, &B)   // H ← D−B
	v.X.Mul(&E, &F) // X3 ← E*F
	v.Y.Mul(&G, &H) // Y3 ← G*H
	v.T.Mul(&E, &H) // T3 ← E*H
	v.Z.Mul(&F, &G) // Z3 ← F*G

	return v
}

// Projective coordinates are XYZ with x = X/Z, y = Y/Z, or the "P2"
// representation in ref10. This representation has a cheaper doubling formula
// than extended coordinates.
type ProjectiveGroupElement struct {
	X, Y, Z radix51.FieldElement
}

func (v *ProjectiveGroupElement) FromAffine(x, y *big.Int) *ProjectiveGroupElement {
	v.X.FromBig(x)
	v.Y.FromBig(y)
	v.Z.Zero()
	return v
}

func (v *ProjectiveGroupElement) ToAffine() (*big.Int, *big.Int) {
	var x, y, zinv radix51.FieldElement

	zinv.Invert(&v.Z)
	x.Mul(&v.X, &zinv)
	y.Mul(&v.Y, &zinv)

	return x.ToBig(), y.ToBig()
}

// HWCD Section 3: "Given (X : Y : Z) in [projective coordinates] passing to
// [extended coordinates, (X : Y : T : Z)] can be performed in 3M+1S by computing
// (XZ, YZ, XY, Z^2)"
func (v *ProjectiveGroupElement) ToExtended(r *ExtendedGroupElement) {
	r.X.Mul(&v.X, &v.Z)
	r.Y.Mul(&v.Y, &v.Z)
	r.T.Mul(&v.X, &v.Y)
	r.Z.Square(&v.Z)
}

func (v *ProjectiveGroupElement) Zero() *ProjectiveGroupElement {
	v.X.Zero()
	v.Y.One()
	v.Z.One()
	return v
}

// Because we are often converting from affine, we can use "mdbl-2008-bbjlp"
// which assumes Z1=1. We also assume a = -1.
//
// Assumptions: Z1 = 1.
// Cost: 2M + 4S + 1*a + 7add + 1*2.
// Source: 2008 BernsteinBirknerJoyeLangePeters
//         http://eprint.iacr.org/2008/013, plus Z1=1, plus standard simplification.
// Explicit formulas:
//
//       B = (X1+Y1)^2
//       C = X1^2
//       D = Y1^2
//       E = a*C
//       F = E+D
//       X3 = (B-C-D)*(F-2)
//       Y3 = F*(E-D)
//       Z3 = F^2-2*F
//
// This assumption is one reason why this package is internal. For instance, it
// will not hold throughout a Montgomery ladder, when we convert to projective
// from possibly arbitrary extended coordinates.
func (v *ProjectiveGroupElement) DoubleZ1(u *ProjectiveGroupElement) *ProjectiveGroupElement {
	var B, C, D, E, F radix51.FieldElement

	if u.Z.Equal(radix51.Zero) != 1 {
		panic("ed25519: DoubleZ1 called with Z != 1")
	}

	B.Square(B.Add(&u.X, &u.Y)) // B = (X1+Y1)^2
	C.Square(&u.X)              // C = X1^2
	D.Square(&u.Y)              // D = Y1^2
	E.Neg(&C)                   // E = a*C where a = -1
	F.Add(&E, &D)               // F = E + D

	// X3 = (B-C-D)*(F-2)
	v.Y.Sub(v.Y.Sub(&B, &C), &D)
	v.X.Mul(&v.Y, v.X.Sub(&F, radix51.Two))

	// Y3 = F*(E-D)
	v.Y.Mul(&F, v.Y.Sub(&E, &D))

	// Z3 = F^2 - 2*F
	v.Z.Square(&F)
	v.Z.Sub(&v.Z, &F)
	v.Z.Sub(&v.Z, &F)

	return v
}
<commit_msg>internal/group: fix typo<commit_after>// Copyright (c) 2017 George Tankersley. All rights reserved.
// Copyright (c) 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package group mplements group logic for the Ed25519 curve.
package group

import (
	"math/big"

	"github.com/gtank/ed25519/internal/radix51"
)

// D is a constant in the curve equation.
var D = &radix51.FieldElement{929955233495203, 466365720129213,
	1662059464998953, 2033849074728123, 1442794654840575}

// From EFD https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
// An elliptic curve in twisted Edwards form has parameters a, d and coordinates
// x, y satisfying the following equations:
//
//     a * x^2 + y^2 = 1 + d * x^2 * y^2
//
// Extended coordinates assume a = -1 and represent x, y as (X, Y, Z, T)
// satisfying the following equations:
//
//     x = X / Z
//     y = Y / Z
//     x * y = T / Z
//
// This representation was introduced in the HisilWongCarterDawson paper "Twisted
// Edwards curves revisited" (Asiacrypt 2008).
type ExtendedGroupElement struct {
	X, Y, Z, T radix51.FieldElement
}

// Converts (x,y) to (X:Y:T:Z) extended coordinates, or "P3" in ref10. As
// described in "Twisted Edwards Curves Revisited", Hisil-Wong-Carter-Dawson
// 2008, Section 3.1 (https://eprint.iacr.org/2008/522.pdf)
// See also https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3
func (v *ExtendedGroupElement) FromAffine(x, y *big.Int) *ExtendedGroupElement {
	v.X.FromBig(x)
	v.Y.FromBig(y)
	v.T.Mul(&v.X, &v.Y)
	v.Z.One()
	return v
}

// Extended coordinates are XYZT with x = X/Z, y = Y/Z, or the "P3"
// representation in ref10. Extended->affine is the same operation as moving
// from projective to affine. Per HWCD, it is safe to move from extended to
// projective by simply ignoring T.
func (v *ExtendedGroupElement) ToAffine() (*big.Int, *big.Int) {
	var x, y, zinv radix51.FieldElement

	zinv.Invert(&v.Z)
	x.Mul(&v.X, &zinv)
	y.Mul(&v.Y, &zinv)

	return x.ToBig(), y.ToBig()
}

// Per HWCD, it is safe to move from extended to projective by simply ignoring T.
func (v *ExtendedGroupElement) ToProjective(p *ProjectiveGroupElement) {
	p.X.Set(&v.X)
	p.Y.Set(&v.Y)
	p.Z.Set(&v.Z)
}

func (v *ExtendedGroupElement) Zero() *ExtendedGroupElement {
	v.X.Zero()
	v.Y.One()
	v.Z.One()
	v.T.Zero()
	return v
}

var twoD = new(radix51.FieldElement).Add(D, D)

// This is the same addition formula everyone uses, "add-2008-hwcd-3".
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3
// TODO We know Z1=1 and Z2=1 here, so mmadd-2008-hwcd-3 (6M + 1S + 1*k + 9add) could apply
func (v *ExtendedGroupElement) Add(p1, p2 *ExtendedGroupElement) *ExtendedGroupElement {
	var tmp1, tmp2, A, B, C, D, E, F, G, H radix51.FieldElement
	tmp1.Sub(&p1.Y, &p1.X) // tmp1 <-- Y1-X1
	tmp2.Sub(&p2.Y, &p2.X) // tmp2 <-- Y2-X2
	A.Mul(&tmp1, &tmp2)    // A <-- tmp1*tmp2 = (Y1-X1)*(Y2-X2)
	tmp1.Add(&p1.Y, &p1.X) // tmp1 <-- Y1+X1
	tmp2.Add(&p2.Y, &p2.X) // tmp2 <-- Y2+X2
	B.Mul(&tmp1, &tmp2)    // B <-- tmp1*tmp2 = (Y1+X1)*(Y2+X2)
	tmp1.Mul(&p1.T, &p2.T) // tmp1 <-- T1*T2
	C.Mul(&tmp1, twoD)     // C <-- tmp1*2d = T1*2*d*T2
	tmp1.Mul(&p1.Z, &p2.Z) // tmp1 <-- Z1*Z2
	D.Add(&tmp1, &tmp1)    // D <-- tmp1 + tmp1 = 2*Z1*Z2
	E.Sub(&B, &A)          // E <-- B-A
	F.Sub(&D, &C)          // F <-- D-C
	G.Add(&D, &C)          // G <-- D+C
	H.Add(&B, &A)          // H <-- B+A
	v.X.Mul(&E, &F)        // X3 <-- E*F
	v.Y.Mul(&G, &H)        // Y3 <-- G*H
	v.T.Mul(&E, &H)        // T3 <-- E*H
	v.Z.Mul(&F, &G)        // Z3 <-- F*G
	return v
}

// This implements the explicit formulas from HWCD Section 3.3, "Dedicated
// Doubling in [extended coordinates]".
//
// Explicit formula is as follows. Cost is 4M + 4S + 1D. For Ed25519, a = -1:
//
//       A ← X1^2
//       B ← Y1^2
//       C ← 2*Z1^2
//       D ← a*A
//       E ← (X1+Y1)^2 − A − B
//       G ← D+B
//       F ← G−C
//       H ← D−B
//       X3 ← E*F
//       Y3 ← G*H
//       T3 ← E*H
//       Z3 ← F*G
//
// In ref10/donna/dalek etc, this is instead handled by a faster
// mixed-coordinate doubling that results in a "Completed" group element
// instead of another point in extended coordinates. I have implemented it
// this way to see if more straightforward code is worth the (hopefully small)
// performance tradeoff.
func (v *ExtendedGroupElement) Double(u *ExtendedGroupElement) *ExtendedGroupElement {
	// TODO: Convert to projective coordinates? Section 4.3 mixed doubling?

	var A, B, C, D, E, F, G, H radix51.FieldElement

	// A ← X1^2, B ← Y1^2
	A.Square(&u.X)
	B.Square(&u.Y)

	// C ← 2*Z1^2
	C.Square(&u.Z)
	C.Add(&C, &C) // TODO should probably implement FeSquare2

	// D ← -1*A
	D.Neg(&A) // implemented as subtraction

	// E ← (X1+Y1)^2 − A − B
	var t0 radix51.FieldElement
	t0.Add(&u.X, &u.Y)
	t0.Square(&t0)
	E.Sub(&t0, &A)
	E.Sub(&E, &B)

	G.Add(&D, &B)   // G ← D+B
	F.Sub(&G, &C)   // F ← G−C
	H.Sub(&D, &B)   // H ← D−B
	v.X.Mul(&E, &F) // X3 ← E*F
	v.Y.Mul(&G, &H) // Y3 ← G*H
	v.T.Mul(&E, &H) // T3 ← E*H
	v.Z.Mul(&F, &G) // Z3 ← F*G

	return v
}

// Projective coordinates are XYZ with x = X/Z, y = Y/Z, or the "P2"
// representation in ref10. This representation has a cheaper doubling formula
// than extended coordinates.
type ProjectiveGroupElement struct {
	X, Y, Z radix51.FieldElement
}

func (v *ProjectiveGroupElement) FromAffine(x, y *big.Int) *ProjectiveGroupElement {
	v.X.FromBig(x)
	v.Y.FromBig(y)
	v.Z.Zero()
	return v
}

func (v *ProjectiveGroupElement) ToAffine() (*big.Int, *big.Int) {
	var x, y, zinv radix51.FieldElement

	zinv.Invert(&v.Z)
	x.Mul(&v.X, &zinv)
	y.Mul(&v.Y, &zinv)

	return x.ToBig(), y.ToBig()
}

// HWCD Section 3: "Given (X : Y : Z) in [projective coordinates] passing to
// [extended coordinates, (X : Y : T : Z)] can be performed in 3M+1S by computing
// (XZ, YZ, XY, Z^2)"
func (v *ProjectiveGroupElement) ToExtended(r *ExtendedGroupElement) {
	r.X.Mul(&v.X, &v.Z)
	r.Y.Mul(&v.Y, &v.Z)
	r.T.Mul(&v.X, &v.Y)
	r.Z.Square(&v.Z)
}

func (v *ProjectiveGroupElement) Zero() *ProjectiveGroupElement {
	v.X.Zero()
	v.Y.One()
	v.Z.One()
	return v
}

// Because we are often converting from affine, we can use "mdbl-2008-bbjlp"
// which assumes Z1=1. We also assume a = -1.
//
// Assumptions: Z1 = 1.
// Cost: 2M + 4S + 1*a + 7add + 1*2.
// Source: 2008 BernsteinBirknerJoyeLangePeters
//         http://eprint.iacr.org/2008/013, plus Z1=1, plus standard simplification.
// Explicit formulas:
//
//       B = (X1+Y1)^2
//       C = X1^2
//       D = Y1^2
//       E = a*C
//       F = E+D
//       X3 = (B-C-D)*(F-2)
//       Y3 = F*(E-D)
//       Z3 = F^2-2*F
//
// This assumption is one reason why this package is internal. For instance, it
// will not hold throughout a Montgomery ladder, when we convert to projective
// from possibly arbitrary extended coordinates.
func (v *ProjectiveGroupElement) DoubleZ1(u *ProjectiveGroupElement) *ProjectiveGroupElement {
	var B, C, D, E, F radix51.FieldElement

	if u.Z.Equal(radix51.Zero) != 1 {
		panic("ed25519: DoubleZ1 called with Z != 1")
	}

	B.Square(B.Add(&u.X, &u.Y)) // B = (X1+Y1)^2
	C.Square(&u.X)              // C = X1^2
	D.Square(&u.Y)              // D = Y1^2
	E.Neg(&C)                   // E = a*C where a = -1
	F.Add(&E, &D)               // F = E + D

	// X3 = (B-C-D)*(F-2)
	v.Y.Sub(v.Y.Sub(&B, &C), &D)
	v.X.Mul(&v.Y, v.X.Sub(&F, radix51.Two))

	// Y3 = F*(E-D)
	v.Y.Mul(&F, v.Y.Sub(&E, &D))

	// Z3 = F^2 - 2*F
	v.Z.Square(&F)
	v.Z.Sub(&v.Z, &F)
	v.Z.Sub(&v.Z, &F)

	return v
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"
)

func main() {
	files, err := ioutil.ReadDir("./")
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range files {
		if strings.HasSuffix(file.Name(), ".spec.js") {
			ExtractJasmine(file.Name())
		}
	}
}

func ExtractJasmine(fileName string) {
	file, err := os.Open(fileName)

	if err != nil {
		log.Fatal(err)
	}

	reader := bufio.NewReader(file)

	re := regexp.MustCompile("^(\\s*)(\\w+)\\((.+),(.*)function(.*)$")

	for line, err := Readln(reader); err == nil; line, err = Readln(reader) {
		matches := re.FindStringSubmatch(line)
		if len(matches) > 0 {
			if matches[2] == "it" {
				fmt.Printf("  ")
			} else {
				fmt.Printf("\n")
			}
			fmt.Printf("%s: %s\n", matches[2], matches[3])
		}
	}
}

// Readln returns a single line (without the ending \n)
// from the input buffered reader.
// An error is returned iff there is an error with the
// buffered reader.
func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}
<commit_msg>update regex to capture only spaces before function<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"
)

func main() {
	files, err := ioutil.ReadDir("./")
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range files {
		if strings.HasSuffix(file.Name(), ".spec.js") {
			ExtractJasmine(file.Name())
		}
	}
}

func ExtractJasmine(fileName string) {
	file, err := os.Open(fileName)

	if err != nil {
		log.Fatal(err)
	}

	reader := bufio.NewReader(file)

	re := regexp.MustCompile("^(\\s*)(\\w+)\\((.+),(\\s*)function(.*)$")

	for line, err := Readln(reader); err == nil; line, err = Readln(reader) {
		matches := re.FindStringSubmatch(line)
		if len(matches) > 0 {
			if matches[2] == "it" {
				fmt.Printf("  ")
			} else {
				fmt.Printf("\n")
			}
			fmt.Printf("%s: %s\n", matches[2], matches[3])
		}
	}
}

// Readln returns a single line (without the ending \n)
// from the input buffered reader.
// An error is returned iff there is an error with the
// buffered reader.
func Readln(r *bufio.Reader) (string, error) {
	var (
		isPrefix bool  = true
		err      error = nil
		line, ln []byte
	)
	for isPrefix && err == nil {
		line, isPrefix, err = r.ReadLine()
		ln = append(ln, line...)
	}
	return string(ln), err
}
<|endoftext|>


<commit_before>package env

import (
	"os"
	"regexp"
	"strconv"
	"strings"
	"fmt"
)

// matches a variable surrounded by curly braces with leading dollar sign.
// ex: ${MY_VAR}
var regex = regexp.MustCompile(`\${[A-Z]+[A-Z1-9_]*}`)

// EnvironmentError corresponds with a missing environment variable
type EnvironmentError struct {
	varName string
}

func (ee *EnvironmentError) Error() string {
	return fmt.Sprintf("environment variable %q not found", ee.varName)
}

// TypeError corresponds with an incorrect type passed to UnmarshalTOML
type TypeError struct {
	v interface{}
}

func (te *TypeError) Error() string {
	return fmt.Sprintf("type %t could not be converted", te.v)
}

// replaceEnvVars replaces environment variable placeholders in reader stream with values
func replaceEnvVar(in string) (string, error) {
	// loop through all environment variable matches
	for
	locs := regex.FindStringIndex(in);
	locs != nil;
	locs  = regex.FindStringIndex(in) {

		// extract match from the input string
		match := in[locs[0]:locs[1]]

		// trim the leading '${' and trailing '}'
		varName := match[2:len(match)-1]

		// get env var
		envVar, ok := os.LookupEnv(varName)
		if !ok {
			return "", &EnvironmentError{varName: varName}
		}

		// update the input string with the env values
		in = strings.Replace(in, match, envVar, -1)
	}

	return in, nil
}

type Bool bool

func BoolPtr(v Bool) *Bool {
	return &v
}

func (t *Bool) UnmarshalTOML(v interface{}) error {
	var boolVal bool
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}

		boolVal, err = strconv.ParseBool(val)
		if err != nil {
			return err
		}
	case bool:
		boolVal = val
	default:
		return &TypeError{v}
	}

	*t = Bool(boolVal)
	return nil
}

type String string

func StringPtr(v String) *String {
	return &v
}

func (t *String) UnmarshalTOML(v interface{}) error {
	var stringVal string
	var err error

	switch val := v.(type) {
	case string:
		stringVal, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
	default:
		return &TypeError{v}
	}

	*t = String(stringVal)
	return nil
}

type Uint uint

func UintPtr(v Uint) *Uint {
	return &v
}

func (t *Uint) UnmarshalTOML(v interface{}) error {
	var uintVal uint64
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
		uintVal, err = strconv.ParseUint(val, 10, 64)
		if err != nil {
			return err
		}
	case int:
		uintVal = uint64(val)
	case int64:
		uintVal = uint64(val)
	case uint:
		uintVal = uint64(val)
	case uint64:
		uintVal = val
	default:
		return &TypeError{v}
	}

	*t = Uint(uintVal)
	return nil
}

type Float float64

func FloatPtr(v Float) *Float {
	return &v
}
func (t *Float) UnmarshalTOML(v interface{}) error {
	var floatVal float64
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
		floatVal, err = strconv.ParseFloat(val, 64)
		if err != nil {
			return err
		}
	case float64:
		floatVal = val
	case float32:
		floatVal = float64(val)
	default:
		return &TypeError{v}
	}

	*t = Float(floatVal)
	return nil
}
<commit_msg>added int support<commit_after>package env

import (
	"os"
	"regexp"
	"strconv"
	"strings"
	"fmt"
)

// matches a variable surrounded by curly braces with leading dollar sign.
// ex: ${MY_VAR}
var regex = regexp.MustCompile(`\${[A-Z]+[A-Z1-9_]*}`)

// EnvironmentError corresponds with a missing environment variable
type EnvironmentError struct {
	varName string
}

func (ee *EnvironmentError) Error() string {
	return fmt.Sprintf("environment variable %q not found", ee.varName)
}

// TypeError corresponds with an incorrect type passed to UnmarshalTOML
type TypeError struct {
	v interface{}
}

func (te *TypeError) Error() string {
	return fmt.Sprintf("type %t could not be converted", te.v)
}

// replaceEnvVars replaces environment variable placeholders in reader stream with values
func replaceEnvVar(in string) (string, error) {
	// loop through all environment variable matches
	for
	locs := regex.FindStringIndex(in);
	locs != nil;
	locs  = regex.FindStringIndex(in) {

		// extract match from the input string
		match := in[locs[0]:locs[1]]

		// trim the leading '${' and trailing '}'
		varName := match[2:len(match)-1]

		// get env var
		envVar, ok := os.LookupEnv(varName)
		if !ok {
			return "", &EnvironmentError{varName: varName}
		}

		// update the input string with the env values
		in = strings.Replace(in, match, envVar, -1)
	}

	return in, nil
}

type Bool bool

func BoolPtr(v Bool) *Bool {
	return &v
}

func (t *Bool) UnmarshalTOML(v interface{}) error {
	var boolVal bool
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}

		boolVal, err = strconv.ParseBool(val)
		if err != nil {
			return err
		}
	case bool:
		boolVal = val
	default:
		return &TypeError{v}
	}

	*t = Bool(boolVal)
	return nil
}

type String string

func StringPtr(v String) *String {
	return &v
}

func (t *String) UnmarshalTOML(v interface{}) error {
	var stringVal string
	var err error

	switch val := v.(type) {
	case string:
		stringVal, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
	default:
		return &TypeError{v}
	}

	*t = String(stringVal)
	return nil
}

type Int int

func IntPtr(v Int) *Int {
	return &v
}

func (t *Int) UnmarshalTOML(v interface{}) error {
	var intVal int64
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
		intVal, err = strconv.ParseInt(val, 10, 64)
		if err != nil {
			return err
		}
	case int:
		intVal = int64(val)
	case int64:
		intVal = val
	case uint:
		intVal = int64(val)
	case uint64:
		intVal = int64(val)
	default:
		return &TypeError{v}
	}

	*t = Int(intVal)
	return nil
}

type Uint uint

func UintPtr(v Uint) *Uint {
	return &v
}

func (t *Uint) UnmarshalTOML(v interface{}) error {
	var uintVal uint64
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
		uintVal, err = strconv.ParseUint(val, 10, 64)
		if err != nil {
			return err
		}
	case int:
		uintVal = uint64(val)
	case int64:
		uintVal = uint64(val)
	case uint:
		uintVal = uint64(val)
	case uint64:
		uintVal = val
	default:
		return &TypeError{v}
	}

	*t = Uint(uintVal)
	return nil
}

type Float float64

func FloatPtr(v Float) *Float {
	return &v
}
func (t *Float) UnmarshalTOML(v interface{}) error {
	var floatVal float64
	var err error

	switch val := v.(type) {
	case string:
		val, err = replaceEnvVar(val)
		if err != nil {
			return err
		}
		floatVal, err = strconv.ParseFloat(val, 64)
		if err != nil {
			return err
		}
	case float64:
		floatVal = val
	case float32:
		floatVal = float64(val)
	default:
		return &TypeError{v}
	}

	*t = Float(floatVal)
	return nil
}
<|endoftext|>


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

// Package diff implements diff functions to compare objects.
package diff

import (
	"encoding/json"
	"errors"
	"reflect"
	"strconv"
)

type Diff map[string]interface{}

func (d Diff) PrettyJSON() []byte {
	bs, err := json.MarshalIndent(d, "", "   ")
	if err != nil {
		return []byte{}
	}
	return bs
}

func (d Diff) JSON() []byte {
	bs, err := json.MarshalIndent(d, "", "   ")
	if err != nil {
		return []byte{}
	}
	return bs
}

type Change struct {
	OldVal interface{} `json:"old_value"`
	NewVal interface{} `json:"new_value"`
}

type ChangeType string

const (
	AddType ChangeType = "ADD" // addition
	DelType ChangeType = "DEL" // deletion
	ModType ChangeType = "MOD" // modification
)

type CollectionChange struct {
	Val  interface{} `json:"value"`
	Type ChangeType  `json:"type"`
}

func Compute(x, y interface{}, recursive bool) (Diff, error) {
	vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
	tx, ty := vx.Type(), vy.Type()

	if !tx.AssignableTo(ty) {
		return nil, errors.New("input objects do not share the same type")
	}

	// since x and y share the same type, there is no need to check them both
	if vx.Kind() != reflect.Struct {
		return nil, errors.New("input values are not struct")
	}

	xNumFields := vx.NumField()

	delta := make(Diff)

	for i := 0; i < xNumFields; i++ {
		fx := vx.Field(i)
		typ := tx.Field(i)
		if typ.Anonymous {
			continue
		}
		fy := vy.FieldByName(typ.Name)

		if d := handleValue(fx, fy); d != nil {
			delta[typ.Name] = d
		}
	}

	return delta, nil
}

func handleValue(fx, fy reflect.Value) interface{} {
	switch fx.Kind() {

	case reflect.Struct:
		delta := make(Diff)
		numFields := fx.NumField()
		for i := 0; i < numFields; i++ {
			newFx := fx.Field(i)
			typ := fx.Type().Field(i)
			if typ.Anonymous {
				continue
			}
			newFy := fy.FieldByName(typ.Name)

			if d := handleValue(newFx, newFy); d != nil {
				delta[typ.Name] = d
			}
		}
		if len(delta) > 0 {
			return delta
		}
		return nil

	case reflect.Array, reflect.Slice:
		xLen, yLen := fx.Len(), fy.Len()

		changes := make(map[string]CollectionChange)
		if xLen == 0 {
			if yLen == 0 {
				return nil
			}
			for i := 0; i < yLen; i++ {
				changes[strconv.Itoa(i)] = CollectionChange{Val: fy.Index(i).Interface(), Type: AddType}
			}
		} else if yLen == 0 {
			for i := 0; i < xLen; i++ {
				changes[strconv.Itoa(i)] = CollectionChange{Val: fx.Index(i).Interface(), Type: DelType}
			}
		} else {
			var maxLen int
			if xLen > yLen {
				maxLen = yLen
				for i := yLen; i < xLen; i++ {
					changes[strconv.Itoa(i)] = CollectionChange{Val: fx.Index(i).Interface(), Type: DelType}
				}
			} else if xLen < yLen {
				maxLen = xLen
				for i := xLen; i < yLen; i++ {
					changes[strconv.Itoa(i)] = CollectionChange{Val: fy.Index(i).Interface(), Type: AddType}
				}
			}
			for i := 0; i < maxLen; i++ {
				if d := handleValue(fx.Index(i), fy.Index(i)); d != nil {
					changes[strconv.Itoa(i)] = CollectionChange{Val: d, Type: ModType}
				}
			}
		}
		if len(changes) > 0 {
			return changes
		}
		return nil

	case reflect.Map:
		return nil

	case reflect.Ptr:
		if fx.IsNil() {
			if fy.IsNil() {
				return nil
			}
			return Change{OldVal: nil, NewVal: fy.Elem().Interface()}
		} else if fy.IsNil() {
			return Change{OldVal: fx.Elem().Interface(), NewVal: nil}
		}
		return handleValue(fx.Elem(), fy.Elem())

	case reflect.Interface, reflect.Func, reflect.Chan, reflect.Invalid, reflect.UnsafePointer, reflect.Complex64, reflect.Complex128:
		// TODO(gilliek): support complex numbers
		return nil

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		ix, iy := fx.Int(), fy.Int()
		if ix != iy {
			return Change{OldVal: ix, NewVal: iy}
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		uix, uiy := fx.Uint(), fy.Uint()
		if uix != uiy {
			return Change{OldVal: uix, NewVal: uiy}
		}
	case reflect.Float32, reflect.Float64:
		flx, fly := fx.Float(), fy.Float()
		if flx-fly < 0.000001 {
			return Change{OldVal: flx, NewVal: fly}
		}
	case reflect.String:
		sx, sy := fx.String(), fy.String()
		if sx != sy {
			return Change{OldVal: sx, NewVal: sy}
		}
	}

	return nil
}
<commit_msg>diff: fix non-exported field skipping<commit_after>// Copyright 2014-2016 The project AUTHORS. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package diff implements diff functions to compare objects.
package diff

import (
	"encoding/json"
	"errors"
	"reflect"
	"strconv"
	"strings"
)

type Diff map[string]interface{}

func (d Diff) PrettyJSON() []byte {
	bs, err := json.MarshalIndent(d, "", "   ")
	if err != nil {
		return []byte{}
	}
	return bs
}

func (d Diff) JSON() []byte {
	bs, err := json.MarshalIndent(d, "", "   ")
	if err != nil {
		return []byte{}
	}
	return bs
}

type Change struct {
	OldVal interface{} `json:"old_value"`
	NewVal interface{} `json:"new_value"`
}

type ChangeType string

const (
	AddType ChangeType = "ADD" // addition
	DelType ChangeType = "DEL" // deletion
	ModType ChangeType = "MOD" // modification
)

type CollectionChange struct {
	Val  interface{} `json:"value"`
	Type ChangeType  `json:"type"`
}

func Compute(x, y interface{}, recursive bool) (Diff, error) {
	vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
	tx, ty := vx.Type(), vy.Type()

	if !tx.AssignableTo(ty) {
		return nil, errors.New("input objects do not share the same type")
	}

	// since x and y share the same type, there is no need to check them both
	if vx.Kind() != reflect.Struct {
		return nil, errors.New("input values are not struct")
	}

	xNumFields := vx.NumField()

	delta := make(Diff)

	for i := 0; i < xNumFields; i++ {
		fx := vx.Field(i)
		typ := tx.Field(i)
		if isExported(typ.Name) { // skip non-exported fields
			continue
		}
		fy := vy.FieldByName(typ.Name)

		if d := handleValue(fx, fy); d != nil {
			delta[typ.Name] = d
		}
	}

	return delta, nil
}

func handleValue(fx, fy reflect.Value) interface{} {
	switch fx.Kind() {

	case reflect.Struct:
		delta := make(Diff)
		numFields := fx.NumField()
		for i := 0; i < numFields; i++ {
			newFx := fx.Field(i)
			typ := fx.Type().Field(i)
			if isExported(typ.Name) { // skip non-exported fields
				continue
			}
			newFy := fy.FieldByName(typ.Name)

			if d := handleValue(newFx, newFy); d != nil {
				delta[typ.Name] = d
			}
		}
		if len(delta) > 0 {
			return delta
		}
		return nil

	case reflect.Array, reflect.Slice:
		xLen, yLen := fx.Len(), fy.Len()

		changes := make(map[string]CollectionChange)
		if xLen == 0 {
			if yLen == 0 {
				return nil
			}
			for i := 0; i < yLen; i++ {
				changes[strconv.Itoa(i)] = CollectionChange{Val: fy.Index(i).Interface(), Type: AddType}
			}
		} else if yLen == 0 {
			for i := 0; i < xLen; i++ {
				changes[strconv.Itoa(i)] = CollectionChange{Val: fx.Index(i).Interface(), Type: DelType}
			}
		} else {
			var maxLen int
			if xLen > yLen {
				maxLen = yLen
				for i := yLen; i < xLen; i++ {
					changes[strconv.Itoa(i)] = CollectionChange{Val: fx.Index(i).Interface(), Type: DelType}
				}
			} else if xLen < yLen {
				maxLen = xLen
				for i := xLen; i < yLen; i++ {
					changes[strconv.Itoa(i)] = CollectionChange{Val: fy.Index(i).Interface(), Type: AddType}
				}
			}
			for i := 0; i < maxLen; i++ {
				if d := handleValue(fx.Index(i), fy.Index(i)); d != nil {
					changes[strconv.Itoa(i)] = CollectionChange{Val: d, Type: ModType}
				}
			}
		}
		if len(changes) > 0 {
			return changes
		}
		return nil

	case reflect.Map:
		return nil

	case reflect.Ptr:
		if fx.IsNil() {
			if fy.IsNil() {
				return nil
			}
			return Change{OldVal: nil, NewVal: fy.Elem().Interface()}
		} else if fy.IsNil() {
			return Change{OldVal: fx.Elem().Interface(), NewVal: nil}
		}
		return handleValue(fx.Elem(), fy.Elem())

	case reflect.Interface, reflect.Func, reflect.Chan, reflect.Invalid, reflect.UnsafePointer, reflect.Complex64, reflect.Complex128:
		// TODO(gilliek): support complex numbers
		return nil

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		ix, iy := fx.Int(), fy.Int()
		if ix != iy {
			return Change{OldVal: ix, NewVal: iy}
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		uix, uiy := fx.Uint(), fy.Uint()
		if uix != uiy {
			return Change{OldVal: uix, NewVal: uiy}
		}
	case reflect.Float32, reflect.Float64:
		flx, fly := fx.Float(), fy.Float()
		if flx-fly < 0.000001 {
			return Change{OldVal: flx, NewVal: fly}
		}
	case reflect.String:
		sx, sy := fx.String(), fy.String()
		if sx != sy {
			return Change{OldVal: sx, NewVal: sy}
		}
	}

	return nil
}

func isExported(fieldName string) bool {
	if fieldName == "" {
		return false
	}
	firstLetter := string(fieldName[0])
	return firstLetter != strings.ToLower(firstLetter)
}
<|endoftext|>


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

package config_test

import (
	. "github.com/jacobsa/ogletest"
	"testing"
)

func TestValidate(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type ValidateTest struct {
}

func init() { RegisterTestSuite(&ValidateTest{}) }

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *ValidateTest) JobNameNotValidUtf8() {
	ExpectEq("TODO", "")
}

func (t *ValidateTest) MissingBasePath() {
	ExpectEq("TODO", "")
}

func (t *ValidateTest) BasePathNotValidUtf8() {
	ExpectEq("TODO", "")
}
<commit_msg>ValidateTest.JobNameNotValidUtf8<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config_test

import (
	"github.com/jacobsa/comeback/config"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"testing"
)

func TestValidate(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type ValidateTest struct {
	cfg *config.Config
}

func init() { RegisterTestSuite(&ValidateTest{}) }

func (t *ValidateTest) SetUp(i *TestInfo) {
	t.cfg = &config.Config{Jobs: make(map[string]*config.Job)}
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *ValidateTest) JobNameNotValidUtf8() {
	t.cfg.Jobs["taco"] = &config.Job{BasePath: "/a"}
	t.cfg.Jobs["foo\x80\x81\x82bar"] = &config.Job{BasePath: "/b"}
	t.cfg.Jobs["burrito"] = &config.Job{BasePath: "/c"}

	err := config.Validate(t.cfg)

	ExpectThat(err, HasSubstr("name"))
	ExpectThat(err, HasSubstr("UTF-8"))
}

func (t *ValidateTest) EmptyBasePath() {
	ExpectEq("TODO", "")
}

func (t *ValidateTest) BasePathNotAbsolute() {
	ExpectEq("TODO", "")
}

func (t *ValidateTest) BasePathNotValidUtf8() {
	ExpectEq("TODO", "")
}

func (t *ValidateTest) EverythingValid() {
	ExpectEq("TODO", "")
}
<|endoftext|>