Skip to content

Commit 3f9e62b

Browse files
authored
Merge pull request rmohr#80 from kellyma2/rpmtree
Add support for generating lockfiles to rpmtree
2 parents f8b077c + 6cd5c31 commit 3f9e62b

File tree

7 files changed

+226
-49
lines changed

7 files changed

+226
-49
lines changed

README.md

+29
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,35 @@ the `--nobest` option can be supplied. With this option all packages are
234234
considered. Newest packages will have the higest weight but it may not always be
235235
able to choose them and older packages may be pulled in instead.
236236

237+
### Lock files
238+
239+
bazeldnf can use lock files as the source of RPMs in lieu of using the WORKSPACE file. These
240+
can be hand written or generated with `bazeldnf rpmtree` similarly to how WORKSPACE files work.
241+
Lock files can *only* be used when working in bzlmod mode, not in workspace mode.
242+
243+
To generate lock files you can run the following:
244+
245+
```bash
246+
bazeldnf rpmtree --lockfile rpms.json --configname myrpms --name libvirttree libvirt
247+
```
248+
249+
The lock file JSON format is as follows:
250+
```
251+
{
252+
"name": "bazeldnf-rpms",
253+
"rpms": [
254+
{
255+
"name": "libvirt-libs",
256+
"sha256": "aac272a2ace134b5ef60a41e6624deb24331e79c76699ef6cef0dca22d94ac7e",
257+
"urls": [
258+
"https://kojipkgs.fedoraproject.org//packages/libvirt/11.0.0/1.fc42/x86_64/libvirt-libs-11.0.0-1.fc42.x86_64.rpm"
259+
]
260+
}
261+
]
262+
}
263+
264+
```
265+
237266
### Dependency resolution limitations
238267

239268
##### Missing features

cmd/rpmtree.go

+125-38
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55

66
"github.com/bazelbuild/buildtools/build"
77
"github.com/rmohr/bazeldnf/cmd/template"
8+
"github.com/rmohr/bazeldnf/pkg/api"
9+
"github.com/rmohr/bazeldnf/pkg/api/bazeldnf"
810
"github.com/rmohr/bazeldnf/pkg/bazel"
911
"github.com/rmohr/bazeldnf/pkg/reducer"
1012
"github.com/rmohr/bazeldnf/pkg/repo"
@@ -21,22 +23,117 @@ type rpmtreeOpts struct {
2123
workspace string
2224
toMacro string
2325
buildfile string
26+
configname string
27+
lockfile string
2428
name string
2529
public bool
2630
forceIgnoreRegex []string
2731
}
2832

2933
var rpmtreeopts = rpmtreeOpts{}
3034

35+
type Handler interface {
36+
Process(pkgs []*api.Package, arch string, buildfile *build.File) error
37+
Write() error
38+
}
39+
40+
type MacroHandler struct {
41+
bzl, defName string
42+
bzlfile *build.File
43+
}
44+
45+
func NewMacroHandler(toMacro string) (Handler, error) {
46+
bzl, defName, err := bazel.ParseMacro(rpmtreeopts.toMacro)
47+
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
bzlfile, err := bazel.LoadBzl(bzl)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
return &MacroHandler{
58+
bzl: bzl,
59+
bzlfile: bzlfile,
60+
defName: defName,
61+
}, nil
62+
}
63+
64+
func (h *MacroHandler) Process(pkgs []*api.Package, arch string, buildfile *build.File) error {
65+
if err := bazel.AddBzlfileRPMs(h.bzlfile, h.defName, pkgs, arch); err != nil {
66+
return err
67+
}
68+
69+
bazel.PruneBzlfileRPMs(buildfile, h.bzlfile, h.defName)
70+
return nil
71+
}
72+
73+
func (h *MacroHandler) Write() error {
74+
return bazel.WriteBzl(false, h.bzlfile, h.bzl)
75+
}
76+
77+
type WorkspaceHandler struct {
78+
workspace string
79+
workspacefile *build.File
80+
}
81+
82+
func NewWorkspaceHandler(workspace string) (Handler, error) {
83+
workspacefile, err := bazel.LoadWorkspace(workspace)
84+
if err != nil {
85+
return nil, err
86+
}
87+
88+
return &WorkspaceHandler{
89+
workspace: workspace,
90+
workspacefile: workspacefile,
91+
}, nil
92+
}
93+
94+
func (h *WorkspaceHandler) Process(pkgs []*api.Package, arch string, buildfile *build.File) error {
95+
if err := bazel.AddWorkspaceRPMs(h.workspacefile, pkgs, arch); err != nil {
96+
return err
97+
}
98+
99+
bazel.PruneWorkspaceRPMs(buildfile, h.workspacefile)
100+
return nil
101+
}
102+
103+
func (h *WorkspaceHandler) Write() error {
104+
return bazel.WriteWorkspace(false, h.workspacefile, h.workspace)
105+
}
106+
107+
type LockFileHandler struct {
108+
filename string
109+
config *bazeldnf.Config
110+
}
111+
112+
func NewLockFileHandler(configname, filename string) (Handler, error) {
113+
return &LockFileHandler{
114+
filename: filename,
115+
config: &bazeldnf.Config{
116+
Name: configname,
117+
RPMs: []bazeldnf.RPM{},
118+
},
119+
}, nil
120+
}
121+
122+
func (h *LockFileHandler) Process(pkgs []*api.Package, arch string, buildfile *build.File) error {
123+
return bazel.AddConfigRPMs(h.config, pkgs, arch)
124+
}
125+
126+
func (h *LockFileHandler) Write() error {
127+
return bazel.WriteLockFile(h.config, h.filename)
128+
}
129+
31130
func NewRpmTreeCmd() *cobra.Command {
32131

33132
rpmtreeCmd := &cobra.Command{
34133
Use: "rpmtree",
35134
Short: "Writes a rpmtree rule and its rpmdependencies to bazel files",
36135
Args: cobra.MinimumNArgs(1),
37136
RunE: func(cmd *cobra.Command, required []string) error {
38-
writeToMacro := rpmtreeopts.toMacro != ""
39-
40137
repos, err := repo.LoadRepoFiles(rpmtreeopts.repofiles)
41138
if err != nil {
42139
return err
@@ -68,54 +165,42 @@ func NewRpmTreeCmd() *cobra.Command {
68165
if err != nil {
69166
return err
70167
}
71-
workspace, err := bazel.LoadWorkspace(rpmtreeopts.workspace)
168+
169+
var handler Handler
170+
var configname string
171+
172+
if rpmtreeopts.toMacro != "" {
173+
handler, err = NewMacroHandler(rpmtreeopts.toMacro)
174+
} else if rpmtreeopts.lockfile != "" {
175+
configname = rpmtreeopts.configname
176+
handler, err = NewLockFileHandler(
177+
rpmtreeopts.configname,
178+
rpmtreeopts.lockfile,
179+
)
180+
} else {
181+
handler, err = NewWorkspaceHandler(rpmtreeopts.workspace)
182+
}
183+
72184
if err != nil {
73185
return err
74186
}
75-
var bzlfile *build.File
76-
var bzl, defName string
77-
if writeToMacro {
78-
bzl, defName, err = bazel.ParseMacro(rpmtreeopts.toMacro)
79-
if err != nil {
80-
return err
81-
}
82-
bzlfile, err = bazel.LoadBzl(bzl)
83-
if err != nil {
84-
return err
85-
}
86-
}
187+
87188
build, err := bazel.LoadBuild(rpmtreeopts.buildfile)
88189
if err != nil {
89190
return err
90191
}
91-
if writeToMacro {
92-
err = bazel.AddBzlfileRPMs(bzlfile, defName, install, rpmtreeopts.arch)
93-
if err != nil {
94-
return err
95-
}
96-
} else {
97-
err = bazel.AddWorkspaceRPMs(workspace, install, rpmtreeopts.arch)
98-
if err != nil {
99-
return err
100-
}
101-
}
102-
bazel.AddTree(rpmtreeopts.name, build, install, rpmtreeopts.arch, rpmtreeopts.public)
103-
if writeToMacro {
104-
bazel.PruneBzlfileRPMs(build, bzlfile, defName)
105-
} else {
106-
bazel.PruneWorkspaceRPMs(build, workspace)
192+
bazel.AddTree(rpmtreeopts.name, configname, build, install, rpmtreeopts.arch, rpmtreeopts.public)
193+
194+
if err := handler.Process(install, rpmtreeopts.arch, build); err != nil {
195+
return err
107196
}
197+
108198
logrus.Info("Writing bazel files.")
109-
err = bazel.WriteWorkspace(false, workspace, rpmtreeopts.workspace)
199+
err = handler.Write()
110200
if err != nil {
111201
return err
112202
}
113-
if writeToMacro {
114-
err = bazel.WriteBzl(false, bzlfile, bzl)
115-
if err != nil {
116-
return err
117-
}
118-
}
203+
119204
err = bazel.WriteBuild(false, build, rpmtreeopts.buildfile)
120205
if err != nil {
121206
return err
@@ -136,6 +221,8 @@ func NewRpmTreeCmd() *cobra.Command {
136221
rpmtreeCmd.Flags().StringVarP(&rpmtreeopts.workspace, "workspace", "w", "WORKSPACE", "Bazel workspace file")
137222
rpmtreeCmd.Flags().StringVarP(&rpmtreeopts.toMacro, "to-macro", "", "", "Tells bazeldnf to write the RPMs to a macro in the given bzl file instead of the WORKSPACE file. The expected format is: macroFile%defName")
138223
rpmtreeCmd.Flags().StringVarP(&rpmtreeopts.buildfile, "buildfile", "b", "rpm/BUILD.bazel", "Build file for RPMs")
224+
rpmtreeCmd.Flags().StringVar(&rpmtreeopts.configname, "configname", "rpms", "config name to use in lockfile")
225+
rpmtreeCmd.Flags().StringVar(&rpmtreeopts.lockfile, "lockfile", "", "lockfile for RPMs")
139226
rpmtreeCmd.Flags().StringVar(&rpmtreeopts.name, "name", "", "rpmtree rule name")
140227
rpmtreeCmd.Flags().StringArrayVar(&rpmtreeopts.forceIgnoreRegex, "force-ignore-with-dependencies", []string{}, "Packages matching these regex patterns will not be installed. Allows force-removing unwanted dependencies. Be careful, this can lead to hidden missing dependencies.")
141228
rpmtreeCmd.MarkFlagRequired("name")

pkg/api/bazeldnf/BUILD.bazel

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ load("@rules_go//go:def.bzl", "go_library")
22

33
go_library(
44
name = "bazeldnf",
5-
srcs = ["repo.go"],
5+
srcs = [
6+
"config.go",
7+
"repo.go",
8+
],
69
importpath = "github.com/rmohr/bazeldnf/pkg/api/bazeldnf",
710
visibility = ["//visibility:public"],
811
)

pkg/api/bazeldnf/config.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package bazeldnf
2+
3+
type RPM struct {
4+
Name string `json:"name"`
5+
SHA256 string `json:"sha256"`
6+
URLs []string `json:"urls"`
7+
}
8+
9+
type Config struct {
10+
Name string `json:"name"`
11+
RPMs []RPM `json:"rpms"`
12+
}

pkg/bazel/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ go_library(
77
visibility = ["//visibility:public"],
88
deps = [
99
"//pkg/api",
10+
"//pkg/api/bazeldnf",
1011
"@com_github_bazelbuild_buildtools//build:go_default_library",
1112
"@com_github_bazelbuild_buildtools//edit:go_default_library",
1213
],

0 commit comments

Comments
 (0)