forked from TrueCloudLab/neoneo-go
smartcontract: fix nef.GetVersion
It should be able to parse versions like `1.1.1-rc.1`. Close #1540.
This commit is contained in:
parent
e664657c8c
commit
9c3d8cd398
2 changed files with 88 additions and 60 deletions
|
@ -82,52 +82,51 @@ func NewFile(script []byte) (File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVersion returns Version from the given string. It accepts the following formats:
|
// GetVersion returns Version from the given string. It accepts the following formats:
|
||||||
// `major.minor.build-[...]`
|
// `major[-...].minor[-...].build[-...]` and `major[-...].minor[-...].build[-...].revision[-...]`
|
||||||
// `major.minor.build.revision-[...]`
|
|
||||||
// where `major`, `minor`, `build` and `revision` are 32-bit integers with base=10
|
// where `major`, `minor`, `build` and `revision` are 32-bit integers with base=10
|
||||||
func GetVersion(version string) (Version, error) {
|
func GetVersion(version string) (Version, error) {
|
||||||
var (
|
var (
|
||||||
result Version
|
result Version
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
versions := strings.SplitN(version, ".", 4)
|
versions := strings.SplitN(version, ".", 4)
|
||||||
if len(versions) < 3 {
|
if len(versions) < 3 {
|
||||||
return result, errors.New("invalid version format")
|
return result, errors.New("invalid version format")
|
||||||
}
|
}
|
||||||
major, err := strconv.ParseInt(versions[0], 10, 32)
|
result.Major, err = parseDashedVersion(versions[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse major version: %w", err)
|
return result, fmt.Errorf("failed to parse major version: %w", err)
|
||||||
}
|
}
|
||||||
result.Major = int32(major)
|
result.Minor, err = parseDashedVersion(versions[1])
|
||||||
|
|
||||||
minor, err := strconv.ParseInt(versions[1], 10, 32)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse minor version: %w", err)
|
return result, fmt.Errorf("failed to parse minor version: %w", err)
|
||||||
|
|
||||||
}
|
}
|
||||||
result.Minor = int32(minor)
|
result.Build, err = parseDashedVersion(versions[2])
|
||||||
|
|
||||||
b := versions[2]
|
|
||||||
if len(versions) == 3 {
|
|
||||||
b = strings.SplitN(b, "-", 2)[0]
|
|
||||||
}
|
|
||||||
build, err := strconv.ParseInt(b, 10, 32)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse build version: %w", err)
|
return result, fmt.Errorf("failed to parse build version: %w", err)
|
||||||
}
|
}
|
||||||
result.Build = int32(build)
|
|
||||||
|
|
||||||
if len(versions) == 4 {
|
if len(versions) == 4 {
|
||||||
r := strings.SplitN(versions[3], "-", 2)[0]
|
result.Revision, err = parseDashedVersion(versions[3])
|
||||||
revision, err := strconv.ParseInt(r, 10, 32)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse revision version: %w", err)
|
return result, fmt.Errorf("failed to parse revision version: %w", err)
|
||||||
}
|
}
|
||||||
result.Revision = int32(revision)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseDashedVersion extracts int from string of the format `int[-...]` where `int` is
|
||||||
|
// a 32-bit integer with base=10.
|
||||||
|
func parseDashedVersion(version string) (int32, error) {
|
||||||
|
version = strings.SplitN(version, "-", 2)[0]
|
||||||
|
result, err := strconv.ParseInt(version, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return int32(result), nil
|
||||||
|
}
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (v *Version) EncodeBinary(w *io.BinWriter) {
|
func (v *Version) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteU32LE(uint32(v.Major))
|
w.WriteU32LE(uint32(v.Major))
|
||||||
|
|
|
@ -93,48 +93,77 @@ func TestBytesFromBytes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetVersion(t *testing.T) {
|
func TestGetVersion(t *testing.T) {
|
||||||
_, err := GetVersion("qwerty")
|
testCases := map[string]struct {
|
||||||
require.Error(t, err)
|
input string
|
||||||
|
fails bool
|
||||||
_, err = GetVersion("1.pre")
|
expected Version
|
||||||
require.Error(t, err)
|
}{
|
||||||
|
"major only": {
|
||||||
_, err = GetVersion("1.1.pre")
|
input: "1",
|
||||||
require.Error(t, err)
|
fails: true,
|
||||||
|
},
|
||||||
_, err = GetVersion("1.1.1.pre")
|
"major and minor only": {
|
||||||
require.Error(t, err)
|
input: "1.1",
|
||||||
|
fails: true,
|
||||||
actual, err := GetVersion("1.1.1-pre")
|
},
|
||||||
require.NoError(t, err)
|
"major, minor and revision only": {
|
||||||
expected := Version{
|
input: "1.1.1",
|
||||||
|
expected: Version{
|
||||||
Major: 1,
|
Major: 1,
|
||||||
Minor: 1,
|
Minor: 1,
|
||||||
Build: 1,
|
Build: 1,
|
||||||
Revision: 0,
|
Revision: 0,
|
||||||
}
|
},
|
||||||
require.Equal(t, expected, actual)
|
},
|
||||||
|
"full version": {
|
||||||
actual, err = GetVersion("0.90.0-pre")
|
input: "1.1.1.1",
|
||||||
require.NoError(t, err)
|
expected: Version{
|
||||||
expected = Version{
|
|
||||||
Major: 0,
|
|
||||||
Minor: 90,
|
|
||||||
Build: 0,
|
|
||||||
Revision: 0,
|
|
||||||
}
|
|
||||||
require.Equal(t, expected, actual)
|
|
||||||
|
|
||||||
actual, err = GetVersion("1.1.1.1-pre")
|
|
||||||
require.NoError(t, err)
|
|
||||||
expected = Version{
|
|
||||||
Major: 1,
|
Major: 1,
|
||||||
Minor: 1,
|
Minor: 1,
|
||||||
Build: 1,
|
Build: 1,
|
||||||
Revision: 1,
|
Revision: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dashed, without revision": {
|
||||||
|
input: "1-pre.2-pre.3-pre",
|
||||||
|
expected: Version{
|
||||||
|
Major: 1,
|
||||||
|
Minor: 2,
|
||||||
|
Build: 3,
|
||||||
|
Revision: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dashed, full version": {
|
||||||
|
input: "1-pre.2-pre.3-pre.4-pre",
|
||||||
|
expected: Version{
|
||||||
|
Major: 1,
|
||||||
|
Minor: 2,
|
||||||
|
Build: 3,
|
||||||
|
Revision: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"dashed build": {
|
||||||
|
input: "1.2.3-pre.4",
|
||||||
|
expected: Version{
|
||||||
|
Major: 1,
|
||||||
|
Minor: 2,
|
||||||
|
Build: 3,
|
||||||
|
Revision: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"extra versions": {
|
||||||
|
input: "1.2.3.4.5",
|
||||||
|
fails: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, test := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
actual, err := GetVersion(test.input)
|
||||||
|
if test.fails {
|
||||||
|
require.NotNil(t, err)
|
||||||
|
} else {
|
||||||
|
require.Equal(t, test.expected, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
require.Equal(t, expected, actual)
|
|
||||||
|
|
||||||
_, err = GetVersion("1.1.1.1.1")
|
|
||||||
require.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue