-
Notifications
You must be signed in to change notification settings - Fork 79
distro: unify transform/match into a single concept #1682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,7 +43,7 @@ distros: | |
| - &fedora_stable | ||
| <<: *fedora_rawhide | ||
| name: "fedora-{{.MajorVersion}}" | ||
| match: "fedora-[0-9][0-9]{,[0-9]}" | ||
| match: 'fedora-[0-9][0-9]+' | ||
| preview: false | ||
| os_version: "{{.MajorVersion}}" | ||
| release_version: "{{.MajorVersion}}" | ||
|
|
@@ -63,7 +63,7 @@ distros: | |
|
|
||
| - &rhel10 | ||
| name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}" | ||
| match: "rhel-10.[0-9]{,[0-9]}" | ||
| match: 'rhel-10\.[0-9]{1,2}' | ||
| distro_like: rhel-10 | ||
| product: "Red Hat Enterprise Linux" | ||
| os_version: "10.{{.MinorVersion}}" | ||
|
|
@@ -115,7 +115,7 @@ distros: | |
|
|
||
| - <<: *rhel10 | ||
| name: "almalinux-{{.MajorVersion}}.{{.MinorVersion}}" | ||
| match: "almalinux-10.[0-9]{,[0-9]}" | ||
| match: 'almalinux-10\.[0-9]{1,2}' | ||
| product: "AlmaLinux" | ||
| vendor: "almalinux" | ||
| ostree_ref_tmpl: "almalinux/10/%%s/edge" | ||
|
|
@@ -150,9 +150,8 @@ distros: | |
|
|
||
| - &rhel9 | ||
| name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}" | ||
| match: "rhel-9.[0-9]{,[0-9]}" | ||
| # rhel9 support being named "rhel-91" for "rhel-9.1" or "rhel-910" for "rhel-9.10" etc | ||
| transform_re: "^(?P<name>rhel)-(?P<major>9)(?P<minor>[0-9]{1,2})$" | ||
| match: '(?P<name>rhel)-(?P<major>9)\.?(?P<minor>[0-9]{1,2})' | ||
| distro_like: rhel-9 | ||
| product: "Red Hat Enterprise Linux" | ||
| os_version: "9.{{.MinorVersion}}" | ||
|
|
@@ -217,9 +216,8 @@ distros: | |
|
|
||
| - &rhel8 | ||
| name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}" | ||
| match: "rhel-8.[0-9]{,[0-9]}" | ||
| # rhel8 support being named "rhel-81" for "rhel-8.1" or "rhel-810" for "rhel-8.10" etc | ||
| transform_re: "^(?P<name>rhel)-(?P<major>8)(?P<minor>[0-9]{1,2})$" | ||
| match: '(?P<name>rhel)-(?P<major>8)\.?(?P<minor>[0-9]{1,2})' | ||
| distro_like: rhel-8 | ||
| product: "Red Hat Enterprise Linux" | ||
| os_version: "8.{{.MinorVersion}}" | ||
|
|
@@ -289,7 +287,7 @@ distros: | |
|
|
||
| - &rhel7 | ||
| name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}" | ||
| match: "rhel-7.[0-9]{,[0-9]}" | ||
| match: 'rhel-7\.[0-9]{1,2}' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: the latest RHEL-7 is 7.9 and there won't be any newer one, so this could be really |
||
| distro_like: rhel-7 | ||
| product: "Red Hat Enterprise Linux" | ||
| codename: "Maipo" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,25 +7,59 @@ import ( | |
| "github.com/osbuild/images/pkg/distro" | ||
| ) | ||
|
|
||
| // matchAndNormalize() matches and normalizes the given nameVer | ||
| // based on the reStr. On match it returns the normalized version | ||
| // of the given nameVer. | ||
| func matchAndNormalize(reStr, nameVer string) (string, error) { | ||
| if reStr == "" { | ||
| return "", nil | ||
| } | ||
|
|
||
| re, err := regexp.Compile(`^` + reStr + `$`) | ||
| if err != nil { | ||
| return "", fmt.Errorf("cannot use %q: %w", reStr, err) | ||
| } | ||
| l := re.FindStringSubmatch(nameVer) | ||
| switch len(l) { | ||
| case 0: | ||
| // no match | ||
| return "", nil | ||
| case 1: | ||
| // simple match, no named matching | ||
| return nameVer, nil | ||
| case 2: | ||
| // incomplete match, user did not provide <name>,<major>,<minor> | ||
| return "", fmt.Errorf("invalid number of submatches for %q %q (%v)", reStr, nameVer, len(l)) | ||
|
Comment on lines
+30
to
+32
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be dropped, right? Since it's identical to the |
||
| case 3: | ||
| // distro only uses major ver and needs normalizing | ||
| return fmt.Sprintf("%s-%s", l[re.SubexpIndex("name")], l[re.SubexpIndex("major")]), nil | ||
| case 4: | ||
| // common case, major/minor and normalizing | ||
| return fmt.Sprintf("%s-%s.%s", l[re.SubexpIndex("name")], l[re.SubexpIndex("major")], l[re.SubexpIndex("minor")]), nil | ||
| default: | ||
| return "", fmt.Errorf("invalid number of submatches for %q %q (%v)", reStr, nameVer, len(l)) | ||
| } | ||
|
|
||
| } | ||
|
|
||
| // ParseID parse the given nameVer into a distro.ID. It will also | ||
| // apply any matching `transform_re`. This is needed to support distro | ||
| // names like "rhel-810" without dots. | ||
| // apply normalizations from the distros `match` rule. This is needed | ||
| // to support distro names like "rhel-810" without dots. | ||
| // | ||
| // If no transformations are needed it will return "nil" | ||
| // If no match is found it will "nil" and no error ( | ||
| func ParseID(nameVer string) (*distro.ID, error) { | ||
| distros, err := loadDistros() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| for _, d := range distros.Distros { | ||
| re, err := regexp.Compile(d.TransformRE) | ||
| found, err := matchAndNormalize(d.Match, nameVer) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| if l := re.FindStringSubmatch(nameVer); len(l) == 4 { | ||
| transformed := fmt.Sprintf("%s-%s.%s", l[re.SubexpIndex("name")], l[re.SubexpIndex("major")], l[re.SubexpIndex("minor")]) | ||
| return distro.ParseID(transformed) | ||
| if found != "" { | ||
| return distro.ParseID(found) | ||
| } | ||
| } | ||
| return nil, nil | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package defs | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func TestMatchAndNormalizeHappy(t *testing.T) { | ||
| for _, tc := range []struct { | ||
| reStr, nameVer string | ||
| expected string | ||
| }{ | ||
| // simple cases, no capture groups | ||
| {`rhel-10\.[0-9]{1,2}`, "rhel-100", ""}, | ||
| {`rhel-10\.[0-9]{1,2}`, "rhel-10.0", "rhel-10.0"}, | ||
| // capture groups for major/minor | ||
| {`(?P<name>rhel)-(?P<major>8)\.?(?P<minor>[0-9]{1,2})`, "rhel-8.10", "rhel-8.10"}, | ||
| {`(?P<name>rhel)-(?P<major>8)\.?(?P<minor>[0-9]{1,2})`, "rhel-810", "rhel-8.10"}, | ||
| // capture groups for just major | ||
| {`(?P<name>centos)-(?P<major>[0-9])stream`, "centos-9stream", "centos-9"}, | ||
| // normalizing strange things works | ||
| {`(?P<major>[0-9])-(?P<name>foo)`, "8-foo", "foo-8"}, | ||
| } { | ||
| found, err := matchAndNormalize(tc.reStr, tc.nameVer) | ||
| assert.NoError(t, err) | ||
| assert.Equal(t, found, tc.expected) | ||
| } | ||
| } | ||
|
|
||
| func TestMatchAndNormalizeSad(t *testing.T) { | ||
| for _, tc := range []struct { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to also test a case when the regex has a valid number of named match groups, but the names of the match groups are not what the code expects, i.e.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had the same thought |
||
| reStr, nameVer string | ||
| expectedErr string | ||
| }{ | ||
| // simple cases, bad regex | ||
| {`rhel-10[`, "rhel-100", `cannot use "rhel-10[": error parsing regexp: missing closing ]`}, | ||
| // incomplete capture groups | ||
| {`rhel-([0-9]+)`, "rhel-100", `invalid number of submatches for "rhel-([0-9]+)" "rhel-100" (2)`}, | ||
| // too many capture groups | ||
| {`(rhel)-([0-9])([0-9])([0-9])`, "rhel-100", `invalid number of submatches for "(rhel)-([0-9])([0-9])([0-9])" "rhel-100" (5)`}, | ||
| } { | ||
| _, err := matchAndNormalize(tc.reStr, tc.nameVer) | ||
| assert.ErrorContains(t, err, tc.expectedErr) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick, this should be ideally
fedora-[1-9][0-9]+, to not match i.e.fedora-043.