diff --git a/internal/rpm/mock/mock.go b/internal/rpm/mock/mock.go index 2ed9a0a8..05c87455 100644 --- a/internal/rpm/mock/mock.go +++ b/internal/rpm/mock/mock.go @@ -440,7 +440,11 @@ func (r *Runner) BuildRPM(ctx context.Context, srpmPath, outputDirPath string, o return fmt.Errorf("failed to create external command for mock:\n%w", err) } - extcmd = extcmd.SetLongRunning("Waiting for mock (building RPM)...") + // In verbose mode, mock streams its full build output to the console, so we skip the + // indeterminate progress spinner (which would otherwise fight with the live output). + if !r.verbose { + extcmd = extcmd.SetLongRunning("Waiting for mock (building RPM)...") + } // Watch output logs in real-time so we can asynchronously synthesize progress updates. err = addMockCmdListeners(r.eventListener, extcmd, outputDirPath) @@ -597,7 +601,11 @@ func (r *Runner) InstallPackages(ctx context.Context, packages []string) error { return fmt.Errorf("failed to create external command for mock:\n%w", err) } - extcmd = extcmd.SetLongRunning("Waiting for mock (installing packages)...") + // In verbose mode, mock streams its output directly to the console, so we skip the + // indeterminate progress spinner (which would otherwise fight with the live output). + if !r.verbose { + extcmd = extcmd.SetLongRunning("Waiting for mock (installing packages)...") + } err = extcmd.Run(ctx) if err != nil { @@ -633,7 +641,11 @@ func (r *Runner) ScrubRoot(ctx context.Context) error { return fmt.Errorf("failed to create external command for mock:\n%w", err) } - extcmd = extcmd.SetLongRunning("Waiting for mock (cleaning build root)...") + // In verbose mode, mock streams its output directly to the console, so we skip the + // indeterminate progress spinner (which would otherwise fight with the live output). + if !r.verbose { + extcmd = extcmd.SetLongRunning("Waiting for mock (cleaning build root)...") + } err = extcmd.Run(ctx) if err != nil { @@ -644,7 +656,10 @@ func (r *Runner) ScrubRoot(ctx context.Context) error { } func (r *Runner) getBaseArgs() (args []string) { - if !r.verbose { + if r.verbose { + // Have mock stream its full build output (including build.log) live to the console. + args = append(args, "--verbose") + } else { args = append(args, "--quiet") } diff --git a/internal/rpm/mock/mock_test.go b/internal/rpm/mock/mock_test.go index 96d5f148..3d402c9c 100644 --- a/internal/rpm/mock/mock_test.go +++ b/internal/rpm/mock/mock_test.go @@ -203,6 +203,52 @@ func TestBuildRPM(t *testing.T) { assert.Contains(t, mockCmd, fmt.Sprintf("--define %s %s", macroName, macroValue)) } +func TestBuildRPM_VerboseArgs(t *testing.T) { + t.Run("NonVerbose", func(t *testing.T) { + ctx := newTestCtxWithMockPrereqsPresent() + ctx.VerboseValue = false + + mockCmd := captureBuildRPMCmd(t, ctx) + + // Non-verbose runs should ask mock to be quiet and must not pass --verbose. + assert.Contains(t, mockCmd, "--quiet") + assert.NotContains(t, mockCmd, "--verbose") + }) + + t.Run("Verbose", func(t *testing.T) { + ctx := newTestCtxWithMockPrereqsPresent() + ctx.VerboseValue = true + + mockCmd := captureBuildRPMCmd(t, ctx) + + // Verbose runs should pass --verbose so mock streams its full output, and must not be quiet. + assert.Contains(t, mockCmd, "--verbose") + assert.NotContains(t, mockCmd, "--quiet") + }) +} + +// captureBuildRPMCmd runs a successful BuildRPM and returns the joined mock command line. +func captureBuildRPMCmd(t *testing.T, ctx *testctx.TestCtx) string { + t.Helper() + + var mockCmd string + + ctx.CmdFactory.RunHandler = func(cmd *exec.Cmd) error { + mockCmd = strings.Join(cmd.Args, " ") + + require.NoError(t, fileutils.WriteFile(ctx.FS(), testRPMPath, []byte{}, fileperms.PrivateFile)) + + return nil + } + + runner := mock.NewRunner(ctx, testMockConfigPath) + + err := runner.BuildRPM(ctx, testSRPMPath, testOutputDirPath, mock.RPMBuildOptions{}) + require.NoError(t, err) + + return mockCmd +} + func TestBuildRPM_MockFails(t *testing.T) { testError := errors.New("injected mock failure")