Skip to content

Commit

Permalink
Implement prepend and append modes for all build scriptlets
Browse files Browse the repository at this point in the history
Allows %prep, %conf, %build, %install, %check, %clean and %generate_depends
to be augmented arbitrary number of times by appending or prepending to
them. The main use-case is to support automatic population of these
sections (declarative builds) while still allowing packagers to easily
tweak them, but could also be useful for complicated conditional specs
and such.

Related: #1087
  • Loading branch information
pmatilai committed Oct 27, 2023
1 parent 064ba64 commit 3864c89
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 8 deletions.
59 changes: 53 additions & 6 deletions build/parseSimpleScript.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,64 @@
int parseSimpleScript(rpmSpec spec, const char * name, StringBuf *sbp)
{
int res = PART_ERROR;

if (*sbp != NULL) {
poptContext optCon = NULL;
int argc;
const char **argv = NULL;
StringBuf *target = sbp;
StringBuf buf = NULL;
int rc, append = 0, prepend = 0;
struct poptOption optionsTable[] = {
{ NULL, 'a', POPT_ARG_NONE, &append, 'a', NULL, NULL },
{ NULL, 'p', POPT_ARG_NONE, &prepend, 'p', NULL, NULL },
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};


if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
rpmlog(RPMLOG_ERR, _("line %d: Error parsing script: %s: %s\n"),
spec->lineNum, spec->line, poptStrerror(rc));
goto exit;
}

optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
while ((rc = poptGetNextOpt(optCon)) > 0) {};
if (rc < -1) {
rpmlog(RPMLOG_ERR, _("line %d: Bad %s option %s: %s\n"),
spec->lineNum, argv[0],
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
poptStrerror(rc));
goto exit;
}

if (*sbp != NULL && append == 0 && prepend == 0) {
rpmlog(RPMLOG_ERR, _("line %d: second %s\n"),
spec->lineNum, name);
goto exit;
}

/* There are no options to %build, %install, %check, or %clean */
res = parseLines(spec, STRIP_NOTHING, NULL, sbp);


if (append && prepend) {
rpmlog(RPMLOG_ERR, _("line %d: append and prepend specified: %s\n"),
spec->lineNum, spec->line);
goto exit;
}

/* Prepend is only special if the section already exists */
if (prepend && *sbp) {
buf = newStringBuf();
target = &buf;
}

res = parseLines(spec, STRIP_NOTHING, NULL, target);

if (buf) {
appendStringBuf(buf, getStringBuf(*sbp));
freeStringBuf(*sbp);
*sbp = buf;
}

exit:
free(argv);
poptFreeContext(optCon);

return res;
}
13 changes: 11 additions & 2 deletions docs/manual/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,17 @@ when name is omitted, the description refers to the main package.

## Build scriptlets

Package build is divided into multiple separate steps, each executed
in a separate shell.
Package build is divided into multiple separate steps, each executed in a
separate shell: `%prep`, `%conf`, `%build`, `%install`, `%check`, `%clean`
and `%generate_buildrequires`. Any unnecessary scriptlet sections can be
omitted.

Each section may be present only once, but in rpm >= 4.20 it is
possible to augment them by appending or prepending to them using
`-a` and `-p` options.
If the main section exists, it must come first to avoid ambiguity.
Otherwise, append and prepend can be used in any order and multiple
times, even if the corresponding main section does not exist.

### %prep

Expand Down
33 changes: 33 additions & 0 deletions tests/data/SPECS/append.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Name: append
Version: 1.0
Release: 1
BuildArch: noarch
Summary: Testing scriptlet append/prepend
License: GPL

%description
%{summary}

%build
echo BBB >> out

%build -a
echo CCC >> out

%build -p
echo AAA >> out

%build -a
echo DDD >> out

%build -p
echo 000 >> out

%install -a
cp out ${RPM_BUILD_ROOT}/opt/

%install -p
mkdir -p ${RPM_BUILD_ROOT}/opt/

%files
/opt/out
18 changes: 18 additions & 0 deletions tests/rpmbuild.at
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,24 @@ runroot rpmbuild -bs /data/SPECS/specstep.spec 2>&1|grep ^Executing|cut -d: -f1
[])
RPMTEST_CLEANUP

AT_SETUP([rpmbuild script prepend/append])
AT_KEYWORDS([build])
RPMDB_INIT
RPMTEST_CHECK([
runroot rpmbuild -bb --quiet ${RPMDATA}/SPECS/append.spec
runroot_other rpm2cpio /build/RPMS/noarch/append-1.0-1.noarch.rpm | cpio -id 2> /dev/null
cat opt/out
],
[0],
[000
AAA
BBB
CCC
DDD
],
[])
RPMTEST_CLEANUP

AT_SETUP([rpmbuild -ba autosetup])
AT_KEYWORDS([build])
RPMDB_INIT
Expand Down

0 comments on commit 3864c89

Please sign in to comment.