Now for some fun ...
Let's say you are building packages using Fedora CVS.
The last time I used Fedora CVS, the work flow went something like
cd /S/FC/devel/time # <== note "/S/FC" is where my checkout is
cvs up
make i386
ls i386/*.rpm
So "+bing" can now be used to select *.rpm packages
directly from where they reside with this macro override:
%_rpmgi_pattern_glob /S/FC/devel/%{NEVRA}/i386/
Then to install, say, the just built time package, one types
rpm -Uvh +time
For extra credit, let's assume that you have all Fedora 8 packages
in /S/FC/packages as well as a cvs checkout. Try this
%_rpmgi_pattern_glob /S/FC/devel/%{NEVRA}/i386/:/S/FC/packages/
to look first for newly built, and use "released" if not rebuilt
locally from cvs.
Enjoy!
Hint: rpmio permits the paths to be URL's, but I haven't quite gotten
there yet ...
73 de Jeff
On Feb 4, 2008, at 1:33 PM, Jeff Johnson wrote:
> RPM Package Manager, CVS Repository
> http://rpm5.org/cvs/
>
> ______________________________________________________________________
> ______
>
> Server: rpm5.org Name: Jeff Johnson
> Root: /v/rpm/cvs Email: jbj@rpm5.org
> Module: rpm Date: 04-Feb-2008
> 19:33:30
> Branch: HEAD Handle: 2008020418332901
>
> Modified files:
> rpm CHANGES
> rpm/lib rpminstall.c
> rpm/rpmio argv.c argv.h
>
> Log:
> - jbj: "+bing" -- handle no *.rpm package found condition
> correctly.
> - jbj: "+bing" -- limit Fts(3) recursion to target directory
> traversal only.
> - jbj: "+bing" -- define "%NEVRA bing" on-the-fly for use by
> glob patterns.
> - jbj: "+bing" -- permit colon separated glob directory patterns.
>
> Summary:
> Revision Changes Path
> 1.2134 +6 -2 rpm/CHANGES
> 1.197 +46 -30 rpm/lib/rpminstall.c
> 1.12 +11 -9 rpm/rpmio/argv.c
> 1.8 +1 -1 rpm/rpmio/argv.h
>
> ______________________________________________________________________
> ______
>
> patch -p0 <<'@@ .'
> Index: rpm/CHANGES
>
> ======================================================================
> ======
> $ cvs diff -u -r1.2133 -r1.2134 CHANGES
> --- rpm/CHANGES 4 Feb 2008 16:37:17 -0000 1.2133
> +++ rpm/CHANGES 4 Feb 2008 18:33:29 -0000 1.2134
> @@ -1,6 +1,10 @@
> 5.0.0 -> 5.1a1:
> - - jbj: include rpmuuid.h to remove warning.
> - - jbj: add %{!?load:...} syntax, display error if %
> {load:...} fails.
> + - jbj: "+bing" -- handle no *.rpm package found condition
> correctly.
> + - jbj: "+bing" -- limit Fts(3) recursion to target directory
> traversal only.
> + - jbj: "+bing" -- define "%NEVRA bing" on-the-fly for use by
> glob patterns.
> + - jbj: "+bing" -- permit colon separated glob directory
> patterns.
> + - jbj: macro.c: include rpmuuid.h to remove warning.
> + - jbj: macro.c: add %{!?load:...} syntax, display error if %
> {load:...} fails.
> - jbj: updated sv.po (Translation Project).
> - jbj: fix: permit #%patchN comments by forcing single line
> expansion.
> - jbj: document newer macro builtins (%{@foo:...}, %
> {uuid:...}, and %{lua:...} todo).
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/lib/rpminstall.c
>
> ======================================================================
> ======
> $ cvs diff -u -r1.196 -r1.197 rpminstall.c
> --- rpm/lib/rpminstall.c 3 Feb 2008 20:12:33 -0000 1.196
> +++ rpm/lib/rpminstall.c 4 Feb 2008 18:33:29 -0000 1.197
> @@ -335,10 +335,12 @@
> static const char * rpmcliWalkFirst(ARGV_t av, miRE mire)
> {
> /* XXX use global ftsOpts? */
> - int _ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
> + /* XXX changing FTS_LOGICAL to FTS_PHYSICAL prevents symlink
> follow. */
> + int _ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT |
> FTS_NOCHDIR);
> FTS * ftsp = Fts_open((char *const *)av, _ftsOpts, NULL);
> FTSENT * fts;
> const char * fn = NULL;
> + int fts_level = 1;
> int xx;
>
> if (ftsp != NULL)
> @@ -347,6 +349,10 @@
> /* No-op conditions. */
> case FTS_D: /* preorder directory */
> case FTS_DP: /* postorder directory */
> + /* XXX Don't recurse downwards, all elements should be
> files. */
> + if (fts_level > 0 && fts->fts_level >= fts_level)
> + Fts_set(ftsp, fts, FTS_SKIP);
> + /*@fallthrough@*/
> case FTS_DOT: /* dot or dot-dot */
> continue;
> /*@notreached@*/ break;
> @@ -382,52 +388,54 @@
>
> static const char * rpmcliInstallElementPath(rpmts ts, const
> char * arg)
> {
> -#ifdef GLOB_ONLY
> - /* XXX note the added "-*.rpm" to force globbing on '-'
> boundaries. */
> - const char * fn = rpmGetPath(
> - "%{?_rpmgi_pattern_glob:%{_rpmgi_pattern_glob ", arg, "}}"
> - "%{!?_rpmgi_pattern_glob:", arg, "-*-*.*.rpm}",
> - NULL
> - );
> -#else
> - /* Create a glob pattern to match repository directories. */
> - const char * fn = rpmGetPath(
> + /* A glob pattern list to match repository directories. */
> + const char * fn = rpmExpand(
> "%{?_rpmgi_pattern_glob}"
> - "%{!?_rpmgi_pattern_glob:.}", "/",
> + "%{!?_rpmgi_pattern_glob:.}",
> NULL
> );
> -#endif
> + /* A regex pattern list to match candidate *.rpm files. */
> const char * mirePattern = rpmExpand(
> "%{?_rpmgi_pattern_regex:%{_rpmgi_pattern_regex ", arg,
> "}}"
> "%{!?_rpmgi_pattern_regex:", arg, "-[^-]+-[^-]+\\.[^.]+\
> \.rpm$}",
> NULL
> );
> miRE mire = mireNew(RPMMIRE_REGEX, 0);
> + ARGV_t dav = NULL;
> + int dac = 0;
> ARGV_t av = NULL;
> - int ac = 0;
> int xx = mireRegcomp(mire, mirePattern);
> + int i;
>
> - /* Get explicit list of candidate repository directories. */
> - xx = rpmGlob(fn, &ac, &av);
> + /* Get list of candidate repository patterns. */
> + xx = argvSplit(&dav, fn, ":");
> fn = _free(fn);
> + if (xx || dav == NULL)
> + goto exit;
>
> - /* Filter out glibc <-> glibc-common confusions. */
> -#ifdef GLOB_ONLY
> - { int i;
> - for (i = 0; i < ac; i++) {
> - if (mireRegexec(mire, av[i]))
> - continue;
> - /* Stop on first file that matches. */
> - fn = xstrdup(av[0]);
> - break;
> - }
> + dac = argvCount(dav);
> + for (i = 0; i < dac; i++) {
> + ARGV_t nav = NULL;
> + int nac = 0;
> +
> + /* Insure only directory paths are matched. */
> + fn = rpmGetPath(dav[i], "/", NULL);
> + xx = rpmGlob(fn, &nac, &nav);
> +
> + /* Append matches to list of repository directories. */
> + if (nac > 0 && nav != NULL)
> + xx = argvAppend(&av, nav);
> + nav = argvFree(nav);
> + nac = 0;
> + fn = _free(fn);
> }
> -#else
> +
> /* Walk (possibly multi-root'd) directories, until 1st match
> is found. */
> fn = rpmcliWalkFirst(av, mire);
> -#endif
>
> +exit:
> av = argvFree(av);
> + dav = argvFree(dav);
> mire = mireFree(mire);
> mirePattern = _free(mirePattern);
>
> @@ -523,7 +531,15 @@
>
> /* === Check for "+bing" lookaside paths within install
> transaction. */
> if (fn[0] == '+') {
> - const char * nfn = rpmcliInstallElementPath(ts, &fn[1]);
> + const char * nfn;
> + addMacro(NULL, "NEVRA", NULL, &fn[1], RMIL_GLOBAL);
> + nfn = rpmcliInstallElementPath(ts, &fn[1]);
> + delMacro(NULL, "NEVRA");
> + if (nfn == NULL) {
> + rpmlog(RPMLOG_ERR, _("package \"%s\" cannot be found\n"), fn);
> + numFailed++; /* XXX multiple erasures? */
> + continue;
> + }
> fn = _free(fn);
> fn = nfn;
> /* XXX hack into rpmgi innards for now ... */
> @@ -541,7 +557,7 @@
> break;
> case RPMRC_NOTFOUND:
> default:
> - rpmlog(RPMLOG_ERR, _("package %s cannot be erased\n"), &fn[1]);
> + rpmlog(RPMLOG_ERR, _("package \"%s\" cannot be erased\n"), fn);
> numFailed++; /* XXX multiple erasures? */
> goto exit;
> /*@notreached@*/ break;
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/argv.c
>
> ======================================================================
> ======
> $ cvs diff -u -r1.11 -r1.12 argv.c
> --- rpm/rpmio/argv.c 30 Dec 2007 14:33:07 -0000 1.11
> +++ rpm/rpmio/argv.c 4 Feb 2008 18:33:30 -0000 1.12
> @@ -186,18 +186,20 @@
> return 0;
> }
>
> -int argvAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)
> +int argvAppend(/*@out@*/ ARGV_t * argvp, ARGV_t av)
> {
> - ARGV_t argv = *argvp;
> - int argc = argvCount(argv);
> int ac = argvCount(av);
> - int i;
>
> - argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
> - for (i = 0; i < ac; i++)
> - argv[argc + i] = xstrdup(av[i]);
> - argv[argc + ac] = NULL;
> - *argvp = argv;
> + if (av != NULL && ac > 0) {
> + ARGV_t argv = *argvp;
> + int argc = argvCount(argv);
> +
> + argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
> + while (*av++)
> + argv[argc++] = xstrdup(av[-1]);
> + argv[argc] = NULL;
> + *argvp = argv;
> + }
> return 0;
> }
>
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/argv.h
>
> ======================================================================
> ======
> $ cvs diff -u -r1.7 -r1.8 argv.h
> --- rpm/rpmio/argv.h 14 Dec 2007 11:22:08 -0000 1.7
> +++ rpm/rpmio/argv.h 4 Feb 2008 18:33:30 -0000 1.8
> @@ -182,7 +182,7 @@
> * @param av argv array to append
> * @return 0 always
> */
> -int argvAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)
> +int argvAppend(/*@out@*/ ARGV_t * argvp, ARGV_t av)
> /*@modifies *argvp @*/;
>
> /**
> @@ .
> ______________________________________________________________________
> RPM Package Manager http://rpm5.org
> CVS Sources Repository rpm-cvs@rpm5.org
Received on Mon Feb 4 20:54:18 2008