Add an interactive macro shell mode to rpmspec

Handy for debugging and experimenting with macros, in and out of
spec context.

Placed in rpmspec because we don't want readline dependency on main rpm
executable, this is more of a packager tool anyway.
This commit is contained in:
Panu Matilainen 2021-04-13 16:56:08 +03:00
parent ec1a245937
commit 03b3df0ce0
3 changed files with 71 additions and 5 deletions

View File

@ -145,9 +145,10 @@ rpmbuild_LDADD += @WITH_POPT_LIB@
rpmspec_SOURCES = rpmspec.c debug.h system.h
rpmspec_CPPFLAGS = $(AM_CPPFLAGS)
rpmspec_CPPFLAGS = @READLINE_CFLAGS@
rpmspec_LDADD = libcliutils.la
rpmspec_LDADD += build/librpmbuild.la lib/librpm.la rpmio/librpmio.la
rpmspec_LDADD += @WITH_POPT_LIB@
rpmspec_LDADD += @WITH_POPT_LIB@ @READLINE_LIBS@
rpm2cpio_SOURCES = rpm2cpio.c debug.h system.h
rpm2cpio_LDADD = lib/librpm.la rpmio/librpmio.la

View File

@ -23,6 +23,11 @@ PARSING SPEC FILES TO STDOUT:
**rpmspec** {**-P\|\--parse**} *SPEC\_FILE \...*
INVOKING MACRO SHELL:
---------------------
**rpmspec** {**--shell**} \[*SPEC_FILE \...*\]
DESCRIPTION
===========
@ -83,7 +88,9 @@ file:
> rpm-build-libs-4.11.3-3.fc20.x86_64
> ...
>
> Get summary infos for single binary packages generated from the rpm spec file:
Get summary infos for single binary packages generated from the rpm spec file:
>
> $ rpmspec -q --qf "%{name}: %{summary}\n" rpm.spec
> rpm: The RPM package management system
@ -91,19 +98,41 @@ file:
> rpm-build-libs: Libraries for building and signing RPM packages
> ...
>
> Get the source package which would be generated from the rpm spec file:
Get the source package which would be generated from the rpm spec file:
>
> $ rpmspec -q --srpm rpm.spec
> rpm-4.11.3-3.fc20.x86_64
>
> Parse the rpm spec file to stdout:
>
Parse the rpm spec file to stdout:
> $ rpmspec -P rpm.spec
> Summary: The RPM package management system
> Name: rpm
> Version: 4.14.0
> ...
Run interactive macro shell for debugging macros:
> $ rpmspec --shell
> > %define foo bar
> > %foo
> bar
> > %(date)
> Tue Apr 13 03:55:37 PM EEST 2021
> > %getncpus
> 8
Run interactive macros shell in spec context:
> $ rpmspec --shell popt.spec
> %name
> popt
> %version
> 1.18
SEE ALSO
========

View File

@ -5,6 +5,11 @@
#include <rpm/rpmlog.h>
#include <rpm/rpmts.h>
#ifdef HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif
#include "cliutils.h"
#include "debug.h"
@ -13,6 +18,7 @@ enum modes {
MODE_UNKNOWN = 0,
MODE_QUERY = (1 << 0),
MODE_PARSE = (1 << 1),
MODE_SHELL = (1 << 2),
};
static int mode = MODE_UNKNOWN;
@ -24,6 +30,10 @@ static struct poptOption specOptsTable[] = {
N_("parse spec file(s) to stdout"), NULL },
{ "query", 'q', POPT_ARG_VAL, &mode, MODE_QUERY,
N_("query spec file(s)"), NULL },
#if HAVE_READLINE
{ "shell", 0, POPT_ARG_VAL, &mode, MODE_SHELL,
N_("interactive macro shell"), NULL },
#endif
{ "rpms", 0, POPT_ARG_VAL, &source, RPMQV_SPECRPMS,
N_("operate on binary rpms generated by spec (default)"), NULL },
{ "builtrpms", 0, POPT_ARG_VAL, &source, RPMQV_SPECBUILTRPMS,
@ -52,6 +62,23 @@ static struct poptOption optionsTable[] = {
typedef int (*parsecb)(rpmSpec spec);
#ifdef HAVE_READLINE
static int doShell(rpmSpec spec)
{
fprintf(stderr, _("RPM version %s macro shell\n"), rpmEVR);
char *line = NULL;
while ((line = readline("> ")) != NULL) {
char *exp = rpmExpand(line, NULL);
if (*exp)
fprintf(stdout, "%s\n", exp);
free(exp);
if (*line)
add_history(line);
}
return 0;
}
#endif
static int dumpSpec(rpmSpec spec)
{
fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE));
@ -114,6 +141,15 @@ int main(int argc, char *argv[])
break;
}
#ifdef HAVE_READLINE
case MODE_SHELL:
if (poptPeekArg(optCon))
ec = doSpec(optCon, doShell);
else
ec = doShell(NULL);
break;
#endif
case MODE_UNKNOWN:
if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
printUsage(optCon, stderr, 0);