Skip to content

Commit d0e3420

Browse files
authored
feat: --local-repo switch for building with private RPM repo (#394)
Unblocks local dev experiences where a package build may need to use RPMs from a local (private) path.
1 parent ad366ec commit d0e3420

5 files changed

Lines changed: 62 additions & 39 deletions

File tree

internal/app/azldev/cmds/component/build.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ type ComponentBuildOptions struct {
2626
RunChecks bool
2727
SourcePackageOnly bool
2828
BuildEnvPolicy BuildEnvPreservePolicy
29+
30+
LocalRepoPaths []string
2931
}
3032

3133
// ComponentBuildResults summarizes the results of building a single component.
@@ -72,6 +74,8 @@ func NewBuildCmd() *cobra.Command {
7274
BuildEnvPreserveAlways,
7375
BuildEnvPreserveNever,
7476
))
77+
cmd.Flags().StringArrayVar(&options.LocalRepoPaths, "local-repo", []string{},
78+
"Paths to local repositories to include during build (can be specified multiple times)")
7579

7680
return cmd
7781
}
@@ -169,13 +173,16 @@ func BuildComponent(
169173

170174
builder := componentbuilder.New(env, env.FS(), env, sourcePreparer, buildEnv, workDirFactory)
171175

172-
return buildComponentUsingBuilder(env, component, builder,
176+
return buildComponentUsingBuilder(env, component, builder, options.LocalRepoPaths,
173177
options.SourcePackageOnly, options.RunChecks,
174178
)
175179
}
176180

177181
func buildComponentUsingBuilder(
178-
env *azldev.Env, component components.Component, builder *componentbuilder.Builder,
182+
env *azldev.Env,
183+
component components.Component,
184+
builder *componentbuilder.Builder,
185+
localRepoPaths []string,
179186
sourcePackageOnly, runChecks bool,
180187
) (results ComponentBuildResults, err error) {
181188
// Compose the path to the output dir.
@@ -195,9 +202,7 @@ func buildComponentUsingBuilder(
195202
// Build the SRPM.
196203
//
197204

198-
var outputSourcePackagePath string
199-
200-
outputSourcePackagePath, err = builder.BuildSourcePackage(env, component, outputDir)
205+
outputSourcePackagePath, err := builder.BuildSourcePackage(env, component, localRepoPaths, outputDir)
201206
if err != nil {
202207
return results, fmt.Errorf("failed to build SRPM for %q:\n%w", component.GetName(), err)
203208
}
@@ -215,7 +220,9 @@ func buildComponentUsingBuilder(
215220
// Build the RPM.
216221
//
217222

218-
results.RPMPaths, err = builder.BuildBinaryPackage(env, component, outputSourcePackagePath, outputDir, runChecks)
223+
results.RPMPaths, err = builder.BuildBinaryPackage(
224+
env, component, outputSourcePackagePath, localRepoPaths, outputDir, runChecks,
225+
)
219226
if err != nil {
220227
return results, fmt.Errorf("failed to build RPM for %q: %w", component.GetName(), err)
221228
}

internal/app/azldev/core/componentbuilder/componentbuilder.go

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ type ComponentBuilder interface {
2626
// BuildBinaryPackage builds a binary package for the given component from the provided source package
2727
// and returns the paths to the built binary packages.
2828
BuildBinaryPackage(
29-
ctx context.Context, component components.Component, sourcePackagePath string, outputDir string, runChecks bool,
29+
ctx context.Context,
30+
component components.Component, sourcePackagePath string, localRepoPaths []string,
31+
outputDir string, runChecks bool,
3032
) (packagePaths []string, err error)
3133

3234
// BuildSourcePackage builds a source package for the given component and returns the path to the
3335
// built source package.
34-
BuildSourcePackage(ctx context.Context, component components.Component, outputDir string,
36+
BuildSourcePackage(ctx context.Context, component components.Component, localRepoPaths []string, outputDir string,
3537
) (packagePath string, err error)
3638
}
3739

@@ -66,9 +68,9 @@ func New(
6668
}
6769

6870
func (b *Builder) BuildSourcePackage(
69-
ctx context.Context, component components.Component, outputDir string,
71+
ctx context.Context, component components.Component, localRepoPaths []string, outputDir string,
7072
) (packagePath string, err error) { // NOTE: We intentionally name the returns for better self-documentation.
71-
packagePath, err = b.buildSRPM(ctx, component, b.buildEnv, outputDir)
73+
packagePath, err = b.buildSRPM(ctx, component, b.buildEnv, localRepoPaths, outputDir)
7274
if err != nil {
7375
return packagePath, fmt.Errorf("failed to build source package for component %#q:\n%w", component.GetName(), err)
7476
}
@@ -78,9 +80,10 @@ func (b *Builder) BuildSourcePackage(
7880

7981
func (b *Builder) BuildBinaryPackage(
8082
ctx context.Context,
81-
component components.Component, sourcePackagePath, outputDir string, runChecks bool,
83+
component components.Component, sourcePackagePath string, localRepoPaths []string,
84+
outputDir string, runChecks bool,
8285
) (packagePaths []string, err error) { // NOTE: We intentionally name the returns for better self-documentation.
83-
packagePaths, err = b.buildRPM(ctx, component, sourcePackagePath, b.buildEnv, outputDir, runChecks)
86+
packagePaths, err = b.buildRPM(ctx, component, sourcePackagePath, b.buildEnv, localRepoPaths, outputDir, runChecks)
8487
if err != nil {
8588
return packagePaths, fmt.Errorf("failed to build binary package for component %#q:\n%w", component.GetName(), err)
8689
}
@@ -89,14 +92,16 @@ func (b *Builder) BuildBinaryPackage(
8992
}
9093

9194
func (b *Builder) buildSRPM(
92-
ctx context.Context, component components.Component, buildEnv buildenv.RPMAwareBuildEnv, outputDir string,
95+
ctx context.Context, component components.Component, buildEnv buildenv.RPMAwareBuildEnv,
96+
localRepoPaths []string,
97+
outputDir string,
9398
) (outputSRPMPath string, err error) { // NOTE: We intentionally name the returns for better self-documentation.
9499
preparedSourcesDir, err := b.prepSourcesForSRPM(ctx, component)
95100
if err != nil {
96101
return "", fmt.Errorf("failed to prepare sources for SRPM:\n%w", err)
97102
}
98103

99-
tempSRPMOutputDir, err := b.buildSRPMFromPreparedSources(ctx, component, preparedSourcesDir, buildEnv)
104+
tempSRPMOutputDir, err := b.buildSRPMFromPreparedSources(ctx, component, preparedSourcesDir, buildEnv, localRepoPaths)
100105
if err != nil {
101106
return "", fmt.Errorf("failed to build SRPM from prepared sources:\n%w", err)
102107
}
@@ -129,7 +134,7 @@ func (b *Builder) prepSourcesForSRPM(
129134
func (b *Builder) buildSRPMFromPreparedSources(
130135
ctx context.Context,
131136
component components.Component, preparedSourcesDir string,
132-
buildEnv buildenv.RPMAwareBuildEnv,
137+
buildEnv buildenv.RPMAwareBuildEnv, localRepoPaths []string,
133138
) (srpmOutputDir string, err error) {
134139
preparedSpecPath := path.Join(preparedSourcesDir, component.GetName()+".spec")
135140

@@ -145,14 +150,14 @@ func (b *Builder) buildSRPMFromPreparedSources(
145150

146151
defer srpmEvent.End()
147152

148-
componentConfig := component.GetConfig()
149-
153+
// Since we've already applied the macros, with, and without values, we don't need the builder
154+
// to apply them; we leave them blank.
150155
srpmOptions := buildenv.SRPMBuildOptions{
151156
CommonBuildOptions: mock.CommonBuildOptions{
152-
With: componentConfig.Build.With,
153-
Without: componentConfig.Build.Without,
154-
Defines: componentConfig.Build.Defines,
155-
LocalRepoPaths: []string{},
157+
With: []string{},
158+
Without: []string{},
159+
Defines: map[string]string{},
160+
LocalRepoPaths: localRepoPaths,
156161
},
157162
}
158163

@@ -195,7 +200,7 @@ func (b *Builder) copySRPMToOutputDir(inputSRPMDir, outputSRPMDir string) (strin
195200
func (b *Builder) buildRPM(
196201
ctx context.Context,
197202
component components.Component,
198-
srpmPath string, buildEnv buildenv.RPMAwareBuildEnv,
203+
srpmPath string, buildEnv buildenv.RPMAwareBuildEnv, localRepoPaths []string,
199204
outputDir string, runChecks bool,
200205
) (outputRPMPaths []string, err error) { // NOTE: We intentionally name the returns for better self-documentation.
201206
var tempRPMDir string
@@ -211,15 +216,15 @@ func (b *Builder) buildRPM(
211216

212217
defer rpmEvent.End()
213218

214-
componentConfig := component.GetConfig()
215-
216219
// Compose RPM build options, based on our parameters and the component's default configuration.
220+
// Since we've already applied the macros, with, and without values, we don't need the builder
221+
// to apply them; we leave them blank.
217222
rpmOptions := buildenv.RPMBuildOptions{
218223
CommonBuildOptions: mock.CommonBuildOptions{
219-
With: componentConfig.Build.With,
220-
Without: componentConfig.Build.Without,
221-
Defines: componentConfig.Build.Defines,
222-
LocalRepoPaths: []string{},
224+
With: []string{},
225+
Without: []string{},
226+
Defines: map[string]string{},
227+
LocalRepoPaths: localRepoPaths,
223228
},
224229
RunChecks: runChecks,
225230
ForceRebuild: false, // Could be added to config if needed

internal/app/azldev/core/componentbuilder/componentbuilder_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ func TestBuildSourcePackage(t *testing.T) {
151151

152152
params.setupToBuildSRPM(t, testComponent)
153153

154-
path, err := params.builder.BuildSourcePackage(params.testEnv.Env, testComponent, testOutputDir)
154+
path, err := params.builder.BuildSourcePackage(params.testEnv.Env, testComponent, []string{}, testOutputDir)
155155
require.NoError(t, err)
156156
require.Equal(t, filepath.Join(testOutputDir, testComponent.GetName()+".src.rpm"), path)
157157
require.True(t, strings.HasPrefix(path, testOutputDir))
@@ -172,6 +172,7 @@ func TestBuildBinaryPackage(t *testing.T) {
172172
params.testEnv.Env,
173173
testComponent,
174174
testSRPMPath,
175+
[]string{},
175176
testOutputDir,
176177
false, /*runChecks?*/
177178
)

internal/app/azldev/core/componentbuilder/componentbuilder_test/componentbuilder_mocks.go

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/rpm/mock/mock.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,12 @@ func (r *Runner) BuildSRPM(
291291

292292
// If provided, pass along extra local repo dirs.
293293
for _, localRepoPath := range options.LocalRepoPaths {
294-
args = append(args, "--addrepo", localRepoPath)
294+
absLocalRepoPath, err := filepath.Abs(localRepoPath)
295+
if err != nil {
296+
return fmt.Errorf("failed to get absolute path for local repo %#q:\n%w", localRepoPath, err)
297+
}
298+
299+
args = append(args, "--addrepo", absLocalRepoPath)
295300
}
296301

297302
cmd := exec.CommandContext(ctx, MockBinary, args...)
@@ -337,7 +342,12 @@ func (r *Runner) BuildRPM(ctx context.Context, srpmPath, outputDirPath string, o
337342

338343
// If provided, pass along extra local repo dirs.
339344
for _, localRepoPath := range options.LocalRepoPaths {
340-
args = append(args, "--addrepo", localRepoPath)
345+
absLocalRepoPath, err := filepath.Abs(localRepoPath)
346+
if err != nil {
347+
return fmt.Errorf("failed to get absolute path for local repo %#q:\n%w", localRepoPath, err)
348+
}
349+
350+
args = append(args, "--addrepo", absLocalRepoPath)
341351
}
342352

343353
// If the output dir already contains a "relevant" binary RPM, mock

0 commit comments

Comments
 (0)