Imported Upstream version 0.7.17 upstream/0.7.17
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 23 Dec 2021 05:46:59 +0000 (14:46 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 23 Dec 2021 05:46:59 +0000 (14:46 +0900)
20 files changed:
NEWS
VERSION.cmake
bindings/solv.i
doc/gen/libsolv-bindings.3
doc/gen/libsolv-pool.3
doc/gen/rpmdb2solv.1
doc/rpmdb2solv.txt
ext/repo_comps.c
ext/repo_rpmdb.c
ext/repo_rpmdb_bdb.h
ext/repo_rpmdb_librpm.h
ext/repo_updateinfoxml.c
ext/testcase.c
package/libsolv.changes
src/knownid.h
src/repo_write.c
src/rules.c
test/testcases/choicerules/choice3.t [new file with mode: 0644]
test/testcases/choicerules/choice4.t [new file with mode: 0644]
tools/rpmdb2solv.c

diff --git a/NEWS b/NEWS
index ca6efa9..7e91d66 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,18 @@
 This file contains the major changes between
 libsolv versions:
 
+Version 0.7.17
+- selected bug fixes:
+  * repo_write: fix handling of nested flexarray
+  * improve choicerule generation a bit more to cover more cases
+  * harden testcase parser against repos being added too late
+  * support python-3.10
+  * check %_dbpath macro in rpmdb code
+- new features:
+  * handle default/visible/langonly attributes in comps parser
+  * support multiple collections in updateinfo parser
+  * add '-D' option in rpmdb2solv to set the dbpath
+
 Version 0.7.16
 - selected bug fixes:
   * do not ask the namespace callback for splitprovides when writing
index c218401..adf18d2 100644 (file)
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "1")
 
 SET(LIBSOLV_MAJOR "0")
 SET(LIBSOLV_MINOR "7")
-SET(LIBSOLV_PATCH "16")
+SET(LIBSOLV_PATCH "17")
 
index 48d3f1f..1882b13 100644 (file)
@@ -44,7 +44,11 @@ typedef struct {
 #if defined(SWIGPYTHON)
     const void *pybuf = 0;
     Py_ssize_t pysize = 0;
+%#if PY_VERSION_HEX >= 0x03000000
+    res = PyBytes_AsStringAndSize($input, (char **)&pybuf, &pysize);
+%#else
     res = PyObject_AsReadBuffer($input, &pybuf, &pysize);
+%#endif
     if (res < 0) {
       %argument_fail(res, "BinaryBlob", $symname, $argnum);
     } else {
index 8e6417e..7384d2a 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: Libsolv-Bindings
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 01/21/2020
+.\"      Date: 11/18/2020
 .\"    Manual: LIBSOLV
 .\"    Source: libsolv
 .\"  Language: English
 .\"
-.TH "LIBSOLV\-BINDINGS" "3" "01/21/2020" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-BINDINGS" "3" "11/18/2020" "libsolv" "LIBSOLV"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 6d94939..ab1b3f0 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: Libsolv-Pool
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 01/21/2020
+.\"      Date: 11/18/2020
 .\"    Manual: LIBSOLV
 .\"    Source: libsolv
 .\"  Language: English
 .\"
-.TH "LIBSOLV\-POOL" "3" "01/21/2020" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-POOL" "3" "11/18/2020" "libsolv" "LIBSOLV"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 6f84a7f..c54c319 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: rpmdb2solv
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 09/14/2018
+.\"      Date: 11/18/2020
 .\"    Manual: LIBSOLV
 .\"    Source: libsolv
 .\"  Language: English
 .\"
-.TH "RPMDB2SOLV" "1" "09/14/2018" "libsolv" "LIBSOLV"
+.TH "RPMDB2SOLV" "1" "11/18/2020" "libsolv" "LIBSOLV"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -55,6 +55,13 @@ Use
 as root directory\&.
 .RE
 .PP
+\fB\-D\fR \fIDBPATH\fR
+.RS 4
+Use the database in the
+\fIDBPATH\fR
+directory\&.
+.RE
+.PP
 \fB\-k\fR
 .RS 4
 Read pubkeys from the rpm database instead of installed packages\&. Note that many distributions stopped storing pubkeys in the database but use a directory like
@@ -83,6 +90,11 @@ Do not read any packages from the rpm database\&. This is useful together with
 to only convert SUSE products\&.
 .RE
 .PP
+\fB\-C\fR
+.RS 4
+Include the package changelog in the generated solv file\&.
+.RE
+.PP
 \fB\-X\fR
 .RS 4
 Autoexpand SUSE pattern and product provides into packages\&.
index 128e179..8e31cb8 100644 (file)
@@ -29,6 +29,9 @@ format is like rpm's --percent option.
 *-r* 'ROOTDIR'::
 Use 'ROOTDIR' as root directory.
 
+*-D* 'DBPATH'::
+Use the database in the 'DBPATH' directory.
+
 *-k*::
 Read pubkeys from the rpm database instead of installed packages.
 Note that many distributions stopped storing pubkeys in the
index 6991656..014f89a 100644 (file)
@@ -29,7 +29,6 @@
  * TODO:
  *
  * what's the difference between group/category?
- * handle "default" and "langonly".
  *
  * maybe handle REL_COND in solver recommends handling?
  */
@@ -97,10 +96,26 @@ struct parsedata {
 
   Solvable *solvable;
   const char *kind;
+  int isdefault;
+  int isvisible;
   Id handle;
 };
 
 
+#define COMPS_DEFAULT_ISVISIBLE 1
+#define COMPS_DEFAULT_ISDEFAULT 0
+
+/* Return true if "true", false if "false", default_value otherwise */
+static int
+parse_boolean(char *content, int default_value)
+{
+  if (!strcmp(content, "true"))
+    return 1;
+  if (!strcmp(content, "false"))
+    return 0;
+  return default_value;
+}
+
 
 static void
 startElement(struct solv_xmlparser *xmlp, int state, const char *name, const char **atts)
@@ -116,6 +131,8 @@ startElement(struct solv_xmlparser *xmlp, int state, const char *name, const cha
       s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
       pd->handle = s - pool->solvables;
       pd->kind = state == STATE_GROUP ? "group" : "category";
+      pd->isvisible = COMPS_DEFAULT_ISVISIBLE;
+      pd->isdefault = COMPS_DEFAULT_ISDEFAULT;
       break;
 
     case STATE_NAME:
@@ -166,6 +183,10 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
        s->evr = ID_EMPTY;
       if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
+      if (pd->isvisible)
+        repodata_set_void(pd->data, pd->handle, SOLVABLE_ISVISIBLE);
+      if (pd->isdefault)
+        repodata_set_void(pd->data, pd->handle, SOLVABLE_ISDEFAULT);
       pd->solvable = 0;
       break;
 
@@ -194,7 +215,19 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
       break;
 
     case STATE_USERVISIBLE:
-      repodata_set_void(pd->data, pd->handle, SOLVABLE_ISVISIBLE);
+      pd->isvisible = parse_boolean(content, COMPS_DEFAULT_ISVISIBLE);
+      break;
+
+    case STATE_DEFAULT:
+      pd->isdefault = parse_boolean(content, COMPS_DEFAULT_ISDEFAULT);
+      break;
+
+    case STATE_LANG_ONLY:
+      repodata_set_str(pd->data, pd->handle, SOLVABLE_LANGONLY, content);
+      break;
+
+    case STATE_LANGONLY:
+      repodata_set_str(pd->data, pd->handle, SOLVABLE_LANGONLY, content);
       break;
 
     case STATE_DISPLAY_ORDER:
index 67ce81d..d78893e 100644 (file)
@@ -1349,6 +1349,8 @@ freestate(struct rpmdbstate *state)
 #ifdef ENABLE_RPMDB
   if (state->dbenvopened)
     closedbenv(state);
+  if (state->dbpath_allocated)
+    solv_free((char *)state->dbpath);
 #endif
   if (state->rootdir)
     solv_free(state->rootdir);
index 1c83317..4043ef1 100644 (file)
@@ -48,6 +48,7 @@ struct rpmdbstate {
   int dbenvopened;     /* database environment opened */
   int pkgdbopened;     /* package database openend */
   const char *dbpath;  /* path to the database */
+  int dbpath_allocated;        /* do we need to free the path? */
 
   DB_ENV *dbenv;       /* database environment */
   DB *db;              /* packages database */
index 35a46fa..3f9798c 100644 (file)
@@ -12,6 +12,7 @@
  *
  */
 
+#include <rpm/rpmlib.h>
 #include <rpm/rpmts.h>
 #include <rpm/rpmmacro.h>
 
@@ -24,6 +25,7 @@ struct rpmdbstate {
 
   int dbenvopened;     /* database environment opened */
   const char *dbpath;  /* path to the database */
+  int dbpath_allocated;        /* do we need to free the path? */
 
   rpmts ts;
   rpmdbMatchIterator mi;       /* iterator over packages database */
@@ -45,6 +47,13 @@ access_rootdir(struct rpmdbstate *state, const char *dir, int mode)
 static void
 detect_dbpath(struct rpmdbstate *state)
 {
+  state->dbpath = rpmExpand("%{?_dbpath}", NULL);
+  if (state->dbpath && *state->dbpath)
+    {
+      state->dbpath_allocated = 1;
+      return;
+    }
+  solv_free((char *)state->dbpath);
   state->dbpath = access_rootdir(state, "/var/lib/rpm", W_OK) == -1
                   && (access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 0 || access_rootdir(state, "/usr/share/rpm/rpmdb.sqlite", R_OK) == 0)
                   ? "/usr/share/rpm" : "/var/lib/rpm";
@@ -90,6 +99,24 @@ stat_database(struct rpmdbstate *state, struct stat *statbuf)
   return 0;
 }
 
+/* rpm-4.16.0 cannot read the database if _db_backend is not set */
+#ifndef HAVE_RPMDBNEXTITERATORHEADERBLOB
+static void
+set_db_backend()
+{
+  static int db_backend_set;
+  char *db_backend;
+
+  if (db_backend_set)
+    return;
+  db_backend_set = 1;
+  db_backend = rpmExpand("%{?_db_backend}", NULL);
+  if (!db_backend || !*db_backend)
+    rpmReadConfigFiles(NULL, NULL);
+  solv_free(db_backend);
+}
+#endif
+
 static int
 opendbenv(struct rpmdbstate *state)
 {
@@ -108,6 +135,10 @@ opendbenv(struct rpmdbstate *state)
       delMacro(NULL, "_dbpath");
       return 0;
     }
+#ifndef HAVE_RPMDBNEXTITERATORHEADERBLOB
+  if (!strcmp(RPMVERSION, "4.16.0"))
+    set_db_backend();
+#endif
   if (rpmtsOpenDB(ts, O_RDONLY))
     {
       pool_error(state->pool, 0, "rpmtsOpenDB failed: %s", strerror(errno));
index 36d76b5..22f7093 100644 (file)
@@ -110,9 +110,10 @@ struct parsedata {
   Id handle;
   Solvable *solvable;
   time_t buildtime;
-  Id collhandle;
+  Id pkghandle;
   struct solv_xmlparser xmlp;
   struct joindata jd;
+  Id collhandle;
 };
 
 /*
@@ -287,6 +288,12 @@ startElement(struct solv_xmlparser *xmlp, int state, const char *name, const cha
       }
       break;
 
+    case STATE_COLLECTION:
+      {
+        pd->collhandle = repodata_new_handle(pd->data);
+      }
+      break;
+
       /*   <package arch="ppc64" name="imlib-debuginfo" release="6.fc8"
        *            src="http://download.fedoraproject.org/pub/fedora/linux/updates/8/ppc64/imlib-debuginfo-1.9.15-6.fc8.ppc64.rpm"
        *            version="1.9.15">
@@ -326,12 +333,12 @@ startElement(struct solv_xmlparser *xmlp, int state, const char *name, const cha
            solvable->conflicts = repo_addid_dep(pd->repo, solvable->conflicts, id, 0);
          }
 
-        /* who needs the collection anyway? */
-        pd->collhandle = repodata_new_handle(pd->data);
-       repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_NAME, n);
-       repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_EVR, evr);
+        /* UPDATE_COLLECTION is misnamed, it should have been UPDATE_PACKAGE */
+        pd->pkghandle = repodata_new_handle(pd->data);
+       repodata_set_id(pd->data, pd->pkghandle, UPDATE_COLLECTION_NAME, n);
+       repodata_set_id(pd->data, pd->pkghandle, UPDATE_COLLECTION_EVR, evr);
        if (a)
-         repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_ARCH, a);
+         repodata_set_id(pd->data, pd->pkghandle, UPDATE_COLLECTION_ARCH, a);
         break;
       }
     case STATE_MODULE:
@@ -364,6 +371,7 @@ startElement(struct solv_xmlparser *xmlp, int state, const char *name, const cha
         if (arch)
           repodata_set_poolstr(pd->data, module_handle, UPDATE_MODULE_ARCH, arch);
         repodata_add_flexarray(pd->data, pd->handle, UPDATE_MODULE, module_handle);
+        repodata_add_flexarray(pd->data, pd->collhandle, UPDATE_MODULE, module_handle);
         break;
       }
 
@@ -427,15 +435,21 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
       repodata_set_str(pd->data, pd->handle, UPDATE_MESSAGE, content);
       break;
 
-    case STATE_PACKAGE:
-      repodata_add_flexarray(pd->data, pd->handle, UPDATE_COLLECTION, pd->collhandle);
+    case STATE_COLLECTION:
+      repodata_add_flexarray(pd->data, pd->handle, UPDATE_COLLECTIONLIST, pd->collhandle);
       pd->collhandle = 0;
       break;
 
+    case STATE_PACKAGE:
+      repodata_add_flexarray(pd->data, pd->handle, UPDATE_COLLECTION, pd->pkghandle);
+      repodata_add_flexarray(pd->data, pd->collhandle, UPDATE_COLLECTION, pd->pkghandle);
+      pd->pkghandle = 0;
+      break;
+
       /* <filename>libntlm-0.4.2-1.fc8.x86_64.rpm</filename> */
       /* <filename>libntlm-0.4.2-1.fc8.x86_64.rpm</filename> */
     case STATE_FILENAME:
-      repodata_set_str(pd->data, pd->collhandle, UPDATE_COLLECTION_FILENAME, content);
+      repodata_set_str(pd->data, pd->pkghandle, UPDATE_COLLECTION_FILENAME, content);
       break;
 
       /* <reboot_suggested>True</reboot_suggested> */
@@ -444,7 +458,7 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
        {
          /* FIXME: this is per-package, the global flag should be computed at runtime */
          repodata_set_void(pd->data, pd->handle, UPDATE_REBOOT);
-         repodata_set_void(pd->data, pd->collhandle, UPDATE_REBOOT);
+         repodata_set_void(pd->data, pd->pkghandle, UPDATE_REBOOT);
        }
       break;
 
@@ -454,7 +468,7 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
        {
          /* FIXME: this is per-package, the global flag should be computed at runtime */
          repodata_set_void(pd->data, pd->handle, UPDATE_RESTART);
-         repodata_set_void(pd->data, pd->collhandle, UPDATE_RESTART);
+         repodata_set_void(pd->data, pd->pkghandle, UPDATE_RESTART);
        }
       break;
 
@@ -464,7 +478,7 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
        {
          /* FIXME: this is per-package, the global flag should be computed at runtime */
          repodata_set_void(pd->data, pd->handle, UPDATE_RELOGIN);
-         repodata_set_void(pd->data, pd->collhandle, UPDATE_RELOGIN);
+         repodata_set_void(pd->data, pd->pkghandle, UPDATE_RELOGIN);
        }
       break;
     default:
index 0be7a21..8fb6d79 100644 (file)
@@ -1991,6 +1991,7 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
   Id *genid = 0;
   int ngenid = 0;
   Queue autoinstq;
+  int oldjobsize = job ? job->count : 0;
 
   if (resultp)
     *resultp = 0;
@@ -2065,6 +2066,21 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
          int prio, subprio;
          const char *rdata;
 
+         if (pool->considered)
+           {
+             pool_error(pool, 0, "testcase_read: cannot add repos after packages were disabled");
+             continue;
+           }
+         if (solv)
+           {
+             pool_error(pool, 0, "testcase_read: cannot add repos after the solver was created");
+             continue;
+           }
+         if (job && job->count != oldjobsize)
+           {
+             pool_error(pool, 0, "testcase_read: cannot add repos after jobs have been created");
+             continue;
+           }
          prepared = 0;
           if (!poolflagsreset)
            {
@@ -2125,6 +2141,11 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
          int i;
 
          /* must set the disttype before the arch */
+         if (job && job->count != oldjobsize)
+           {
+             pool_error(pool, 0, "testcase_read: cannot change the system after jobs have been created");
+             continue;
+           }
          prepared = 0;
          if (strcmp(pieces[2], "*") != 0)
            {
index 2f4bfe3..d477d71 100644 (file)
@@ -1,4 +1,17 @@
 -------------------------------------------------------------------
+Tue Jan 19 15:09:12 CET 2021 - mls@suse.de
+
+- repo_write: fix handling of nested flexarray
+- improve choicerule generation a bit more to cover more cases
+- harden testcase parser against repos being added too late
+- support python-3.10
+- check %_dbpath macro in rpmdb code
+- handle default/visible/langonly attributes in comps parser
+- support multiple collections in updateinfo parser
+- add '-D' option in rpmdb2solv to set the dbpath
+- bump version to 0.7.17
+
+-------------------------------------------------------------------
 Tue Oct 20 12:04:00 CEST 2020 - mls@suse.de
 
 - do not ask the namespace callback for splitprovides when writing
index 4c1730b..d131e78 100644 (file)
@@ -267,6 +267,10 @@ KNOWNID(LIBSOLV_SELF_DESTRUCT_PKG,      "libsolv-self-destruct-pkg()"),    /* this
 
 KNOWNID(SOLVABLE_CONSTRAINS,           "solvable:constrains"),         /* conda */
 KNOWNID(SOLVABLE_TRACK_FEATURES,       "solvable:track_features"),     /* conda */
+KNOWNID(SOLVABLE_ISDEFAULT,            "solvable:isdefault"),
+KNOWNID(SOLVABLE_LANGONLY,             "solvable:langonly"),
+
+KNOWNID(UPDATE_COLLECTIONLIST,      "update:collectionlist"),  /* list of UPDATE_COLLECTION (actually packages) and UPDATE_MODULE */
 
 KNOWNID(ID_NUM_INTERNAL,               0)
 
index 2a03e58..0f9fc4f 100644 (file)
@@ -570,25 +570,29 @@ collect_needed_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyV
        break;
       case REPOKEY_TYPE_FIXARRAY:
       case REPOKEY_TYPE_FLEXARRAY:
-       if (kv->entry == 0)
+       if (kv->entry)
          {
-           if (kv->eof != 2)
-             *cbdata->sp++ = 0;        /* mark start */
-         }
-       else
-         {
-           /* just finished a schema, rewind to start */
+           /* finish schema, rewind to start */
            Id *sp = cbdata->sp - 1;
            *sp = 0;
            while (sp[-1])
              sp--;
-           if (kv->entry == 1 || key->type == REPOKEY_TYPE_FLEXARRAY)
+           if (sp[-2] >= 0)
+             cbdata->subschemata[sp[-2]] = repodata_schema2id(cbdata->target, sp, 1);
+           cbdata->sp = sp - 2;
+         }
+       if (kv->eof != 2)
+         {
+           /* start new schema */
+           if (kv->entry == 0 || key->type == REPOKEY_TYPE_FLEXARRAY)
              {
                cbdata->subschemata = solv_extend(cbdata->subschemata, cbdata->nsubschemata, 1, sizeof(Id), SCHEMATA_BLOCK);
-               cbdata->subschemata[cbdata->nsubschemata++] = repodata_schema2id(cbdata->target, sp, 1);
+               *cbdata->sp++ = cbdata->nsubschemata++;
              }
-           cbdata->sp = kv->eof == 2 ? sp - 1: sp;
-         }
+           else
+             *cbdata->sp++ = -1;
+           *cbdata->sp++ = 0;
+          }
        break;
       default:
        break;
index 6c8e82b..b3609bb 100644 (file)
@@ -3225,6 +3225,40 @@ solver_choicerulecheck2(Solver *solv, Id pi, Id pt, Queue *q)
   return 0;    /* not newest */
 }
 
+static int
+solver_choicerulecheck3(Solver *solv, Id pt, Queue *q)
+{
+  Pool *pool = solv->pool;
+  Id p, pp;
+  int i;
+
+  if (!q->count || q->elements[0] != pt)
+    {
+      Solvable *s = pool->solvables + pt;
+      if (q->count)
+        queue_empty(q);
+      /* no installed package, so check all with same name */
+      queue_push2(q, pt, 0);
+      FOR_PROVIDES(p, pp, s->name)
+        if (pool->solvables[p].name == s->name && p != pt)
+          queue_push(q, p);
+      queue_push(q, pt);
+    }
+  if (q->count <= 3)
+    return q->count == 3 && q->elements[2] == pt ? 1 : 0;
+  if (!q->elements[1])
+    {
+      queue_deleten(q, 0, 2);
+      policy_filter_unwanted(solv, q, POLICY_MODE_CHOOSE);
+      queue_unshift(q, 1);     /* filter mark */
+      queue_unshift(q, pt);
+    }
+  for (i = 2; i < q->count; i++)
+    if (q->elements[i] == pt)
+      return 1;
+  return 0;    /* not newest */
+}
+
 static inline void
 queue_removeelement(Queue *q, Id el)
 {
@@ -3381,6 +3415,11 @@ solver_addchoicerules(Solver *solv)
              isnewest = 0;
              break;
            }
+         if (!p2 && !solver_choicerulecheck3(solv, -p, &qcheck2))
+           {
+             isnewest = 0;
+             break;
+           }
        }
       /* do extra checking */
       for (i = j = 0; i < qi.count; i += 2)
diff --git a/test/testcases/choicerules/choice3.t b/test/testcases/choicerules/choice3.t
new file mode 100644 (file)
index 0000000..d5d41ac
--- /dev/null
@@ -0,0 +1,17 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Prv: libA
+#>=Pkg: B 1 1 noarch
+#>=Req: libA
+repo available 0 testtags <inline>
+#>=Pkg: B 1 1 noarch
+#>=Req: libA
+#>=Pkg: A 2 1 noarch
+#>=Pkg: Anew 2 1 noarch
+#>=Prv: libA
+system i686 rpm system
+
+job update all packages
+result transaction,problems <inline>
+#>install Anew-2-1.noarch@available
+#>upgrade A-1-1.noarch@system A-2-1.noarch@available
diff --git a/test/testcases/choicerules/choice4.t b/test/testcases/choicerules/choice4.t
new file mode 100644 (file)
index 0000000..1bf9f48
--- /dev/null
@@ -0,0 +1,31 @@
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Prv: libA = 1-1
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Prv: libA = 1-1
+#>=Pkg: Anew 1 1 noarch
+#>=Prv: libA = 1-1
+#>=Pkg: B 1 1 noarch
+#>=Req: libA = 1-1
+#>=Pkg: A 2 1 noarch
+#>=Prv: libA = 2-1
+#>=Pkg: Anew 2 1 noarch
+#>=Prv: libA = 2-1
+#>=Pkg: B 2 1 noarch
+#>=Req: libA = 2-1
+#>=Pkg: A 2 2 noarch
+#>=Prv: libA = 2-2
+#>=Pkg: Anew 2 2 noarch
+#>=Prv: libA = 2-2
+#>=Pkg: B 2 2 noarch
+#>=Req: libA = 2-2
+#>=Pkg: C 2 1 noarch
+#>=Req: B = 2
+system i686 rpm system
+
+job install name C
+result transaction,problems <inline>
+#>install B-2-2.noarch@available
+#>install C-2-1.noarch@available
+#>upgrade A-1-1.noarch@system A-2-2.noarch@available
index 1a04adf..93dd1dc 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#ifdef ENABLE_RPMDB_LIBRPM
+#include <rpm/rpmmacro.h>
+#endif
+
+
 #include "pool.h"
 #include "repo.h"
 #include "repo_rpmdb.h"
@@ -64,6 +69,7 @@ main(int argc, char **argv)
   int nopacks = 0;
   int add_changelog = 0;
   const char *root = 0;
+  const char *dbpath = 0;
   const char *refname = 0;
 #ifdef ENABLE_SUSEREPO
   char *proddir = 0;
@@ -83,7 +89,7 @@ main(int argc, char **argv)
    * parse arguments
    */
   
-  while ((c = getopt(argc, argv, "ACPhnkxXr:p:o:")) >= 0)
+  while ((c = getopt(argc, argv, "ACD:PhnkxXr:p:o:")) >= 0)
     switch (c)
       {
       case 'h':
@@ -92,6 +98,9 @@ main(int argc, char **argv)
       case 'r':
         root = optarg;
         break;
+      case 'D':
+        dbpath = optarg;
+        break;
       case 'n':
        nopacks = 1;
        break;
@@ -160,6 +169,21 @@ main(int argc, char **argv)
 
   if (root && *root)
     pool_set_rootdir(pool, root);
+#ifdef ENABLE_PUBKEY
+  if (dbpath && *dbpath && (!nopacks || pubkeys))
+#else
+  if (dbpath && *dbpath && !nopacks)
+#endif
+    {
+#ifdef ENABLE_RPMDB_LIBRPM
+      char *macro = solv_dupjoin("_dbpath ", dbpath, 0);
+      rpmDefineMacro(NULL, macro, 0);
+      free(macro);
+#else
+      fprintf(stderr, "cannot set dbpath without librpm\n");
+      exit(1);
+#endif
+    }
 
   repo = repo_create(pool, "installed");
   data = repo_add_repodata(repo, 0);