Skip to content

Commit 6187cf4

Browse files
committed
wip
1 parent 15b9e41 commit 6187cf4

File tree

3 files changed

+157
-11
lines changed

3 files changed

+157
-11
lines changed

cmd/bzlmod.go

Lines changed: 142 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package main
22

33
import (
4+
"cmp"
45
"encoding/json"
56
"fmt"
67
"os"
8+
"regexp"
79

810
"slices"
911

@@ -14,6 +16,7 @@ import (
1416
"github.com/rmohr/bazeldnf/pkg/sat"
1517
"github.com/sirupsen/logrus"
1618
"github.com/spf13/cobra"
19+
"golang.org/x/exp/maps"
1720
)
1821

1922
type BzlmodOpts struct {
@@ -122,8 +125,12 @@ func DumpJSON(result ResolvedResult, targets []string, cmdline []string) ([]byte
122125
}
123126

124127
alreadyInstalled := make(map[string]bool)
125-
packageNames := keys(allPackages)
128+
packageNames := sortedKeys(allPackages)
126129
for _, name := range packageNames {
130+
if _, ignored := forceIgnored[name]; ignored {
131+
continue
132+
}
133+
127134
requires := allPackages[name].Dependencies
128135
deps, err := computeDependencies(requires, providers, forceIgnored)
129136
if err != nil {
@@ -150,9 +157,13 @@ func DumpJSON(result ResolvedResult, targets []string, cmdline []string) ([]byte
150157
sortedPackages = append(sortedPackages, allPackages[name])
151158
}
152159

160+
ignoredPackages := sortedKeys(forceIgnored)
161+
162+
slices.Sort(ignoredPackages)
163+
153164
lockFile := BzlmodLockFile{
154165
CommandLineArguments: cmdline,
155-
ForceIgnored: keys(forceIgnored),
166+
ForceIgnored: ignoredPackages,
156167
Packages: sortedPackages,
157168
Repositories: make(map[string][]string),
158169
}
@@ -187,7 +198,128 @@ func computeDependencies(requires []string, providers map[string]string, ignored
187198
}
188199
deps[provider] = true
189200
}
190-
return keys(deps), nil
201+
return sortedKeys(deps), nil
202+
}
203+
204+
func shouldInclude(target string, ignoreRegex []string) bool {
205+
for _, rex := range ignoreRegex {
206+
if match, err := regexp.MatchString(rex, target); err != nil {
207+
logrus.Errorf("Failed to match package %s with regex '%v': %v", target, rex, err)
208+
return false
209+
} else if match {
210+
logrus.Debugf("will not include %s as it matched %s", target, rex)
211+
return false
212+
}
213+
}
214+
logrus.Debugf("including %s", target)
215+
return true
216+
}
217+
218+
func exploreAllDependenciesToExclude(input *api.Package, allPackages map[string]*api.Package, previouslyExplored map[string]bool) []*api.Package {
219+
alreadyExplored := make(map[string]*api.Package, 0)
220+
pending := []*api.Package{input}
221+
222+
for len(pending) > 0 {
223+
current := pending[0]
224+
pending = pending[1:]
225+
226+
if _, explored := previouslyExplored[current.Name]; explored {
227+
logrus.Debugf("previously explored %s", current.Name)
228+
continue
229+
}
230+
231+
if _, explored := alreadyExplored[current.Name]; explored {
232+
continue
233+
}
234+
235+
alreadyExplored[current.Name] = current
236+
237+
for _, entry := range current.Format.Requires.Entries {
238+
pending = append(pending, allPackages[entry.Name])
239+
}
240+
}
241+
242+
output := maps.Values(alreadyExplored)
243+
slices.SortStableFunc(output, func(a, b *api.Package) int {
244+
return cmp.Compare(a.Name, b.Name)
245+
})
246+
247+
return output
248+
}
249+
250+
func filterIgnores(rpmsRequested []string, allAvailable []*api.Package, ignoreRegex []string) ([]*api.Package, []*api.Package) {
251+
/*
252+
* Given a list of rpmsRequested and a list of ignoreRegex then go through all the resolved rpms
253+
* in allAvailable to install and filter only those needed.
254+
*/
255+
if len(ignoreRegex) == 0 {
256+
return allAvailable, []*api.Package{}
257+
}
258+
259+
allAvailablePerName := make(map[string]*api.Package, 0)
260+
261+
for _, rpm := range allAvailable {
262+
allAvailablePerName[rpm.Name] = rpm
263+
264+
for _, entry := range rpm.Format.Provides.Entries {
265+
allAvailablePerName[entry.Name] = rpm
266+
}
267+
268+
for _, entry := range rpm.Format.Files {
269+
allAvailablePerName[entry.Text] = rpm
270+
}
271+
}
272+
273+
toInstall := make([]*api.Package, 0)
274+
ignored := make(map[string]*api.Package, 0)
275+
276+
explored := make(map[string]bool, 0)
277+
for _, rpm := range rpmsRequested {
278+
target, ok := allAvailablePerName[rpm]
279+
if !ok {
280+
logrus.Errorf("failed to match %s", rpm)
281+
continue
282+
}
283+
284+
pending := []*api.Package{target}
285+
for len(pending) > 0 {
286+
current := pending[0]
287+
logrus.Debugf("processing %s", current.Name)
288+
pending = pending[1:]
289+
if _, alreadyExplored := explored[current.Name]; alreadyExplored {
290+
logrus.Debugf("already iterated")
291+
continue
292+
}
293+
294+
if !shouldInclude(current.Name, ignoreRegex) {
295+
toIgnore := exploreAllDependenciesToExclude(current, allAvailablePerName, explored)
296+
for _, d := range toIgnore {
297+
logrus.Debugf("excluding %s", d.Name)
298+
ignored[d.Name] = d
299+
explored[d.Name] = true
300+
}
301+
continue
302+
}
303+
304+
explored[current.Name] = true
305+
306+
toInstall = append(toInstall, current)
307+
for _, dep := range current.Format.Requires.Entries {
308+
logrus.Debugf("finding dependency provider for %s", dep.Name)
309+
p, ok := allAvailablePerName[dep.Name]
310+
if ok {
311+
pending = append(pending, p)
312+
}
313+
}
314+
}
315+
}
316+
317+
ignoredPackages := maps.Values(ignored)
318+
slices.SortStableFunc(ignoredPackages, func(a, b *api.Package) int {
319+
return cmp.Compare(a.Name, b.Name)
320+
})
321+
322+
return toInstall, ignoredPackages
191323
}
192324

193325
func (opts *BzlmodOpts) RunE(cmd *cobra.Command, rpms []string) error {
@@ -214,7 +346,7 @@ func (opts *BzlmodOpts) RunE(cmd *cobra.Command, rpms []string) error {
214346

215347
solver := sat.NewResolver(resolvehelperopts.nobest)
216348
logrus.Info("Loading involved packages into the rpmtreer.")
217-
err = solver.LoadInvolvedPackages(involved, resolvehelperopts.forceIgnoreRegex, resolvehelperopts.onlyAllowRegex)
349+
err = solver.LoadInvolvedPackages(involved, []string{}, resolvehelperopts.onlyAllowRegex)
218350
if err != nil {
219351
return err
220352
}
@@ -226,15 +358,19 @@ func (opts *BzlmodOpts) RunE(cmd *cobra.Command, rpms []string) error {
226358
}
227359

228360
logrus.Info("Solving.")
229-
install, _, forceIgnored, err := solver.Resolve()
361+
install, _, _, err := solver.Resolve()
230362
if err != nil {
231363
return err
232364
}
233365

234366
logrus.Debugf("install: %v", install)
367+
368+
actualInstall, forceIgnored := filterIgnores(rpms, install, resolvehelperopts.forceIgnoreRegex)
369+
370+
logrus.Debugf("actualInstall: %v", actualInstall)
235371
logrus.Debugf("forceIgnored: %v", forceIgnored)
236372

237-
result := ResolvedResult{Install: install, ForceIgnored: forceIgnored}
373+
result := ResolvedResult{Install: actualInstall, ForceIgnored: forceIgnored}
238374

239375
data, err := DumpJSON(result, rpms, os.Args[2:])
240376

cmd/config_helper.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"golang.org/x/exp/maps"
1212
)
1313

14-
func keys[K cmp.Ordered, V any](m map[K]V) []K {
14+
func sortedKeys[K cmp.Ordered, V any](m map[K]V) []K {
1515
keys := maps.Keys(m)
1616
slices.Sort(keys)
1717
return keys
@@ -45,7 +45,7 @@ func toConfig(install, forceIgnored []*api.Package, targets []string, cmdline []
4545
}
4646

4747
providers := collectProviders(forceIgnored, install)
48-
packageNames := keys(allPackages)
48+
packageNames := sortedKeys(allPackages)
4949
sortedPackages := make([]*bazeldnf.RPM, 0, len(packageNames))
5050
for _, name := range packageNames {
5151
pkg := allPackages[name]
@@ -61,7 +61,7 @@ func toConfig(install, forceIgnored []*api.Package, targets []string, cmdline []
6161

6262
lockFile := bazeldnf.Config{
6363
CommandLineArguments: cmdline,
64-
ForceIgnored: keys(ignored),
64+
ForceIgnored: sortedKeys(ignored),
6565
RPMs: sortedPackages,
6666
Repositories: repositories,
6767
Targets: targets,
@@ -107,7 +107,7 @@ func collectDependencies(pkg string, requires []string, providers map[string]str
107107
depSet[provider] = true
108108
}
109109

110-
deps := keys(depSet)
110+
deps := sortedKeys(depSet)
111111

112112
found := map[string]bool{pkg: true}
113113

e2e/bazel-bzlmod-toolchain-from-source-lock-file/bazeldnf-lock.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,18 @@
3333
"bash"
3434
],
3535
"ignored": [
36+
"basesystem",
37+
"fedora-gpg-keys",
38+
"fedora-repos",
3639
"filesystem",
40+
"generic-release",
41+
"generic-release-common",
3742
"glibc",
38-
"ncurses-libs"
43+
"glibc-all-langpacks",
44+
"glibc-common",
45+
"libgcc",
46+
"ncurses-base",
47+
"ncurses-libs",
48+
"setup"
3949
]
4050
}

0 commit comments

Comments
 (0)