pkg/validate/version_func.go (75 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package validate
import (
"regexp"
"strconv"
"strings"
"github.com/apache/servicecomb-service-center/pkg/util"
)
type VersionRegexp struct {
Regex *regexp.Regexp
Fuzzy bool
}
func (vr *VersionRegexp) MatchString(s string) bool {
if vr.Regex != nil && !vr.Regex.MatchString(s) {
return false
}
return vr.validateVersionRule(s) == nil
}
func (vr *VersionRegexp) String() string {
if vr.Fuzzy {
return "the form x[.y[.z]] or x[.y[.z]]+ or x[.y[.z]]-x[.y[.z]] or 'latest' where x y and z are 0-32767 range"
}
return "the form x[.y[.z]] where x y and z are 0-32767 range"
}
func (vr *VersionRegexp) validateVersionRule(versionRule string) (err error) {
if len(versionRule) == 0 {
return
}
if !vr.Fuzzy {
_, err = VersionToInt64(versionRule)
return
}
rangeIdx := strings.Index(versionRule, "-")
switch {
case versionRule == "latest":
return
case versionRule[len(versionRule)-1:] == "+":
// 取最低版本及高版本集合
start := versionRule[:len(versionRule)-1]
_, err = VersionToInt64(start)
case rangeIdx > 0:
// 取版本范围集合
start := versionRule[:rangeIdx]
end := versionRule[rangeIdx+1:]
if _, err = VersionToInt64(start); err == nil {
_, err = VersionToInt64(end)
}
default:
// 精确匹配
_, err = VersionToInt64(versionRule)
}
return
}
func NewVersionRegexp(fuzzy bool) (vr *VersionRegexp) {
vr = &VersionRegexp{Fuzzy: fuzzy}
if fuzzy {
vr.Regex, _ = regexp.Compile(`^\d+(\.\d+){0,3}\+?$|^\d+(\.\d+){0,3}-\d+(\.\d+){0,3}$|^latest$`)
return
}
vr.Regex, _ = regexp.Compile(`^\d+(\.\d+){0,3}$`)
return
}
func VersionToInt64(versionStr string) (int64, error) {
verBytes := [4]int16{}
for idx, i := 0, 0; i < 4 && idx < len(versionStr); i++ {
f := strings.IndexRune(versionStr[idx:], '.')
if f < 0 {
f = len(versionStr) - idx
}
integer, err := strconv.ParseInt(versionStr[idx:idx+f], 10, 16)
if err != nil {
return 0, err
}
verBytes[i] = int16(integer)
idx += f + 1
}
ret := util.Int16ToInt64(verBytes[:])
return ret, nil
}