Move to vendor dir

This commit is contained in:
Zachary Gershman
2016-06-21 08:09:19 -07:00
parent cd28eb3859
commit dc2870080e
282 changed files with 135 additions and 6438 deletions

View File

@@ -0,0 +1,49 @@
package version
import (
"errors"
"regexp"
"strconv"
)
var (
verSegCompIntRegexp = regexp.MustCompile(`\A[0-9]+\z`)
)
type VerSegCompInt struct{ I int }
func NewVerSegCompIntFromString(piece string) (VerSegCompInt, bool, error) {
if !verSegCompIntRegexp.MatchString(piece) {
return VerSegCompInt{}, false, nil
}
i, err := strconv.Atoi(piece)
if err != nil {
return VerSegCompInt{}, true, err
}
return VerSegCompInt{i}, true, nil
}
func (i VerSegCompInt) Validate() error {
if i.I < 0 {
return errors.New("Expected integer component to be greater than or equal to 0")
}
return nil
}
func (i VerSegCompInt) Compare(other VerSegComp) int {
otherTyped := other.(VerSegCompInt)
switch {
case i.I < otherTyped.I:
return -1
case i.I == otherTyped.I:
return 0
case i.I > otherTyped.I:
return 1
}
panic("unreachable")
}
func (i VerSegCompInt) AsString() string { return strconv.Itoa(i.I) }

View File

@@ -0,0 +1,43 @@
package version
import (
"errors"
"regexp"
)
var (
verSegCompStrRegexp = regexp.MustCompile(`\A[0-9A-Za-z_\-]+\z`)
)
type VerSegCompStr struct{ S string }
func NewVerSegCompStrFromString(piece string) (VerSegCompStr, bool) {
if !verSegCompStrRegexp.MatchString(piece) {
return VerSegCompStr{}, false
}
return VerSegCompStr{piece}, true
}
func (s VerSegCompStr) Validate() error {
if len(s.S) == 0 {
return errors.New("Expected string component to be non-empty")
}
return nil
}
func (s VerSegCompStr) Compare(other VerSegComp) int {
otherTyped := other.(VerSegCompStr)
switch {
case s.S < otherTyped.S:
return -1
case s.S == otherTyped.S:
return 0
case s.S > otherTyped.S:
return 1
}
panic("unreachable")
}
func (s VerSegCompStr) AsString() string { return s.S }

View File

@@ -0,0 +1,152 @@
package version
import (
"errors"
"fmt"
"regexp"
)
var (
versionRegexp = matchingRegexp{regexp.MustCompile(`\A(?P<release>[0-9A-Za-z_\.]+)(\-(?P<pre_release>[0-9A-Za-z_\-\.]+))?(\+(?P<post_release>[0-9A-Za-z_\-\.]+))?\z`)}
)
type matchingRegexp struct {
*regexp.Regexp
}
type Version struct {
Release, PreRelease, PostRelease VersionSegment
Segments []VersionSegment
}
func NewVersionFromString(v string) (Version, error) {
var err error
if len(v) == 0 {
return Version{}, errors.New("Expected version to be non-empty string")
}
captures := versionRegexp.FindStringSubmatchMap(v)
if len(captures) == 0 {
errMsg := fmt.Sprintf("Expected version '%s' to match version format", v)
return Version{}, errors.New(errMsg)
}
release := VersionSegment{}
preRelease := VersionSegment{}
postRelease := VersionSegment{}
if releaseStr, ok := captures["release"]; ok {
release, err = NewVersionSegmentFromString(releaseStr)
if err != nil {
return Version{}, err
}
}
if preReleaseStr, ok := captures["pre_release"]; ok {
preRelease, err = NewVersionSegmentFromString(preReleaseStr)
if err != nil {
return Version{}, err
}
}
if postReleaseStr, ok := captures["post_release"]; ok {
postRelease, err = NewVersionSegmentFromString(postReleaseStr)
if err != nil {
return Version{}, err
}
}
return NewVersion(release, preRelease, postRelease)
}
func NewVersion(release, preRelease, postRelease VersionSegment) (Version, error) {
if release.Empty() {
return Version{}, errors.New("Expected to non-empty release segment for constructing version")
}
version := Version{
Release: release,
PreRelease: preRelease,
PostRelease: postRelease,
Segments: []VersionSegment{release, preRelease, postRelease},
}
return version, nil
}
func (v Version) String() string { return v.AsString() }
func (v Version) AsString() string {
result := v.Release.AsString()
if !v.PreRelease.Empty() {
result += "-" + v.PreRelease.AsString()
}
if !v.PostRelease.Empty() {
result += "+" + v.PostRelease.AsString()
}
return result
}
func (v Version) Compare(other Version) int {
result := v.Release.Compare(other.Release)
if result != 0 {
return result
}
if !v.PreRelease.Empty() || !other.PreRelease.Empty() {
if v.PreRelease.Empty() {
return 1
}
if other.PreRelease.Empty() {
return -1
}
result = v.PreRelease.Compare(other.PreRelease)
if result != 0 {
return result
}
}
if !v.PostRelease.Empty() || !other.PostRelease.Empty() {
if v.PostRelease.Empty() {
return -1
}
if other.PostRelease.Empty() {
return 1
}
result = v.PostRelease.Compare(other.PostRelease)
if result != 0 {
return result
}
}
return 0
}
func (v Version) IsEq(other Version) bool { return v.Compare(other) == 0 }
func (v Version) IsGt(other Version) bool { return v.Compare(other) == 1 }
func (v Version) IsLt(other Version) bool { return v.Compare(other) == -1 }
func (r *matchingRegexp) FindStringSubmatchMap(s string) map[string]string {
captures := map[string]string{}
match := r.FindStringSubmatch(s)
if match == nil {
return captures
}
for i, name := range r.SubexpNames() {
// 0 is a whole regex
if i == 0 || name == "" || match[i] == "" {
continue
}
captures[name] = match[i]
}
return captures
}

View File

@@ -0,0 +1,143 @@
package version
import (
"errors"
"fmt"
"strings"
)
type VerSegComp interface {
Validate() error
// Compare should panic if incompatible interface is given
Compare(VerSegComp) int
AsString() string
}
type VersionSegment struct {
Components []VerSegComp
}
func NewVersionSegmentFromString(v string) (VersionSegment, error) {
pieces := strings.Split(v, ".")
components := []VerSegComp{}
for _, p := range pieces {
i, matchedI, err := NewVerSegCompIntFromString(p)
if err != nil {
errMsg := fmt.Sprintf("Expected component '%s' from version segment '%s' to be a parseable integer: %s", p, v, err)
return VersionSegment{}, errors.New(errMsg)
}
if matchedI {
components = append(components, i)
} else if s, matched := NewVerSegCompStrFromString(p); matched {
components = append(components, s)
} else {
errMsg := fmt.Sprintf("Expected component '%s' from version segment '%s' to be either an integer or a formatted string", p, v)
return VersionSegment{}, errors.New(errMsg)
}
}
return VersionSegment{components}, nil
}
func NewVersionSegment(components []VerSegComp) (VersionSegment, error) {
if len(components) == 0 {
return VersionSegment{}, errors.New("Expected version segment to be build from at least one component")
}
for _, c := range components {
err := c.Validate()
if err != nil {
return VersionSegment{}, err
}
}
return VersionSegment{components}, nil
}
func (s VersionSegment) Empty() bool { return len(s.Components) == 0 }
func (s VersionSegment) AsString() string {
result := ""
for i, c := range s.Components {
result += c.AsString()
if i < len(s.Components)-1 {
result += "."
}
}
return result
}
func (s VersionSegment) Compare(other VersionSegment) int {
a := s.Components
b := other.Components
if len(a) > len(b) {
comparison := s.compareArrays(a[0:len(b)], b)
if comparison != 0 {
return comparison
}
if !s.isAllZeros(a[len(b):len(a)]) {
return 1
}
return 0
}
if len(a) < len(b) {
comparison := s.compareArrays(a, b[0:len(a)])
if comparison != 0 {
return comparison
}
if !s.isAllZeros(b[len(a):len(b)]) {
return -1
}
return 0
}
return s.compareArrays(a, b)
}
func (s VersionSegment) IsEq(other VersionSegment) bool { return s.Compare(other) == 0 }
func (s VersionSegment) IsGt(other VersionSegment) bool { return s.Compare(other) == 1 }
func (s VersionSegment) IsLt(other VersionSegment) bool { return s.Compare(other) == -1 }
// compareArrays compares 2 equally sized a & b
func (s VersionSegment) compareArrays(a, b []VerSegComp) int {
for i, v1 := range a {
v2 := b[i]
_, v1IsStr := v1.(VerSegCompStr)
_, v1IsInt := v1.(VerSegCompInt)
_, v2IsStr := v2.(VerSegCompStr)
_, v2IsInt := v2.(VerSegCompInt)
if v1IsStr && v2IsInt {
return 1
} else if v1IsInt && v2IsStr {
return -1
}
comparison := v1.Compare(v2)
if comparison != 0 {
return comparison
}
}
return 0
}
func (s VersionSegment) isAllZeros(a []VerSegComp) bool {
for _, v := range a {
vTyped, ok := v.(VerSegCompInt)
if !ok || vTyped.I != 0 {
return false
}
}
return true
}