Skip to content

Commit

Permalink
Convert %prep into a regular build scriptlet
Browse files Browse the repository at this point in the history
Now that we can, implement %setup and %patch as auxiliary macros that are
defined only during %prep parsing. And voila, %prep is no longer special
at all. Not much anyhow.

Notably rpmspec --parse now emits %build where it belongs.
The error message on %patchN is now very much an ugly hack, but at least
it's something we can drop one sunny day.

Fixes: rpm-software-management#2205
  • Loading branch information
pmatilai committed Oct 23, 2023
1 parent d927ba2 commit 829eecb
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 64 deletions.
103 changes: 39 additions & 64 deletions build/parsePrep.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
#include <rpm/rpmfileutil.h>
#include "rpmbuild_internal.h"
#include "rpmbuild_misc.h"
#include "rpmmacro_internal.h"
#include "rpmug.h"
#include "debug.h"

static void appendBuf(rpmSpec spec, const char *s, int nl)
static void appendMb(rpmMacroBuf mb, const char *s, int nl)
{
appendStringBufAux(spec->prep, s, nl);
appendStringBufAux(spec->parsed, s, nl);
rpmMacroBufAppendStr(mb, s);
if (nl)
rpmMacroBufAppend(mb, '\n');
}

/**
Expand Down Expand Up @@ -153,8 +155,10 @@ static char *doUntar(rpmSpec spec, uint32_t c, int quietly)
* @param line current line from spec file
* @return RPMRC_OK on success
*/
static int doSetupMacro(rpmSpec spec, const char *line)
static void doSetupMacro(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t margs, size_t *parsed)
{
rpmSpec spec = rpmMacroEntryPriv(me);
char *line = argvJoin(margs, " ");
char *buf = NULL;
StringBuf before = newStringBuf();
StringBuf after = newStringBuf();
Expand All @@ -163,7 +167,6 @@ static int doSetupMacro(rpmSpec spec, const char *line)
const char ** argv = NULL;
int arg;
int xx;
rpmRC rc = RPMRC_FAIL;
uint32_t num;
int leaveDirs = 0, skipDefaultAction = 0;
int createDir = 0, quietly = 0;
Expand All @@ -179,15 +182,14 @@ static int doSetupMacro(rpmSpec spec, const char *line)
{ 0, 0, 0, 0, 0, NULL, NULL}
};

if (strstr(line+6, " -q")) quietly = 1;
if (strstr(line+5, " -q")) quietly = 1;

if ((xx = poptParseArgvString(line, &argc, &argv))) {
rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"), poptStrerror(xx));
rpmMacroBufErr(mb, 1, _("Error parsing %%setup: %s\n"), poptStrerror(xx));
goto exit;
}

if (rpmExpandNumeric("%{_build_in_place}")) {
rc = RPMRC_OK;
goto exit;
}

Expand All @@ -198,7 +200,7 @@ static int doSetupMacro(rpmSpec spec, const char *line)
/* We only parse -a and -b here */

if (parseUnsignedNum(optArg, &num)) {
rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"),
rpmMacroBufErr(mb, 1, _("line %d: Bad arg to %%setup: %s\n"),
spec->lineNum, (optArg ? optArg : "???"));
goto exit;
}
Expand All @@ -214,7 +216,7 @@ static int doSetupMacro(rpmSpec spec, const char *line)
}

if (arg < -1) {
rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"),
rpmMacroBufErr(mb, 1, _("line %d: Bad %%setup option %s: %s\n"),
spec->lineNum,
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
poptStrerror(arg));
Expand All @@ -236,25 +238,25 @@ static int doSetupMacro(rpmSpec spec, const char *line)
{ char * buildDir = rpmGenPath(spec->rootDir, "%{_builddir}", "");

rasprintf(&buf, "cd '%s'", buildDir);
appendBuf(spec, buf, 1);
appendMb(mb, buf, 1);
free(buf);
free(buildDir);
}

/* delete any old sources */
if (!leaveDirs) {
buf = rpmExpand("rm -rf '%{buildsubdir}'", NULL);
appendBuf(spec, buf, 1);
appendMb(mb, buf, 1);
free(buf);
}

appendBuf(spec, getStringBuf(before), 0);
appendMb(mb, getStringBuf(before), 0);

/* if necessary, create and cd into the proper dir */
if (createDir) {
buf = rpmExpand("%{__mkdir_p} '%{buildsubdir}'\n",
"cd '%{buildsubdir}'", NULL);
appendBuf(spec, buf, 1);
appendMb(mb, buf, 1);
free(buf);
}

Expand All @@ -263,36 +265,35 @@ static int doSetupMacro(rpmSpec spec, const char *line)
char *chptr = doUntar(spec, 0, quietly);
if (!chptr)
goto exit;
appendBuf(spec, chptr, 1);
appendMb(mb, chptr, 1);
free(chptr);
}

if (!createDir) {
buf = rpmExpand("cd '%{buildsubdir}'", NULL);
appendBuf(spec, buf, 1);
appendMb(mb, buf, 1);
free(buf);
}

/* mkdir for dynamic specparts */
if (rpmMacroIsDefined(spec->macros, "specpartsdir")) {
buf = rpmExpand("rm -rf '%{specpartsdir}'", NULL);
appendBuf(spec, buf, 1);
appendMb(mb, buf, 1);
free(buf);
buf = rpmExpand("%{__mkdir_p} '%{specpartsdir}'", NULL);
appendBuf(spec, buf, 1);
appendMb(mb, buf, 1);
free(buf);
}

appendBuf(spec, getStringBuf(after), 0);
appendMb(mb, getStringBuf(after), 0);

/* Fix the permissions of the setup build tree */
{ char *fix = rpmExpand("%{_fixperms} .", NULL);
if (fix && *fix != '%') {
appendBuf(spec, fix, 1);
appendMb(mb, fix, 1);
}
free(fix);
}
rc = RPMRC_OK;

exit:
freeStringBuf(before);
Expand All @@ -301,7 +302,7 @@ static int doSetupMacro(rpmSpec spec, const char *line)
free(dirName);
free(argv);

return rc;
return;
}

/**
Expand All @@ -316,15 +317,15 @@ static int doSetupMacro(rpmSpec spec, const char *line)
* @param line current line from spec file
* @return RPMRC_OK on success
*/
static rpmRC doPatchMacro(rpmSpec spec, const char *line)
static void doPatchMacro(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t margs, size_t *parsed)
{
rpmSpec spec = rpmMacroEntryPriv(me);
char *line = argvJoin(margs, " ");
char *opt_b, *opt_d, *opt_o;
char *buf = NULL;
int opt_p, opt_R, opt_E, opt_F, opt_Z;
int argc, c;
const char **argv = NULL;
ARGV_t patch, patchnums = NULL;
rpmRC rc = RPMRC_FAIL; /* assume failure */

struct poptOption const patchOpts[] = {
{ NULL, 'P', POPT_ARG_STRING, NULL, 'P', NULL, NULL },
Expand All @@ -345,14 +346,7 @@ static rpmRC doPatchMacro(rpmSpec spec, const char *line)
opt_F = rpmExpandNumeric("%{_default_patch_fuzz}"); /* get default fuzz factor for %patch */
opt_b = opt_d = opt_o = NULL;

/* Emit a legible error on the obsolete %patchN form for now */
if (! strchr(" \t\n", line[6])) {
rpmlog(RPMLOG_ERR,
_("%%patchN is obsolete, "
"use %%patch N (or %%patch -P N): %s\n"), line);
goto exit;
}
poptParseArgvString(buf ? buf : line, &argc, &argv);
poptParseArgvString(line, &argc, &argv);

/*
* Grab all -P<N> numbers for later processing. Stored as strings
Expand All @@ -375,7 +369,7 @@ static rpmRC doPatchMacro(rpmSpec spec, const char *line)
}

if (c < -1) {
rpmlog(RPMLOG_ERR, "%s: %s: %s\n", poptStrerror(c),
rpmMacroBufErr(mb, 1, "%s: %s: %s\n", poptStrerror(c),
poptBadOption(optCon, POPT_BADOPTION_NOALIAS), line);
goto exit;
}
Expand All @@ -384,7 +378,7 @@ static rpmRC doPatchMacro(rpmSpec spec, const char *line)
argvAppend(&patchnums, (ARGV_const_t) poptGetArgs(optCon));

if (argvCount(patchnums) == 0) {
rpmlog(RPMLOG_ERR, _("Patch number not specified: %s\n"), line);
rpmMacroBufErr(mb, 1, _("Patch number not specified: %s\n"), line);
goto exit;
}

Expand All @@ -393,65 +387,46 @@ static rpmRC doPatchMacro(rpmSpec spec, const char *line)
uint32_t pnum;
char *s;
if (parseUnsignedNum(*patch, &pnum)) {
rpmlog(RPMLOG_ERR, _("Invalid patch number %s: %s\n"),
rpmMacroBufErr(mb, 1, _("Invalid patch number %s: %s\n"),
*patch, line);
goto exit;
}
s = doPatch(spec, pnum, opt_p, opt_b, opt_R, opt_E, opt_F, opt_d, opt_o, opt_Z);
if (s == NULL) {
goto exit;
}
appendBuf(spec, s, 1);
appendMb(mb, s, 1);
free(s);
}

rc = RPMRC_OK;

exit:
argvFree(patchnums);
free(opt_b);
free(opt_d);
free(opt_o);
free(argv);
free(buf);
poptFreeContext(optCon);
return rc;
return;
}

int parsePrep(rpmSpec spec)
{
int rc, res = PART_ERROR;
ARGV_t saveLines = NULL;
int res = PART_ERROR;

if (spec->prep != NULL) {
rpmlog(RPMLOG_ERR, _("line %d: second %%prep\n"), spec->lineNum);
goto exit;
}

spec->prep = newStringBuf();
rpmPushMacroAux(NULL, "setup", "-", doSetupMacro, spec, -1, 0, 0);
rpmPushMacroAux(NULL, "patch", "-", doPatchMacro, spec, -1, 0, 0);

/* There are no options to %prep */
/* Handle spec->parsed addition locally due to %setup/%patch specialty */
if ((res = parseLines(spec, STRIP_PARSED, &saveLines, NULL)) == PART_ERROR)
goto exit;

for (ARGV_const_t lines = saveLines; lines && *lines; lines++) {
rc = RPMRC_OK;
if (rstreqn(*lines, "%setup", sizeof("%setup")-1)) {
rc = doSetupMacro(spec, *lines);
} else if (rstreqn(*lines, "%patch", sizeof("%patch")-1)) {
rc = doPatchMacro(spec, *lines);
} else {
appendBuf(spec, *lines, 0);
}
if (rc != RPMRC_OK && !(spec->flags & RPMSPEC_FORCE)) {
res = PART_ERROR;
goto exit;
}
}
res = parseSimpleScript(spec, "prep", &(spec->prep));

rpmPopMacro(NULL, "patch");
rpmPopMacro(NULL, "setup");

exit:
argvFree(saveLines);

return res;
}
12 changes: 12 additions & 0 deletions build/parseSpec.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,18 @@ int parseLines(rpmSpec spec, int strip, ARGV_t *avp, StringBuf *sbp)
*sbp = newStringBuf();

while (! (nextPart = isPart(spec->line))) {
/* HACK: Emit a legible error on the obsolete %patchN form for now */
if (sbp == &(spec->prep)) {
size_t slen = strlen(spec->line);
if (slen >= 7 && risdigit(spec->line[6]) &&
rstreqn(spec->line, "%patch", 6))
{
rpmlog(RPMLOG_ERR, _("%%patchN is obsolete, "
"use %%patch N (or %%patch -P N): %s\n"), spec->line);
nextPart = PART_ERROR;
break;
}
}
if (avp)
argvAdd(avp, spec->line);
if (sbp)
Expand Down
3 changes: 3 additions & 0 deletions tests/rpmspec.at
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,13 @@ cd 'hello-1.0'
rm -rf '/build/BUILD/hello-1.0-SPECPARTS'
/usr/bin/mkdir -p '/build/BUILD/hello-1.0-SPECPARTS'
/usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .

echo "Patch #0 (hello-1.0-modernize.patch):"
/usr/bin/patch --no-backup-if-mismatch -f -p1 -b --suffix .modernize --fuzz=0 < /build/SOURCES/hello-1.0-modernize.patch



%build
make

%install
Expand Down

0 comments on commit 829eecb

Please sign in to comment.