Skip to content

Commit 94b7d45

Browse files
committed
Support dots in Kind name segment
CDI spec states that dots ('.') are allowed. Add support in parser for this. Signed-off-by: adrianc <[email protected]>
1 parent b5ab017 commit 94b7d45

File tree

6 files changed

+61
-41
lines changed

6 files changed

+61
-41
lines changed

pkg/cdi/qualified-device.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,10 @@ import (
2525
//
2626
// "<vendor>/<class>=<name>".
2727
//
28-
// A valid vendor name may contain the following runes:
28+
// A valid vendor and class name may contain the following runes:
2929
//
3030
// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'.
3131
//
32-
// A valid class name may contain the following runes:
33-
//
34-
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_'.
35-
//
3632
// A valid device name may containe the following runes:
3733
//
3834
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':'
@@ -98,7 +94,7 @@ func ValidateVendorName(vendor string) error {
9894
// A class name may contain the following ASCII characters:
9995
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
10096
// - digits ('0'-'9')
101-
// - underscore and dash ('_', '-')
97+
// - underscore, dash, and dot ('_', '-', and '.')
10298
//
10399
// Deprecated: use parser.ValidateClassName instead
104100
func ValidateClassName(class string) error {

pkg/cdi/qualified-device_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ func TestQualifiedName(t *testing.T) {
5454
name: "dev1",
5555
isQualified: true,
5656
},
57+
{
58+
device: "vendor1.com/class.subclass=dev1",
59+
vendor: "vendor1.com",
60+
class: "class.subclass",
61+
name: "dev1",
62+
isQualified: true,
63+
},
5764
{
5865
device: "other-vendor1.com/class_1=dev_1",
5966
vendor: "other-vendor1.com",

pkg/cdi/spec_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,13 @@ func TestRequiredVersion(t *testing.T) {
662662
},
663663
expectedVersion: "0.6.0",
664664
},
665+
{
666+
description: "dotted name (class) label require v0.6.0",
667+
spec: &cdi.Spec{
668+
Kind: "vendor.com/class.sub",
669+
},
670+
expectedVersion: "0.6.0",
671+
},
665672
}
666673

667674
for _, tc := range testCases {

pkg/cdi/version.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ func requiresV060(spec *cdi.Spec) bool {
132132
}
133133
}
134134

135+
// The v0.6.0 spec allows dots "." in Kind name label (class)
136+
vendor, class := parser.ParseQualifier(spec.Kind)
137+
if vendor != "" {
138+
if strings.ContainsRune(class, '.') {
139+
return true
140+
}
141+
}
142+
135143
return false
136144
}
137145

pkg/parser/parser.go

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,10 @@ import (
2626
//
2727
// "<vendor>/<class>=<name>".
2828
//
29-
// A valid vendor name may contain the following runes:
29+
// A valid vendor and class name may contain the following runes:
3030
//
3131
// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'.
3232
//
33-
// A valid class name may contain the following runes:
34-
//
35-
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_'.
36-
//
3733
// A valid device name may containe the following runes:
3834
//
3935
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':'
@@ -122,52 +118,51 @@ func ParseQualifier(kind string) (string, string) {
122118
// - digits ('0'-'9')
123119
// - underscore, dash, and dot ('_', '-', and '.')
124120
func ValidateVendorName(vendor string) error {
125-
if vendor == "" {
126-
return fmt.Errorf("invalid (empty) vendor name")
127-
}
128-
if !IsLetter(rune(vendor[0])) {
129-
return fmt.Errorf("invalid vendor %q, should start with letter", vendor)
130-
}
131-
for _, c := range string(vendor[1 : len(vendor)-1]) {
132-
switch {
133-
case IsAlphaNumeric(c):
134-
case c == '_' || c == '-' || c == '.':
135-
default:
136-
return fmt.Errorf("invalid character '%c' in vendor name %q",
137-
c, vendor)
138-
}
139-
}
140-
if !IsAlphaNumeric(rune(vendor[len(vendor)-1])) {
141-
return fmt.Errorf("invalid vendor %q, should end with a letter or digit", vendor)
121+
err := validateVendorOrClassName(vendor)
122+
if err != nil {
123+
err = fmt.Errorf("invalid vendor. %w", err)
142124
}
143-
144-
return nil
125+
return err
145126
}
146127

147128
// ValidateClassName checks the validity of class name.
148129
// A class name may contain the following ASCII characters:
149130
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
150131
// - digits ('0'-'9')
151-
// - underscore and dash ('_', '-')
132+
// - underscore, dash, and dot ('_', '-', and '.')
152133
func ValidateClassName(class string) error {
153-
if class == "" {
154-
return fmt.Errorf("invalid (empty) device class")
134+
err := validateVendorOrClassName(class)
135+
if err != nil {
136+
err = fmt.Errorf("invalid class. %w", err)
155137
}
156-
if !IsLetter(rune(class[0])) {
157-
return fmt.Errorf("invalid class %q, should start with letter", class)
138+
return err
139+
}
140+
141+
// validateVendorOrClassName checks the validity of vendor or class name.
142+
// A name may contain the following ASCII characters:
143+
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
144+
// - digits ('0'-'9')
145+
// - underscore, dash, and dot ('_', '-', and '.')
146+
func validateVendorOrClassName(name string) error {
147+
if name == "" {
148+
return fmt.Errorf("empty name")
158149
}
159-
for _, c := range string(class[1 : len(class)-1]) {
150+
if !IsLetter(rune(name[0])) {
151+
return fmt.Errorf("%q, should start with letter", name)
152+
}
153+
for _, c := range string(name[1 : len(name)-1]) {
160154
switch {
161155
case IsAlphaNumeric(c):
162-
case c == '_' || c == '-':
156+
case c == '_' || c == '-' || c == '.':
163157
default:
164-
return fmt.Errorf("invalid character '%c' in device class %q",
165-
c, class)
158+
return fmt.Errorf("invalid character '%c' in name %q",
159+
c, name)
166160
}
167161
}
168-
if !IsAlphaNumeric(rune(class[len(class)-1])) {
169-
return fmt.Errorf("invalid class %q, should end with a letter or digit", class)
162+
if !IsAlphaNumeric(rune(name[len(name)-1])) {
163+
return fmt.Errorf("%q, should end with a letter or digit", name)
170164
}
165+
171166
return nil
172167
}
173168

pkg/parser/parser_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ func TestQualifiedName(t *testing.T) {
5454
name: "dev1",
5555
isQualified: true,
5656
},
57+
{
58+
device: "vendor1.com/class.subclass=dev1",
59+
vendor: "vendor1.com",
60+
class: "class.subclass",
61+
name: "dev1",
62+
isQualified: true,
63+
},
5764
{
5865
device: "other-vendor1.com/class_1=dev_1",
5966
vendor: "other-vendor1.com",

0 commit comments

Comments
 (0)