Skip to content

Commit 90673ff

Browse files
authored
Fixed tdnf provides parsing to recognize epochs in package names. (#10587)
1 parent ca8dcfa commit 90673ff

4 files changed

Lines changed: 121 additions & 27 deletions

File tree

toolkit/tools/imagegen/installutils/installutils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ func calculateTotalPackages(packages []string, installRoot string) (installedPac
820820
// end with an empty line.
821821
for _, line := range splitStdout {
822822
matches := tdnf.InstallPackageRegex.FindStringSubmatch(line)
823-
if len(matches) != tdnf.InstallMaxMatchLen {
823+
if len(matches) != tdnf.InstallPackageMaxMatchLen {
824824
// This line contains output other than a package information; skip it
825825
continue
826826
}

toolkit/tools/internal/packagerepo/repocloner/rpmrepocloner/rpmrepocloner.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,8 @@ func (r *RpmRepoCloner) WhatProvides(pkgVer *pkgjson.PackageVer) (packageNames [
474474
// MUST keep order of packages printed by TDNF.
475475
// TDNF will print the packages starting from the highest version, which allows us to work around an RPM bug:
476476
// https://github.com/rpm-software-management/rpm/issues/2359
477-
for _, matches := range tdnf.PackageLookupNameMatchRegex.FindAllStringSubmatch(stdout, -1) {
478-
packageName := matches[tdnf.PackageNameIndex]
477+
for _, matches := range tdnf.PackageProvidesRegex.FindAllStringSubmatch(stdout, -1) {
478+
packageName := matches[tdnf.PackageProvidesNameIndex]
479479
if lookupIgnoredCase {
480480
logger.Log.Warnf("'%s' was found by case-insensitive lookup of '%s', but this is not valid and will be ignored", packageName, pkgVer.Name)
481481
// This is not a valid mapping of requires -> provides, so we skip it. This is not a fatal error since
@@ -556,15 +556,15 @@ func (r *RpmRepoCloner) ClonedRepoContents() (repoContents *repocloner.RepoConte
556556
repoContents = &repocloner.RepoContents{}
557557
onStdout := func(line string) {
558558
matches := tdnf.ListedPackageRegex.FindStringSubmatch(line)
559-
if len(matches) != tdnf.ListMaxMatchLen {
559+
if len(matches) != tdnf.ListedPackageMaxMatchLen {
560560
return
561561
}
562562

563563
pkg := &repocloner.RepoPackage{
564-
Name: matches[tdnf.ListPackageName],
565-
Version: matches[tdnf.ListPackageVersion],
566-
Architecture: matches[tdnf.ListPackageArch],
567-
Distribution: matches[tdnf.ListPackageDist],
564+
Name: matches[tdnf.ListedPackageName],
565+
Version: matches[tdnf.ListedPackageVersion],
566+
Architecture: matches[tdnf.ListedPackageArch],
567+
Distribution: matches[tdnf.ListedPackageDist],
568568
}
569569

570570
pkgID := pkg.ID()

toolkit/tools/internal/tdnf/tdnf.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ var (
2828
// Repo : [repo_name]
2929
//
3030
// NOTE: we ignore packages installed in the build environment denoted by "Repo : @System".
31-
PackageLookupNameMatchRegex = regexp.MustCompile(`([^:\s]+(x86_64|aarch64|noarch))\s*:[^\n]*\nRepo\s+:\s+[^@]`)
32-
PackageNameIndex = 1
31+
PackageProvidesRegex = regexp.MustCompile(`(\S+)\s+:[^\n]*\nRepo\s+:\s+[^@]`)
3332

3433
// Tdnf may opt to ignore case when doing a provides lookup. While this is useful for a user, it will give
3534
// bad results when we're trying to match a package name to a package in the repo. This regex will match the
@@ -63,21 +62,27 @@ var (
6362
)
6463

6564
const (
66-
InstallMatchSubString = iota
67-
InstallPackageName = iota
68-
InstallPackageArch = iota
69-
InstallPackageVersion = iota
70-
InstallPackageDist = iota
71-
InstallMaxMatchLen = iota
65+
InstallPackageMatchSubString = iota
66+
InstallPackageName = iota
67+
InstallPackageArch = iota
68+
InstallPackageVersion = iota
69+
InstallPackageDist = iota
70+
InstallPackageMaxMatchLen = iota
7271
)
7372

7473
const (
75-
ListMatchSubString = iota
76-
ListPackageName = iota
77-
ListPackageArch = iota
78-
ListPackageVersion = iota
79-
ListPackageDist = iota
80-
ListMaxMatchLen = iota
74+
PackageProvidesMatchSubString = iota
75+
PackageProvidesNameIndex = iota
76+
PackageProvidesMaxMatchLen = iota
77+
)
78+
79+
const (
80+
ListedPackageMatchSubString = iota
81+
ListedPackageName = iota
82+
ListedPackageArch = iota
83+
ListedPackageVersion = iota
84+
ListedPackageDist = iota
85+
ListedPackageMaxMatchLen = iota
8186
)
8287

8388
const (

toolkit/tools/internal/tdnf/tdnf_test.go

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func TestInstallPackageRegex_MatchesPackageName(t *testing.T) {
7878

7979
matches := InstallPackageRegex.FindStringSubmatch(line)
8080

81-
assert.Len(t, matches, InstallMaxMatchLen)
81+
assert.Len(t, matches, InstallPackageMaxMatchLen)
8282
assert.Equal(t, "X", matches[InstallPackageName])
8383
}
8484

@@ -93,7 +93,7 @@ func TestInstallPackageRegex_MatchesPackageArch(t *testing.T) {
9393

9494
matches := InstallPackageRegex.FindStringSubmatch(line)
9595

96-
assert.Len(t, matches, InstallMaxMatchLen)
96+
assert.Len(t, matches, InstallPackageMaxMatchLen)
9797
assert.Equal(t, "aarch64", matches[InstallPackageArch])
9898
}
9999

@@ -108,7 +108,7 @@ func TestInstallPackageRegex_MatchesPackageVersionNoEpoch(t *testing.T) {
108108

109109
matches := InstallPackageRegex.FindStringSubmatch(line)
110110

111-
assert.Len(t, matches, InstallMaxMatchLen)
111+
assert.Len(t, matches, InstallPackageMaxMatchLen)
112112
assert.Equal(t, "1.1b.8_X-22~rc1", matches[InstallPackageVersion])
113113
}
114114

@@ -117,7 +117,7 @@ func TestInstallPackageRegex_MatchesPackageVersionWithEpoch(t *testing.T) {
117117

118118
matches := InstallPackageRegex.FindStringSubmatch(line)
119119

120-
assert.Len(t, matches, InstallMaxMatchLen)
120+
assert.Len(t, matches, InstallPackageMaxMatchLen)
121121
assert.Equal(t, "5:1.1b.8_X-22~rc1", matches[InstallPackageVersion])
122122
}
123123

@@ -132,7 +132,7 @@ func TestInstallPackageRegex_MatchesPackageDist(t *testing.T) {
132132

133133
matches := InstallPackageRegex.FindStringSubmatch(line)
134134

135-
assert.Len(t, matches, InstallMaxMatchLen)
135+
assert.Len(t, matches, InstallPackageMaxMatchLen)
136136
assert.Equal(t, "azl3", matches[InstallPackageDist])
137137
}
138138

@@ -153,3 +153,92 @@ func TestInstallPackageRegex_DoesNotMatchInvalidLine(t *testing.T) {
153153

154154
assert.False(t, InstallPackageRegex.MatchString(line))
155155
}
156+
func TestPackageLookupNameMatchRegex_MatchesExternalRepo(t *testing.T) {
157+
const line = "xz-devel-5.4.4-1.azl3.x86_64 : Header and development files for xz\nRepo : toolchain-repo"
158+
159+
matches := PackageProvidesRegex.FindStringSubmatch(line)
160+
161+
assert.Len(t, matches, PackageProvidesMaxMatchLen)
162+
assert.Equal(t, "xz-devel-5.4.4-1.azl3.x86_64", matches[PackageProvidesNameIndex])
163+
}
164+
165+
func TestPackageLookupNameMatchRegex_MatchesPackageWithEpoch(t *testing.T) {
166+
const line = "xz-devel-2:5.4.4-1.azl3.x86_64 : Header and development files for xz\nRepo : toolchain-repo"
167+
168+
matches := PackageProvidesRegex.FindStringSubmatch(line)
169+
170+
assert.Len(t, matches, PackageProvidesMaxMatchLen)
171+
assert.Equal(t, "xz-devel-2:5.4.4-1.azl3.x86_64", matches[PackageProvidesNameIndex])
172+
}
173+
174+
func TestPackageLookupNameMatchRegex_FailsForOutputWithoutRepo(t *testing.T) {
175+
const line = "xz-devel-5.4.4-1.azl3.x86_64 : Header and development files for xz"
176+
177+
assert.False(t, PackageProvidesRegex.MatchString(line))
178+
}
179+
180+
func TestPackageLookupNameMatchRegex_FailsForOutputWithSystemRepo(t *testing.T) {
181+
const line = "xz-devel-5.4.4-1.azl3.x86_64 : Header and development files for xz\nRepo : @System"
182+
183+
assert.False(t, PackageProvidesRegex.MatchString(line))
184+
}
185+
186+
func TestPackageLookupNameMatchRegex_FailsForEmptyOutput(t *testing.T) {
187+
const line = ""
188+
189+
assert.False(t, PackageProvidesRegex.MatchString(line))
190+
}
191+
192+
func TestPackageLookupNameMatchRegex_FailsForInvalidOutput(t *testing.T) {
193+
const line = "Invalid output line"
194+
195+
assert.False(t, PackageProvidesRegex.MatchString(line))
196+
}
197+
198+
func TestPackageLookupNameMatchRegex_MatchesOutputWithCapabilityMatch(t *testing.T) {
199+
const line = "[using capability match for 'pkgconfig(liblzma)'] xz-devel-5.4.4-1.azl3.x86_64 : Header and development files for xz\nRepo : toolchain-repo"
200+
201+
matches := PackageProvidesRegex.FindStringSubmatch(line)
202+
203+
assert.Len(t, matches, PackageProvidesMaxMatchLen)
204+
assert.Equal(t, "xz-devel-5.4.4-1.azl3.x86_64", matches[PackageProvidesNameIndex])
205+
}
206+
207+
func TestPackageLookupNameMatchRegex_MatchesOutputWithMultiplePackages(t *testing.T) {
208+
const line = "xz-devel-5.4.4-1.azl3.x86_64 : ABC\nRepo : toolchain-repo\nother-package-4.4.4-1.azl3.x86_64 : ABC2\nRepo : other-repo\n"
209+
210+
allMatches := PackageProvidesRegex.FindAllStringSubmatch(line, -1)
211+
212+
assert.Len(t, allMatches, 2)
213+
assert.Len(t, allMatches[0], PackageProvidesMaxMatchLen)
214+
assert.Equal(t, "xz-devel-5.4.4-1.azl3.x86_64", allMatches[0][PackageProvidesNameIndex])
215+
216+
assert.Len(t, allMatches[1], PackageProvidesMaxMatchLen)
217+
assert.Equal(t, "other-package-4.4.4-1.azl3.x86_64", allMatches[1][PackageProvidesNameIndex])
218+
}
219+
220+
func TestPackageLookupNameMatchRegex_MatchesOutputWithExternalAndSystemMix(t *testing.T) {
221+
const line = "xz-devel-5.4.4-1.azl3.x86_64 : ABC\nRepo : toolchain-repo\nother-package-4.4.4-1.azl3.x86_64 : ABC2\nRepo : @System\n"
222+
223+
allMatches := PackageProvidesRegex.FindAllStringSubmatch(line, -1)
224+
225+
assert.Len(t, allMatches, 1)
226+
assert.Len(t, allMatches[0], PackageProvidesMaxMatchLen)
227+
assert.Equal(t, "xz-devel-5.4.4-1.azl3.x86_64", allMatches[0][PackageProvidesNameIndex])
228+
}
229+
230+
func TestPackageLookupNameMatchRegex_MatchesOutputWithSystemFirstExternalSecond(t *testing.T) {
231+
const line = "other-package-4.4.4-1.azl3.x86_64 : ABC2\nRepo : @System\nxz-devel-5.4.4-1.azl3.x86_64 : ABC\nRepo : toolchain-repo"
232+
233+
allMatches := PackageProvidesRegex.FindAllStringSubmatch(line, -1)
234+
235+
assert.Len(t, allMatches, 1)
236+
assert.Len(t, allMatches[0], PackageProvidesMaxMatchLen)
237+
assert.Equal(t, "xz-devel-5.4.4-1.azl3.x86_64", allMatches[0][PackageProvidesNameIndex])
238+
}
239+
240+
func TestPackageLookupNameMatchRegex_FailsForOutputWithOnlyPluginLoaded(t *testing.T) {
241+
const line = "Loaded plugin: tdnfrepogpgcheck"
242+
243+
assert.False(t, PackageProvidesRegex.MatchString(line))
244+
}

0 commit comments

Comments
 (0)