Skip to content

Commit 42cb494

Browse files
committed
Refactor version checks
Signed-off-by: Evan Lezar <[email protected]>
1 parent 8729204 commit 42cb494

File tree

3 files changed

+52
-44
lines changed

3 files changed

+52
-44
lines changed

pkg/cdi/spec.go

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,6 @@ const (
3737
)
3838

3939
var (
40-
// Valid CDI Spec versions.
41-
validSpecVersions = map[string]struct{}{
42-
"0.1.0": {},
43-
"0.2.0": {},
44-
"0.3.0": {},
45-
"0.4.0": {},
46-
"0.5.0": {},
47-
}
48-
4940
// Externally set CDI Spec validation function.
5041
specValidator func(*cdi.Spec) error
5142
validatorLock sync.RWMutex
@@ -214,12 +205,12 @@ func (s *Spec) validate() (map[string]*Device, error) {
214205
return nil, err
215206
}
216207

217-
minVersion, err := s.MinimumRequiredVersion()
208+
minVersion, err := MinimumRequiredVersion(s.Spec)
218209
if err != nil {
219-
return nil, errors.Errorf("could not determine minumum required version: %v", err)
210+
return nil, fmt.Errorf("could not determine minumum required version: %v", err)
220211
}
221-
if semver.Compare("v"+s.Version, "v"+minVersion) < 0 {
222-
return nil, errors.Errorf("the spec version must be at least v%v", minVersion)
212+
if newVersion(minVersion).IsGreaterThan(newVersion(s.Version)) {
213+
return nil, fmt.Errorf("the spec version must be at least v%v", minVersion)
223214
}
224215

225216
if err := ValidateVendorName(s.vendor); err != nil {
@@ -249,19 +240,13 @@ func (s *Spec) validate() (map[string]*Device, error) {
249240

250241
// validateVersion checks whether the specified spec version is supported.
251242
func validateVersion(version string) error {
252-
if _, ok := validSpecVersions[version]; !ok {
243+
if !validSpecVersions.isValidVersion(version) {
253244
return fmt.Errorf("invalid version %q", version)
254245
}
255246

256247
return nil
257248
}
258249

259-
// MinimumRequiredVersion checks the minimum required version for the spec
260-
func (s *Spec) MinimumRequiredVersion() (string, error) {
261-
minVersion := required.minVersion(s.Spec)
262-
return minVersion.String(), nil
263-
}
264-
265250
// ParseSpec parses CDI Spec data into a raw CDI Spec.
266251
func ParseSpec(data []byte) (*cdi.Spec, error) {
267252
var raw *cdi.Spec

pkg/cdi/spec_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,7 @@ func TestRequiredVersion(t *testing.T) {
634634

635635
for _, tc := range testCases {
636636
t.Run(tc.description, func(t *testing.T) {
637-
s := Spec{Spec: tc.spec}
638-
639-
v, err := s.MinimumRequiredVersion()
637+
v, err := MinimumRequiredVersion(tc.spec)
640638
require.NoError(t, err)
641639

642640
require.Equal(t, tc.expectedVersion, v)

pkg/cdi/version.go

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,57 @@ import (
2525
)
2626

2727
const (
28-
// CurrentVersion is the current vesion of the CDI Spec.
28+
// CurrentVersion is the current version of the CDI Spec.
2929
CurrentVersion = cdi.CurrentVersion
3030

31+
// vCurrent is the current version as a semver-comparable type
3132
vCurrent version = "v" + CurrentVersion
3233

33-
vEarliest version = v020
34-
34+
// These represent the released versions of the CDI specification
35+
v010 version = "v0.1.0"
3536
v020 version = "v0.2.0"
3637
v030 version = "v0.3.0"
3738
v040 version = "v0.4.0"
3839
v050 version = "v0.5.0"
40+
41+
// vEarliest is the earliest supported version of the CDI specification
42+
vEarliest version = v020
3943
)
4044

45+
// validSpecVersions stores a map of spec versions to functions to check the required versions.
46+
// Adding new fields / spec versions requires that a `requiredFunc` be implemented and
47+
// this map be updated.
48+
var validSpecVersions = requiredVersionMap{
49+
v010: nil,
50+
v020: nil,
51+
v030: nil,
52+
v040: requiresV040,
53+
v050: requiresV050,
54+
}
55+
56+
// MinimumRequiredVersion determines the minumum spec version for the input spec.
57+
func MinimumRequiredVersion(spec *cdi.Spec) (string, error) {
58+
minVersion := validSpecVersions.requiredVersion(spec)
59+
return minVersion.String(), nil
60+
}
61+
4162
// version represents a semantic version string
4263
type version string
4364

65+
// newVersion creates a version that can be used for semantic version comparisons.
66+
func newVersion(v string) version {
67+
return version("v" + strings.TrimPrefix(v, "v"))
68+
}
69+
4470
// String returns the string representation of the version.
4571
// This trims a leading v if present.
4672
func (v version) String() string {
4773
return strings.TrimPrefix(string(v), "v")
4874
}
4975

50-
// LT checks whether a version is less than the specified version.
51-
// Semantic versioning is used to perform the comparison.
52-
func (v version) LT(o version) bool {
53-
return semver.Compare(string(v), string(o)) < 0
76+
// IsGreaterThan checks with a version is greater than the specified version.
77+
func (v version) IsGreaterThan(o version) bool {
78+
return semver.Compare(string(v), string(o)) > 0
5479
}
5580

5681
// IsLatest checks whether the version is the latest supported version
@@ -62,24 +87,24 @@ type requiredFunc func(*cdi.Spec) bool
6287

6388
type requiredVersionMap map[version]requiredFunc
6489

65-
// required stores a map of spec versions to functions to check the required versions.
66-
// Adding new fields / spec versions requires that a `requiredFunc` be implemented and
67-
// this map be updated.
68-
var required = requiredVersionMap{
69-
v050: requiresV050,
70-
v040: requiresV040,
90+
// isValidVersion checks whether the specified version is valid.
91+
// A version is valid if it is contained in the required version map.
92+
func (r requiredVersionMap) isValidVersion(specVersion string) bool {
93+
_, ok := validSpecVersions[newVersion(specVersion)]
94+
95+
return ok
7196
}
7297

73-
// minVersion returns the minimum version required for the given spec
74-
func (r requiredVersionMap) minVersion(spec *cdi.Spec) version {
98+
// requiredVersion returns the minimum version required for the given spec
99+
func (r requiredVersionMap) requiredVersion(spec *cdi.Spec) version {
75100
minVersion := vEarliest
76101

77-
for specVersion := range validSpecVersions {
78-
v := version("v" + strings.TrimPrefix(specVersion, "v"))
79-
if f, ok := r[v]; ok {
80-
if f(spec) && minVersion.LT(v) {
81-
minVersion = v
82-
}
102+
for v, isRequired := range validSpecVersions {
103+
if isRequired == nil {
104+
continue
105+
}
106+
if isRequired(spec) && v.IsGreaterThan(minVersion) {
107+
minVersion = v
83108
}
84109
// If we have already detected the latest version then no later version could be detected
85110
if minVersion.IsLatest() {

0 commit comments

Comments
 (0)