Skip to content

Commit

Permalink
Separate build warnings from error summary
Browse files Browse the repository at this point in the history
Confusingly, the "RPM build errors" section also includes messages
logged as warnings.  That gives the false impression that they somehow
contributed to the actual build failure and therefore were turned into
errors.

This appears to be a historical artifact; when a message passes through
the logging system and is of the priority RPMLOG_WARNING or higher, we
save it in a global buffer (ctx->recs), which is then simply dumped with
rpmlogPrint() in the error summary.  This was probably good enough when
the summary was introduced (commit f2efc72, year 2000), as there were
almost no warnings generated by RPM at that time, however as they became
more abundant, the summary code was never revisited.

There are 3 ways to fix this discrepancy:

 1) Change the summary's title to "RPM build problems"
 2) Remove the summary altogether
 3) Don't show warnings in it

Options #1 and #2 would be too disruptive.  The error summary needs to
stay as is, for the following reasons:

 - While it usually just repeats the last error, not all errors
   terminate a build right away, so those can get drown in the output
   that follows after.  Examples: "File not found" in rpmInstall(), or
   macro expansion errors (note: we may have these terminate a build in
   the future).

 - It makes it immediately obvious that something went wrong when
   examining build logs, and the title "RPM build errors" undoubtedly
   has become the de-facto text string to search for.

That leaves us with option #3.  To further lessen the disruption, do
keep a summary of warnings, but put them under their own heading, and
only show it on build failures.  That way, we restrict all the extra
verbosity to error time (as it is now) and don't pollute the output of
otherwise good builds.  There may be packages with long-standing
warnings that are not feasible to fix for any reason, and having an
indented block of text resembling "RPM build errors" at the end of every
build would do no good.

Effectively, this commit is just cosmetic - it splits the error summary
into two, without any functional or API changes (apart from two function
additions).

Fixes: rpm-software-management#793
(cherry picked from commit 7fd7a60)
  • Loading branch information
dmnks committed Jun 7, 2022
1 parent 202f516 commit 7238dea
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
18 changes: 14 additions & 4 deletions build/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,21 @@ static rpmRC buildSpec(rpmts ts, BTA_t buildArgs, rpmSpec spec, int what)
freeStringBuf(sink);
free(cookie);
spec->rootDir = NULL;
if (rc != RPMRC_OK && rc != RPMRC_MISSINGBUILDREQUIRES &&
rpmlogGetNrecs() > 0) {
rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
rpmlogPrint(NULL);

if (rc != RPMRC_OK && rc != RPMRC_MISSINGBUILDREQUIRES) {
unsigned maskWarn = RPMLOG_MASK(RPMLOG_WARNING);
unsigned maskErrs = RPMLOG_UPTO(RPMLOG_ERR);

if (rpmlogGetNrecsByMask(maskWarn)) {
rpmlog(RPMLOG_NOTICE, _("\n\nRPM build warnings:\n"));
rpmlogPrintByMask(NULL, maskWarn);
}
if (rpmlogGetNrecsByMask(maskErrs)) {
rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
rpmlogPrintByMask(NULL, maskErrs);
}
}

rpmugFree();
if (missing_buildreqs && !rc) {
rc = RPMRC_MISSINGBUILDREQUIRES;
Expand Down
34 changes: 29 additions & 5 deletions rpmio/rpmlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct rpmlogCtx_s {
pthread_rwlock_t lock;
unsigned mask;
int nrecs;
int nrecsPri[RPMLOG_NPRIS];
rpmlogRec recs;
rpmlogCallback cbfunc;
rpmlogCallbackData cbdata;
Expand All @@ -33,7 +34,7 @@ static rpmlogCtx rpmlogCtxAcquire(int write)
{
static struct rpmlogCtx_s _globalCtx = { PTHREAD_RWLOCK_INITIALIZER,
RPMLOG_UPTO(RPMLOG_NOTICE),
0, NULL, NULL, NULL, NULL };
0, {0}, NULL, NULL, NULL, NULL };
rpmlogCtx ctx = &_globalCtx;
int xx;

Expand All @@ -54,16 +55,30 @@ static rpmlogCtx rpmlogCtxRelease(rpmlogCtx ctx)
return NULL;
}

int rpmlogGetNrecs(void)
int rpmlogGetNrecsByMask(unsigned mask)
{
rpmlogCtx ctx = rpmlogCtxAcquire(0);
int nrecs = -1;
if (ctx)
int nrecs = 0;

if (ctx == NULL)
return -1;

if (mask) {
for (int i = 0; i < RPMLOG_NPRIS; i++, mask >>= 1)
if (mask & 1)
nrecs += ctx->nrecsPri[i];
} else
nrecs = ctx->nrecs;

rpmlogCtxRelease(ctx);
return nrecs;
}

int rpmlogGetNrecs(void)
{
return rpmlogGetNrecsByMask(0);
}

int rpmlogCode(void)
{
int code = -1;
Expand Down Expand Up @@ -98,7 +113,7 @@ rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
return (rec != NULL) ? rec->pri : (rpmlogLvl)-1;
}

void rpmlogPrint(FILE *f)
void rpmlogPrintByMask(FILE *f, unsigned mask)
{
rpmlogCtx ctx = rpmlogCtxAcquire(0);

Expand All @@ -110,13 +125,20 @@ void rpmlogPrint(FILE *f)

for (int i = 0; i < ctx->nrecs; i++) {
rpmlogRec rec = ctx->recs + i;
if (mask && ((RPMLOG_MASK(rec->pri) & mask) == 0))
continue;
if (rec->message && *rec->message)
fprintf(f, " %s", rec->message);
}

rpmlogCtxRelease(ctx);
}

void rpmlogPrint(FILE *f)
{
rpmlogPrintByMask(f, 0);
}

void rpmlogClose (void)
{
rpmlogCtx ctx = rpmlogCtxAcquire(1);
Expand All @@ -130,6 +152,7 @@ void rpmlogClose (void)
}
ctx->recs = _free(ctx->recs);
ctx->nrecs = 0;
memset(ctx->nrecsPri, 0, sizeof(ctx->nrecsPri));

rpmlogCtxRelease(ctx);
}
Expand Down Expand Up @@ -378,6 +401,7 @@ static void dolog(struct rpmlogRec_s *rec, int saverec)
ctx->recs[ctx->nrecs+1].code = 0;
ctx->recs[ctx->nrecs+1].message = NULL;
ctx->nrecs++;
ctx->nrecsPri[rec->pri]++;
}
cbfunc = ctx->cbfunc;
cbdata = ctx->cbdata;
Expand Down
15 changes: 15 additions & 0 deletions rpmio/rpmlog.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ typedef enum rpmlogLvl_e {
/* extract priority */
#define RPMLOG_PRI(p) ((p) & RPMLOG_PRIMASK)
#define RPMLOG_MAKEPRI(fac, pri) ((((unsigned)(fac)) << 3) | (pri))
#define RPMLOG_NPRIS (RPMLOG_DEBUG + 1)

/** \ingroup rpmlog
* facility codes
Expand Down Expand Up @@ -132,12 +133,26 @@ typedef void * rpmlogCallbackData;
*/
typedef int (*rpmlogCallback) (rpmlogRec rec, rpmlogCallbackData data);

/** \ingroup rpmlog
* Return number of rpmError() messages matching a log mask.
* @param mask log mask to filter by (0 is no filtering)
* @return number of messages matching the mask
*/
int rpmlogGetNrecsByMask(unsigned mask);

/** \ingroup rpmlog
* Return number of rpmError() ressages.
* @return number of messages
*/
int rpmlogGetNrecs(void) ;

/** \ingroup rpmlog
* Print all rpmError() messages matching a log mask.
* @param f file handle (NULL uses stderr)
* @param mask log mask to filter by (0 is no filtering)
*/
void rpmlogPrintByMask(FILE *f, unsigned mask);

/** \ingroup rpmlog
* Print all rpmError() messages.
* @param f file handle (NULL uses stderr)
Expand Down

0 comments on commit 7238dea

Please sign in to comment.