1 From 9b68f47c96625fdafc9b3810de08563abe8e78be Mon Sep 17 00:00:00 2001
2 From: Michael Tremer <michael.tremer@ipfire.org>
3 Date: Wed, 16 May 2012 12:43:25 +0000
4 Subject: [PATCH 11/16] Move C module to newer version of libsolv.
6 Many more improvements which should make the
7 transaction check much faster.
9 po/pakfire.pot | 155 +++++++++++++++++----------------
10 python/pakfire/actions.py | 10 +--
11 python/pakfire/base.py | 36 +++++---
12 python/pakfire/builder.py | 3 +-
13 python/pakfire/filelist.py | 13 +--
14 python/pakfire/packages/installed.py | 18 ++--
15 python/pakfire/repository/database.py | 46 +++++-----
16 python/pakfire/repository/index.py | 9 +-
17 python/pakfire/repository/system.py | 50 +++++++++--
18 python/pakfire/satsolver.py | 65 ++++----------
19 python/pakfire/transaction.py | 49 +++++------
20 python/src/_pakfiremodule.c | 18 +++-
21 python/src/repo.c | 31 ++++---
22 python/src/repo.h | 1 +
23 python/src/request.c | 64 +++++++-------
24 python/src/request.h | 4 +
25 python/src/solution.c | 8 +-
26 python/src/solver.c | 88 +++++++++++--------
27 python/src/solver.h | 5 +-
28 19 files changed, 368 insertions(+), 305 deletions(-)
30 diff --git a/po/pakfire.pot b/po/pakfire.pot
31 index 4fd12e7..db3a88f 100644
34 @@ -8,7 +8,7 @@ msgid ""
36 "Project-Id-Version: PACKAGE VERSION\n"
37 "Report-Msgid-Bugs-To: \n"
38 -"POT-Creation-Date: 2012-04-19 16:57+0200\n"
39 +"POT-Creation-Date: 2012-05-16 12:33+0000\n"
40 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
41 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
42 "Language-Team: LANGUAGE <LL@li.org>\n"
43 @@ -73,13 +73,13 @@ msgid "Exception occured: %s"
46 #: ../python/pakfire/actions.py:364 ../python/pakfire/actions.py:402
47 -#: ../python/pakfire/actions.py:425 ../python/pakfire/actions.py:448
48 -#: ../python/pakfire/actions.py:465 ../python/pakfire/actions.py:484
49 +#: ../python/pakfire/actions.py:424 ../python/pakfire/actions.py:446
50 +#: ../python/pakfire/actions.py:463 ../python/pakfire/actions.py:482
52 msgid "Running transaction test for %s"
55 -#: ../python/pakfire/actions.py:373 ../python/pakfire/actions.py:477
56 +#: ../python/pakfire/actions.py:373
60 @@ -87,63 +87,67 @@ msgstr ""
64 -#: ../python/pakfire/actions.py:431
65 +#: ../python/pakfire/actions.py:430
69 #. Cleaning up leftover files and stuff.
70 -#: ../python/pakfire/actions.py:455
71 +#: ../python/pakfire/actions.py:453
75 -#: ../python/pakfire/actions.py:493
76 +#: ../python/pakfire/actions.py:475
80 +#: ../python/pakfire/actions.py:491
84 -#: ../python/pakfire/base.py:315
85 +#: ../python/pakfire/base.py:320
86 msgid "Local install repository"
89 -#: ../python/pakfire/base.py:372
90 +#: ../python/pakfire/base.py:377
92 msgid "Could not find any installed package providing \"%s\"."
95 -#: ../python/pakfire/base.py:378
96 +#: ../python/pakfire/base.py:383
98 msgid "Multiple reinstall candidates for \"%(pattern)s\": %(pkgs)s"
101 -#: ../python/pakfire/base.py:382 ../python/pakfire/base.py:450
102 -#: ../python/pakfire/base.py:487 ../python/pakfire/base.py:546
103 -#: ../python/pakfire/base.py:567 ../python/pakfire/transaction.py:396
104 +#: ../python/pakfire/base.py:387 ../python/pakfire/base.py:455
105 +#: ../python/pakfire/base.py:491 ../python/pakfire/base.py:553
106 +#: ../python/pakfire/base.py:574 ../python/pakfire/transaction.py:390
107 msgid "Nothing to do"
110 -#: ../python/pakfire/base.py:407
111 +#: ../python/pakfire/base.py:412
113 msgid "Could not find package %s in a remote repository."
116 -#: ../python/pakfire/base.py:479
117 +#: ../python/pakfire/base.py:483
119 msgid "Excluding %s."
122 -#: ../python/pakfire/base.py:531
123 +#: ../python/pakfire/base.py:535
125 msgid "\"%s\" package does not seem to be installed."
128 -#: ../python/pakfire/base.py:681
129 +#: ../python/pakfire/base.py:688
130 msgid "Build command has failed."
133 -#: ../python/pakfire/base.py:716
134 +#: ../python/pakfire/base.py:723
135 msgid "New repository"
138 -#: ../python/pakfire/base.py:752
139 +#: ../python/pakfire/base.py:764
140 msgid "Everything is fine."
143 @@ -199,72 +203,72 @@ msgstr ""
144 msgid "Running installation test..."
147 -#: ../python/pakfire/builder.py:766
148 +#: ../python/pakfire/builder.py:767
149 msgid "Installation test succeeded."
152 #. Create a progressbar.
153 -#: ../python/pakfire/builder.py:803
154 +#: ../python/pakfire/builder.py:804
155 msgid "Signing packages..."
158 -#: ../python/pakfire/builder.py:837
159 +#: ../python/pakfire/builder.py:838
160 msgid "Dumping package information:"
163 #. Walk through the whole tree and collect all files
164 #. that are on the same disk (not crossing mountpoints).
165 -#: ../python/pakfire/builder.py:867
166 +#: ../python/pakfire/builder.py:868
167 msgid "Creating filelist..."
170 #. Create a nice progressbar.
171 -#: ../python/pakfire/builder.py:886
172 +#: ../python/pakfire/builder.py:887
173 msgid "Compressing files..."
176 -#: ../python/pakfire/builder.py:905
177 +#: ../python/pakfire/builder.py:906
179 msgid "Cache file was successfully created at %s."
182 -#: ../python/pakfire/builder.py:906
183 +#: ../python/pakfire/builder.py:907
185 msgid " Containing %(files)s files, it has a size of %(size)s."
188 #. Make a nice progress bar as always.
189 -#: ../python/pakfire/builder.py:917
190 +#: ../python/pakfire/builder.py:918
191 msgid "Extracting files..."
194 #. Update all packages.
195 -#: ../python/pakfire/builder.py:937
196 +#: ../python/pakfire/builder.py:938
197 msgid "Updating packages from cache..."
200 #. Package the result.
201 #. Make all these little package from the build environment.
202 -#: ../python/pakfire/builder.py:1075
203 +#: ../python/pakfire/builder.py:1076
204 msgid "Creating packages:"
207 #. Execute the buildscript of this stage.
208 -#: ../python/pakfire/builder.py:1089
209 +#: ../python/pakfire/builder.py:1090
211 msgid "Running stage %s:"
214 -#: ../python/pakfire/builder.py:1107
215 +#: ../python/pakfire/builder.py:1108
217 msgid "Could not remove static libraries: %s"
220 -#: ../python/pakfire/builder.py:1113
221 +#: ../python/pakfire/builder.py:1114
222 msgid "Compressing man pages did not complete successfully."
225 -#: ../python/pakfire/builder.py:1133
226 +#: ../python/pakfire/builder.py:1134
227 msgid "Extracting debuginfo did not complete with success. Aborting build."
230 @@ -416,7 +420,7 @@ msgstr ""
231 msgid "Give name of at least one package to check."
234 -#: ../python/pakfire/cli.py:348 ../python/pakfire/transaction.py:405
235 +#: ../python/pakfire/cli.py:348 ../python/pakfire/transaction.py:399
239 @@ -740,7 +744,7 @@ msgid "Job: %(name)s"
242 #: ../python/pakfire/cli.py:1078 ../python/pakfire/packages/base.py:107
243 -#: ../python/pakfire/transaction.py:404
244 +#: ../python/pakfire/transaction.py:398
248 @@ -992,7 +996,7 @@ msgstr ""
249 msgid "Running pakfire-build in a pakfire container?"
252 -#: ../python/pakfire/errors.py:94 ../python/pakfire/transaction.py:475
253 +#: ../python/pakfire/errors.py:94 ../python/pakfire/transaction.py:469
254 msgid "Transaction test was not successful"
257 @@ -1085,7 +1089,7 @@ msgstr ""
261 -#: ../python/pakfire/packages/base.py:110 ../python/pakfire/transaction.py:404
262 +#: ../python/pakfire/packages/base.py:110 ../python/pakfire/transaction.py:398
266 @@ -1093,7 +1097,7 @@ msgstr ""
270 -#: ../python/pakfire/packages/base.py:115 ../python/pakfire/transaction.py:405
271 +#: ../python/pakfire/packages/base.py:115 ../python/pakfire/transaction.py:399
275 @@ -1173,7 +1177,7 @@ msgstr ""
279 -#: ../python/pakfire/packages/base.py:528
280 +#: ../python/pakfire/packages/base.py:534
282 msgid "Config file saved as %s."
284 @@ -1243,16 +1247,16 @@ msgstr ""
285 msgid "Building source package %s:"
288 -#: ../python/pakfire/repository/database.py:116
289 +#: ../python/pakfire/repository/database.py:123
290 msgid "The format of the database is not supported by this version of pakfire."
293 -#: ../python/pakfire/repository/database.py:224
294 +#: ../python/pakfire/repository/database.py:231
296 msgid "Cannot use database with version greater than %s."
299 -#: ../python/pakfire/repository/database.py:226
300 +#: ../python/pakfire/repository/database.py:233
302 msgid "Migrating database from format %(old)s to %(new)s."
304 @@ -1320,33 +1324,38 @@ msgstr ""
305 msgid "Trying an other mirror."
308 -#: ../python/pakfire/satsolver.py:230 ../python/pakfire/satsolver.py:256
309 +#. Create a progressbar.
310 +#: ../python/pakfire/repository/system.py:66
311 +msgid "Loading installed packages"
314 +#: ../python/pakfire/satsolver.py:199 ../python/pakfire/satsolver.py:225
315 msgid "The solver returned one problem:"
318 #. Ask the user if he or she want to modify the request. If not, just exit.
319 -#: ../python/pakfire/satsolver.py:272
320 +#: ../python/pakfire/satsolver.py:241
321 msgid "Do you want to manually alter the request?"
324 -#: ../python/pakfire/satsolver.py:275
325 +#: ../python/pakfire/satsolver.py:244
326 msgid "You can now try to satisfy the solver by modifying your request."
329 -#: ../python/pakfire/satsolver.py:280
330 +#: ../python/pakfire/satsolver.py:249
331 msgid "Which problem to you want to resolve?"
334 -#: ../python/pakfire/satsolver.py:282
335 +#: ../python/pakfire/satsolver.py:251
336 msgid "Press enter to try to re-solve the request."
339 -#: ../python/pakfire/satsolver.py:313
340 +#: ../python/pakfire/satsolver.py:282
342 msgid " Solution: %s"
345 -#: ../python/pakfire/satsolver.py:322
346 +#: ../python/pakfire/satsolver.py:291
350 @@ -1354,110 +1363,110 @@ msgstr ""
351 msgid "Could not be determined"
354 -#: ../python/pakfire/transaction.py:95
355 +#: ../python/pakfire/transaction.py:94
357 msgid "file %(name)s from %(pkg1)s conflicts with file from package %(pkg2)s"
360 -#: ../python/pakfire/transaction.py:101
361 +#: ../python/pakfire/transaction.py:100
363 msgid "file %(name)s from %(pkg)s conflicts with files from %(pkgs)s"
366 -#: ../python/pakfire/transaction.py:109
367 +#: ../python/pakfire/transaction.py:108
370 "There is not enough space left on %(name)s. Need at least %(size)s to "
371 "perform transaction."
374 -#: ../python/pakfire/transaction.py:327
375 +#: ../python/pakfire/transaction.py:321
377 msgid "Not enough space to download %s of packages."
380 -#: ../python/pakfire/transaction.py:330
381 +#: ../python/pakfire/transaction.py:324
382 msgid "Downloading packages:"
385 -#: ../python/pakfire/transaction.py:404
386 +#: ../python/pakfire/transaction.py:398
390 -#: ../python/pakfire/transaction.py:409
391 +#: ../python/pakfire/transaction.py:403
395 -#: ../python/pakfire/transaction.py:410
396 +#: ../python/pakfire/transaction.py:404
397 msgid "Reinstalling:"
400 -#: ../python/pakfire/transaction.py:411
401 +#: ../python/pakfire/transaction.py:405
405 -#: ../python/pakfire/transaction.py:412
406 +#: ../python/pakfire/transaction.py:406
410 -#: ../python/pakfire/transaction.py:413
411 +#: ../python/pakfire/transaction.py:407
415 -#: ../python/pakfire/transaction.py:419
416 +#: ../python/pakfire/transaction.py:413
417 msgid "Transaction Summary"
420 -#: ../python/pakfire/transaction.py:426
421 +#: ../python/pakfire/transaction.py:420
425 -#: ../python/pakfire/transaction.py:432
426 +#: ../python/pakfire/transaction.py:426
428 msgid "Total download size: %s"
431 -#: ../python/pakfire/transaction.py:436
432 +#: ../python/pakfire/transaction.py:430
434 msgid "Installed size: %s"
437 -#: ../python/pakfire/transaction.py:439
438 +#: ../python/pakfire/transaction.py:433
440 msgid "Freed size: %s"
443 -#: ../python/pakfire/transaction.py:450
444 +#: ../python/pakfire/transaction.py:444
445 msgid "Is this okay?"
448 -#: ../python/pakfire/transaction.py:456
449 +#: ../python/pakfire/transaction.py:450
450 msgid "Running Transaction Test"
453 -#: ../python/pakfire/transaction.py:468
454 +#: ../python/pakfire/transaction.py:462
455 msgid "Transaction Test Succeeded"
458 #. Make a nice progressbar.
459 -#: ../python/pakfire/transaction.py:501
460 +#: ../python/pakfire/transaction.py:495
461 msgid "Verifying signatures..."
464 -#: ../python/pakfire/transaction.py:533
465 +#: ../python/pakfire/transaction.py:527
467 msgid "Found %s signature error(s)!"
470 -#: ../python/pakfire/transaction.py:538
471 +#: ../python/pakfire/transaction.py:532
472 msgid "Going on because we are running in permissive mode."
475 -#: ../python/pakfire/transaction.py:539
476 +#: ../python/pakfire/transaction.py:533
477 msgid "This is dangerous!"
480 -#: ../python/pakfire/transaction.py:560
481 +#: ../python/pakfire/transaction.py:554
482 msgid "Running transaction"
485 diff --git a/python/pakfire/actions.py b/python/pakfire/actions.py
486 index cdc2778..9fda261 100644
487 --- a/python/pakfire/actions.py
488 +++ b/python/pakfire/actions.py
489 @@ -417,7 +417,6 @@ class ActionRemove(Action):
490 def __init__(self, *args, **kwargs):
491 Action.__init__(self, *args, **kwargs)
493 - # XXX This is ugly, but works for the moment.
494 self.pkg = self.local.db.get_package_from_solv(self.pkg_solv)
497 @@ -431,7 +430,7 @@ class ActionRemove(Action):
498 self.pkg.cleanup(_("Removing"), prefix=self.pakfire.path)
500 # Remove package from the database.
501 - self.local.rem_package(self.pkg)
502 + self.local.rem_package(self.pkg_solv)
505 class ActionCleanup(Action):
506 @@ -440,7 +439,6 @@ class ActionCleanup(Action):
507 def __init__(self, *args, **kwargs):
508 Action.__init__(self, *args, **kwargs)
510 - # XXX This is ugly, but works for the moment.
511 self.pkg = self.local.db.get_package_from_solv(self.pkg_solv)
514 @@ -455,7 +453,7 @@ class ActionCleanup(Action):
515 self.pkg.cleanup(_("Cleanup"), prefix=self.pakfire.path)
517 # Remove package from the database.
518 - self.local.rem_package(self.pkg)
519 + self.local.rem_package(self.pkg_solv)
522 class ActionReinstall(Action):
523 @@ -471,10 +469,10 @@ class ActionReinstall(Action):
525 # Remove package from the database and add it afterwards.
526 # Sounds weird, but fixes broken entries in the database.
527 - self.local.rem_package(self.pkg)
528 + self.local.rem_package(self.pkg_solv)
529 self.local.add_package(self.pkg)
531 - self.pkg.extract(_("Installing"), prefix=self.pakfire.path)
532 + self.pkg.extract(_("Reinstalling"), prefix=self.pakfire.path)
535 class ActionDowngrade(Action):
536 diff --git a/python/pakfire/base.py b/python/pakfire/base.py
537 index 6e2e52e..54485a5 100644
538 --- a/python/pakfire/base.py
539 +++ b/python/pakfire/base.py
540 @@ -132,7 +132,7 @@ class Pakfire(object):
544 - def create_request(self, builder=False, install=None, remove=None, update=None):
545 + def create_request(self, builder=False, install=None, remove=None, update=None, updateall=False):
546 request = satsolver.Request(self.pool)
548 # Add multiinstall information.
549 @@ -151,6 +151,11 @@ class Pakfire(object):
550 for req in self.expand_requires(update):
553 + # Configure the request to update all packages
556 + request.updateall()
558 # Return the request.
561 @@ -467,12 +472,11 @@ class Pakfire(object):
563 # If there are given any packets on the command line, we will
564 # only update them. Otherwise, we update the whole system.
572 - request = self.create_request(update=pkgs)
573 + request = self.create_request(update=pkgs, updateall=updateall)
575 # Exclude packages that should not be updated.
576 for exclude in excludes or []:
577 @@ -481,7 +485,7 @@ class Pakfire(object):
578 exclude = self.create_relation(exclude)
579 request.lock(exclude)
581 - solver = self.solv(request, logger=logger, update=update, **kwargs)
582 + solver = self.solv(request, logger=logger, **kwargs)
584 if not solver.status:
585 logger.info(_("Nothing to do"))
586 @@ -534,8 +538,11 @@ class Pakfire(object):
590 - solver = self.solv(request, allow_downgrade=True, allow_vendorchange=allow_vendorchange,
591 - allow_archchange=allow_archchange)
592 + solver = self.solv(request,
593 + allow_downgrade=True,
594 + allow_vendorchange=allow_vendorchange,
595 + allow_archchange=allow_archchange,
597 assert solver.status is True
599 # Create the transaction.
600 @@ -556,7 +563,7 @@ class Pakfire(object):
601 request = self.create_request(remove=pkgs)
604 - solver = self.solv(request, uninstall=True)
605 + solver = self.solv(request, allow_uninstall=True)
606 assert solver.status is True
608 # Create the transaction.
609 @@ -737,7 +744,7 @@ class Pakfire(object):
610 # Clean up repository caches.
613 - def check(self, downgrade=True, uninstall=True):
614 + def check(self, allow_downgrade=True, allow_uninstall=True):
616 Try to fix any errors in the system.
618 @@ -745,8 +752,13 @@ class Pakfire(object):
619 # For that we create an empty request and solver and try to solve
621 request = self.create_request()
622 - solver = self.solv(request, fix_system=True, allow_downgrade=downgrade,
623 - uninstall=uninstall)
626 + solver = self.solv(
628 + allow_downgrade=allow_downgrade,
629 + allow_uninstall=allow_uninstall,
632 if solver.status is False:
633 log.info(_("Everything is fine."))
634 diff --git a/python/pakfire/builder.py b/python/pakfire/builder.py
635 index 494049e..863ade3 100644
636 --- a/python/pakfire/builder.py
637 +++ b/python/pakfire/builder.py
638 @@ -761,7 +761,8 @@ class BuildEnviron(object):
640 # Install all packages that were built.
641 self.install(self.find_result_packages(),
642 - uninstall=True, signatures_mode="disabled")
643 + allow_vendorchange=True, allow_archchange=True,
644 + allow_uninstall=True, signatures_mode="disabled")
646 self.log.info(_("Installation test succeeded."))
648 diff --git a/python/pakfire/filelist.py b/python/pakfire/filelist.py
649 index ef7ee35..4bac6ef 100644
650 --- a/python/pakfire/filelist.py
651 +++ b/python/pakfire/filelist.py
652 @@ -74,13 +74,12 @@ class File(_File):
655 class FileDatabase(_File):
656 - def __init__(self, pakfire, db, row_id):
657 + def __init__(self, pakfire, db, row_id, row=None):
658 _File.__init__(self, pakfire)
668 @@ -91,13 +90,7 @@ class FileDatabase(_File):
670 c.execute("SELECT * FROM files WHERE id = ? LIMIT 1", (self.row_id,))
672 - # Check if we got the same row.
673 - #assert c.lastrowid == self.row_id
679 + self.__row = c.fetchone()
683 diff --git a/python/pakfire/packages/installed.py b/python/pakfire/packages/installed.py
684 index 5a7763b..33c241d 100644
685 --- a/python/pakfire/packages/installed.py
686 +++ b/python/pakfire/packages/installed.py
687 @@ -39,6 +39,7 @@ class DatabasePackage(Package):
691 + self._filelist = None
693 for key in data.keys():
694 self._data[key] = data[key]
695 @@ -169,20 +170,21 @@ class DatabasePackage(Package):
699 - return self.metadata.get("filename") # XXX basename?
700 + return self.metadata.get("filename")
705 + if self._filelist is None:
706 + self._filelist = []
708 - c = self.db.cursor()
709 - c.execute("SELECT id FROM files WHERE pkg = ?", (self.id,))
710 + c = self.db.cursor()
711 + c.execute("SELECT * FROM files WHERE pkg = ?", (self.id,))
714 - file = pakfire.filelist.FileDatabase(self.pakfire, self.db, id[0])
715 - filelist.append(file)
716 + for row in c.fetchall():
717 + file = pakfire.filelist.FileDatabase(self.pakfire, self.db, row["id"], row)
718 + self._filelist.append(file)
721 + return self._filelist
724 def configfiles(self):
725 diff --git a/python/pakfire/repository/database.py b/python/pakfire/repository/database.py
726 index 6f8f397..a5e5b85 100644
727 --- a/python/pakfire/repository/database.py
728 +++ b/python/pakfire/repository/database.py
729 @@ -53,6 +53,13 @@ class Database(object):
735 + if self._db is None:
743 @@ -338,11 +345,11 @@ class DatabaseLocal(Database):
744 #c.execute("SELECT id FROM packages WHERE name = ? AND epoch = ? AND version = ?"
745 # " AND release = ? LIMIT 1", (pkg.name, pkg.epoch, pkg.version, pkg.release,))
758 # First, delete all files from the database and then delete the pkg itself.
759 c.execute("DELETE FROM files WHERE pkg = ?", (id,))
760 @@ -364,34 +371,29 @@ class DatabaseLocal(Database):
765 + c = self.db.execute("SELECT * FROM packages ORDER BY name")
767 - c.execute("SELECT * FROM packages ORDER BY name")
770 + for row in c.fetchall():
771 yield packages.DatabasePackage(self.pakfire, self.repo, self, row)
775 def get_filelist(self):
777 - c.execute("SELECT DISTINCT name FROM files")
781 - ret.append(row["name"])
784 + c = self.db.execute("SELECT name FROM files")
787 + return [r["name"] for r in c.fetchall()]
789 def get_package_from_solv(self, solv_pkg):
791 - c.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,))
792 + assert solv_pkg.uuid
794 + c = self.db.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,))
798 - return packages.DatabasePackage(self.pakfire, self.repo, self, row)
803 + return packages.DatabasePackage(self.pakfire, self.repo, self, row)
807 diff --git a/python/pakfire/repository/index.py b/python/pakfire/repository/index.py
808 index fac1c2f..7620b38 100644
809 --- a/python/pakfire/repository/index.py
810 +++ b/python/pakfire/repository/index.py
811 @@ -24,6 +24,7 @@ import os
813 log = logging.getLogger("pakfire")
815 +import pakfire.packages as packages
816 import pakfire.satsolver as satsolver
819 @@ -147,8 +148,12 @@ class Index(object):
820 solvable.add_provides(rel)
822 def rem_package(self, pkg):
823 - # XXX delete the solvable from the index.
826 + Delete the solvable from the index.
828 + assert isinstance(pkg, packages.SolvPackage)
830 + self.solver_repo.rem_solv(pkg)
834 diff --git a/python/pakfire/repository/system.py b/python/pakfire/repository/system.py
835 index ce3e979..386f252 100644
836 --- a/python/pakfire/repository/system.py
837 +++ b/python/pakfire/repository/system.py
840 ###############################################################################
847 +import pakfire.packages as packages
848 +import pakfire.util as util
850 +from pakfire.constants import *
851 +from pakfire.i18n import _
853 class RepositorySystem(base.RepositoryFactory):
854 def __init__(self, pakfire):
855 base.RepositoryFactory.__init__(self, pakfire, "@system", "Local repository")
856 @@ -33,6 +41,10 @@ class RepositorySystem(base.RepositoryFactory):
857 self.pool.set_installed(self.solver_repo)
860 + def cache_file(self):
861 + return os.path.join(self.pakfire.path, PACKAGES_SOLV)
866 The local repository has always a high priority.
867 @@ -40,14 +52,35 @@ class RepositorySystem(base.RepositoryFactory):
870 def update(self, force=False, offline=False):
872 - force = len(self) == 0
873 + # XXX using the cache is currently disabled
875 + # if os.path.exists(self.cache_file):
876 + # self.index.read(self.cache_file)
878 + # force = len(self) == 0
883 + # Create a progressbar.
884 + pb = util.make_progress(_("Loading installed packages"), len(self.db))
886 + # Remove all data from the current index.
890 for pkg in self.db.packages:
895 self.index.add_package(pkg)
897 + self.index.optimize()
903 # Commit the database to disk.
905 @@ -55,20 +88,23 @@ class RepositorySystem(base.RepositoryFactory):
906 # Make sure that all data in the index is accessable.
907 self.index.optimize()
909 + # Write the content of the index to a file
910 + # for fast parsing.
911 + # XXX this is currently disabled
912 + #self.index.write(self.cache_file)
914 def add_package(self, pkg):
915 # Add package to the database.
916 self.db.add_package(pkg)
917 self.index.add_package(pkg)
919 def rem_package(self, pkg):
920 + assert isinstance(pkg, packages.SolvPackage), pkg
922 # Remove package from the database.
923 self.db.rem_package(pkg)
924 self.index.rem_package(pkg)
930 - for pkg in self.db.packages:
931 - for file in pkg.filelist:
933 + return self.db.get_filelist()
934 diff --git a/python/pakfire/satsolver.py b/python/pakfire/satsolver.py
935 index c3629ce..48c6d0d 100644
936 --- a/python/pakfire/satsolver.py
937 +++ b/python/pakfire/satsolver.py
938 @@ -111,6 +111,13 @@ class Request(_pakfire.Request):
941 class Solver(object):
943 + "allow_archchange" : SOLVER_FLAG_ALLOW_ARCHCHANGE,
944 + "allow_downgrade" : SOLVER_FLAG_ALLOW_DOWNGRADE,
945 + "allow_uninstall" : SOLVER_FLAG_ALLOW_UNINSTALL,
946 + "allow_vendorchange" : SOLVER_FLAG_ALLOW_VENDORCHANGE,
949 def __init__(self, pakfire, request, logger=None):
951 logger = logging.getLogger("pakfire")
952 @@ -119,27 +126,6 @@ class Solver(object):
953 self.pakfire = pakfire
954 self.pool = self.pakfire.pool
956 - # Default settings.
958 - # Update all installed packages?
961 - # Allow to uninstall any packages?
962 - "uninstall" : False,
964 - # Allow to downgrade any packages?
965 - "allow_downgrade" : False,
967 - # Allow packages to change their vendors?
968 - "allow_vendorchange" : False,
970 - # Allow packages to change their arch?
971 - "allow_archchange" : False,
974 - "fix_system" : False,
977 self.request = request
978 assert self.request, "Empty request?"
980 @@ -159,40 +145,23 @@ class Solver(object):
981 self.__problems = None
982 self.__transaction = None
984 - def set(self, key, value):
985 - assert self.settings.has_key(key), "Unknown configuration setting: %s" % key
986 - assert value in (True, False), "Invalid value: %s" % value
988 + def set(self, option, value):
990 - self.settings[key] = value
991 + flag = self.option2flag[option]
994 + raise Exception, "Unknown configuration setting: %s" % option
995 + self.solver.set_flag(flag, value)
997 - def get(self, key):
998 - assert self.settings.has_key(key), "Unknown configuration setting: %s" % key
1000 - return self.settings.get(key)
1001 + def get(self, option):
1003 + flag = self.option2flag[option]
1005 + raise Exception, "Unknown configuration setting: %s" % option
1006 + return self.solver.get_flag(flag)
1009 assert self.status is None, "Solver did already solve something."
1011 - # Apply solver configuration.
1012 - self.solver.set_fix_system(self.get("fix_system"))
1013 - self.solver.set_allow_uninstall(self.get("uninstall"))
1014 - self.solver.set_allow_downgrade(self.get("allow_downgrade"))
1016 - # Optionally allow packages to change their vendors.
1017 - # This is not recommended because it may have weird effects.
1018 - self.solver.set_allow_vendorchange(self.get("allow_vendorchange"))
1020 - # Optionally allow packages ot change their architecture.
1021 - self.solver.set_allow_archchange(self.get("allow_archchange"))
1023 - # Configure the solver for an update.
1024 - if self.get("update"):
1025 - self.solver.set_updatesystem(True)
1026 - self.solver.set_do_split_provides(True)
1028 # Actually solve the request.
1029 start_time = time.time()
1030 self.status = self.solver.solve(self.request)
1031 diff --git a/python/pakfire/transaction.py b/python/pakfire/transaction.py
1032 index 58b52c6..10a1277 100644
1033 --- a/python/pakfire/transaction.py
1034 +++ b/python/pakfire/transaction.py
1035 @@ -59,15 +59,16 @@ class TransactionCheck(object):
1038 def error_files(self):
1042 - for name, files in self.filelist.items():
1043 - if len(files) <= 1:
1045 + for name, count in self.filelist.items():
1050 + return sorted(ret)
1053 + def provides_file(self, name):
1054 + return [] # XXX TODO
1057 def successful(self):
1058 @@ -85,18 +86,16 @@ class TransactionCheck(object):
1060 logger = logging.getLogger("pakfire")
1062 - for name, files in sorted(self.error_files.items()):
1063 - assert len(files) >= 2
1065 - pkgs = [f.pkg.friendly_name for f in files]
1066 + for file in self.error_files:
1067 + pkgs = self.provides_file(file)
1069 - if len(files) == 2:
1070 + if len(pkgs) == 2:
1072 _("file %(name)s from %(pkg1)s conflicts with file from package %(pkg2)s") % \
1073 { "name" : name, "pkg1" : pkgs[0], "pkg2" : pkgs[1] }
1076 - elif len(files) >= 3:
1077 + elif len(pkgs) >= 3:
1079 _("file %(name)s from %(pkg)s conflicts with files from %(pkgs)s") % \
1080 { "name" : name, "pkg" : pkgs[0], "pkgs" : i18n.list(pkgs[1:])}
1081 @@ -113,7 +112,7 @@ class TransactionCheck(object):
1084 for file in self.pakfire.repos.local.filelist:
1085 - filelist[file.name] = [file,]
1086 + filelist[file] = 1
1090 @@ -122,11 +121,10 @@ class TransactionCheck(object):
1094 - if self.filelist.has_key(file.name):
1095 - self.filelist[file.name].append(file)
1098 - self.filelist[file.name] = [file,]
1100 + self.filelist[file.name] += 1
1102 + self.filelist[file.name] = 1
1104 # Add all filesize data to mountpoints.
1105 self.mountpoints.add_pkg(pkg)
1106 @@ -136,14 +134,10 @@ class TransactionCheck(object):
1110 - if not self.filelist.has_key(file.name):
1113 - for f in self.filelist[file.name]:
1114 - if not f.pkg == pkg:
1117 - self.filelist[file.name].remove(f)
1119 + self.filelist[file.name] -= 1
1123 # Remove all filesize data from mountpoints.
1124 self.mountpoints.rem_pkg(pkg)
1125 @@ -562,8 +556,11 @@ class Transaction(object):
1126 for action in self.actions:
1130 except ActionError, e:
1131 logger.error("Action finished with an error: %s - %s" % (action, e))
1132 + #except Exception, e:
1133 + # logger.error(_("An unforeseen error occoured: %s") % e)
1137 diff --git a/python/src/_pakfiremodule.c b/python/src/_pakfiremodule.c
1138 index d4ea688..8e80468 100644
1139 --- a/python/src/_pakfiremodule.c
1140 +++ b/python/src/_pakfiremodule.c
1141 @@ -80,6 +80,9 @@ static PyMethodDef Request_methods[] = {
1142 {"noobsoletes_solvable", (PyCFunction)Request_noobsoletes_solvable, METH_VARARGS, NULL},
1143 {"noobsoletes_relation", (PyCFunction)Request_noobsoletes_relation, METH_VARARGS, NULL},
1144 {"noobsoletes_name", (PyCFunction)Request_noobsoletes_name, METH_VARARGS, NULL},
1145 + {"updateall", (PyCFunction)Request_updateall, METH_NOARGS, NULL},
1146 + {"distupgrade", (PyCFunction)Request_distupgrade, METH_NOARGS, NULL},
1147 + {"verify", (PyCFunction)Request_verify, METH_NOARGS, NULL},
1148 { NULL, NULL, 0, NULL }
1151 @@ -99,6 +102,7 @@ static PyMethodDef Repo_methods[] = {
1152 {"internalize", (PyCFunction)Repo_internalize, METH_NOARGS, NULL},
1153 {"clear", (PyCFunction)Repo_clear, METH_NOARGS, NULL},
1154 {"get_all", (PyCFunction)Repo_get_all, METH_NOARGS, NULL},
1155 + {"rem_solv", (PyCFunction)Repo_rem_solv, METH_VARARGS, NULL},
1156 { NULL, NULL, 0, NULL }
1159 @@ -152,10 +156,8 @@ static PyMethodDef Solution_methods[] = {
1161 static PyMethodDef Solver_methods[] = {
1162 {"solve", (PyCFunction)Solver_solve, METH_VARARGS, NULL},
1163 - {"get_fix_system", (PyCFunction)Solver_get_fix_system, METH_NOARGS, NULL},
1164 - {"set_fix_system", (PyCFunction)Solver_set_fix_system, METH_VARARGS, NULL},
1165 - {"get_allow_downgrade", (PyCFunction)Solver_get_allow_downgrade, METH_NOARGS, NULL},
1166 - {"set_allow_downgrade", (PyCFunction)Solver_set_allow_downgrade, METH_VARARGS, NULL},
1167 + {"get_flag", (PyCFunction)Solver_get_flag, METH_VARARGS, NULL},
1168 + {"set_flag", (PyCFunction)Solver_set_flag, METH_VARARGS, NULL},
1169 {"get_allow_archchange", (PyCFunction)Solver_get_allow_archchange, METH_NOARGS, NULL},
1170 {"set_allow_archchange", (PyCFunction)Solver_set_allow_archchange, METH_VARARGS, NULL},
1171 {"get_allow_vendorchange", (PyCFunction)Solver_get_allow_vendorchange, METH_NOARGS, NULL},
1172 @@ -307,4 +309,12 @@ void init_pakfire(void) {
1173 PyDict_SetItemString(d, "SOLVER_RULE_FEATURE", Py_BuildValue("i", SOLVER_RULE_FEATURE));
1174 PyDict_SetItemString(d, "SOLVER_RULE_LEARNT", Py_BuildValue("i", SOLVER_RULE_LEARNT));
1175 PyDict_SetItemString(d, "SOLVER_RULE_CHOICE", Py_BuildValue("i", SOLVER_RULE_CHOICE));
1177 + /* Solver flags */
1178 + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_DOWNGRADE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_DOWNGRADE));
1179 + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_ARCHCHANGE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_ARCHCHANGE));
1180 + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_VENDORCHANGE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_VENDORCHANGE));
1181 + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_UNINSTALL", Py_BuildValue("i", SOLVER_FLAG_ALLOW_UNINSTALL));
1182 + PyDict_SetItemString(d, "SOLVER_FLAG_NO_UPDATEPROVIDE", Py_BuildValue("i", SOLVER_FLAG_NO_UPDATEPROVIDE));
1183 + PyDict_SetItemString(d, "SOLVER_FLAG_SPLITPROVIDES", Py_BuildValue("i", SOLVER_FLAG_SPLITPROVIDES));
1185 diff --git a/python/src/repo.c b/python/src/repo.c
1186 index 6621c3b..4bc112a 100644
1187 --- a/python/src/repo.c
1188 +++ b/python/src/repo.c
1189 @@ -47,7 +47,6 @@ PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1192 if (!PyArg_ParseTuple(args, "Os", &pool, &name)) {
1193 - /* XXX raise exception */
1197 @@ -67,7 +66,6 @@ PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1200 PyObject *Repo_dealloc(RepoObject *self) {
1201 - // repo_free(self->_repo, 0);
1202 self->ob_type->tp_free((PyObject *)self);
1205 @@ -97,7 +95,6 @@ PyObject *Repo_set_enabled(RepoObject *self, PyObject *args) {
1208 if (!PyArg_ParseTuple(args, "b", &enabled)) {
1209 - /* XXX raise exception */
1213 @@ -132,13 +129,12 @@ PyObject *Repo_write(RepoObject *self, PyObject *args) {
1214 char exception[STRING_SIZE];
1216 if (!PyArg_ParseTuple(args, "s", &filename)) {
1217 - /* XXX raise exception */
1221 // Prepare the pool and internalize all attributes.
1222 - _Pool_prepare(self->_repo->pool);
1223 + //_Pool_prepare(self->_repo->pool);
1225 - // XXX catch if file cannot be opened
1227 if ((fp = fopen(filename, "wb")) == NULL) {
1228 snprintf(exception, STRING_SIZE - 1, "Could not open file for writing: %s (%s).",
1229 @@ -147,8 +143,7 @@ PyObject *Repo_write(RepoObject *self, PyObject *args) {
1233 - repo_write(self->_repo, fp, NULL, NULL, 0);
1235 + repo_write(self->_repo, fp);
1239 @@ -158,14 +153,12 @@ PyObject *Repo_read(RepoObject *self, PyObject *args) {
1240 const char *filename;
1242 if (!PyArg_ParseTuple(args, "s", &filename)) {
1243 - /* XXX raise exception */
1247 // XXX catch if file cannot be opened
1248 FILE *fp = fopen(filename, "rb");
1250 - repo_add_solv(self->_repo, fp);
1252 + repo_add_solv(self->_repo, fp, 0);
1256 @@ -209,3 +202,17 @@ PyObject *Repo_get_all(RepoObject *self) {
1261 +PyObject *Repo_rem_solv(RepoObject *self, PyObject *args) {
1262 + Repo *repo = self->_repo;
1263 + SolvableObject *solv;
1265 + if (!PyArg_ParseTuple(args, "O", &solv)) {
1269 + Solvable *s = pool_id2solvable(repo->pool, solv->_id);
1270 + repo_free_solvable(repo, s - repo->pool->solvables, 1);
1274 diff --git a/python/src/repo.h b/python/src/repo.h
1275 index 9de636f..3ef96df 100644
1276 --- a/python/src/repo.h
1277 +++ b/python/src/repo.h
1278 @@ -44,6 +44,7 @@ extern PyObject *Repo_read(RepoObject *self, PyObject *args);
1279 extern PyObject *Repo_internalize(RepoObject *self);
1280 extern PyObject *Repo_clear(RepoObject *self);
1281 extern PyObject *Repo_get_all(RepoObject *self);
1282 +extern PyObject *Repo_rem_solv(RepoObject *self, PyObject *args);
1284 extern PyTypeObject RepoType;
1286 diff --git a/python/src/request.c b/python/src/request.c
1287 index 168b455..7d7c5b2 100644
1288 --- a/python/src/request.c
1289 +++ b/python/src/request.c
1290 @@ -64,29 +64,25 @@ PyObject *Request_dealloc(RequestObject *self) {
1293 void _Request_solvable(RequestObject *self, Id what, Id solvable) {
1294 - queue_push(&self->_queue, what|SOLVER_SOLVABLE);
1295 - queue_push(&self->_queue, solvable);
1296 + queue_push2(&self->_queue, what|SOLVER_SOLVABLE, solvable);
1299 void _Request_relation(RequestObject *self, Id what, Id relation) {
1300 - queue_push(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES);
1301 - queue_push(&self->_queue, relation);
1302 + queue_push2(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES, relation);
1305 void _Request_name(RequestObject *self, Id what, Id provides) {
1306 - queue_push(&self->_queue, what|SOLVER_SOLVABLE_NAME);
1307 - queue_push(&self->_queue, provides);
1308 + queue_push2(&self->_queue, what|SOLVER_SOLVABLE_NAME, provides);
1311 PyObject *Request_install_solvable(RequestObject *self, PyObject *args) {
1312 SolvableObject *solv;
1314 if (!PyArg_ParseTuple(args, "O", &solv)) {
1315 - /* XXX raise exception */
1319 _Request_solvable(self, SOLVER_INSTALL, solv->_id);
1324 @@ -94,11 +90,10 @@ PyObject *Request_install_relation(RequestObject *self, PyObject *args) {
1325 RelationObject *rel;
1327 if (!PyArg_ParseTuple(args, "O", &rel)) {
1328 - /* XXX raise exception */
1332 _Request_relation(self, SOLVER_INSTALL, rel->_id);
1337 @@ -106,7 +101,7 @@ PyObject *Request_install_name(RequestObject *self, PyObject *args) {
1340 if (!PyArg_ParseTuple(args, "s", &name)) {
1341 - /* XXX raise exception */
1345 Id _name = pool_str2id(self->_pool, name, 1);
1346 @@ -119,11 +114,10 @@ PyObject *Request_remove_solvable(RequestObject *self, PyObject *args) {
1347 SolvableObject *solv;
1349 if (!PyArg_ParseTuple(args, "O", &solv)) {
1350 - /* XXX raise exception */
1354 _Request_solvable(self, SOLVER_ERASE, solv->_id);
1359 @@ -131,11 +125,10 @@ PyObject *Request_remove_relation(RequestObject *self, PyObject *args) {
1360 RelationObject *rel;
1362 if (!PyArg_ParseTuple(args, "O", &rel)) {
1363 - /* XXX raise exception */
1367 _Request_relation(self, SOLVER_ERASE, rel->_id);
1372 @@ -143,7 +136,7 @@ PyObject *Request_remove_name(RequestObject *self, PyObject *args) {
1375 if (!PyArg_ParseTuple(args, "s", &name)) {
1376 - /* XXX raise exception */
1380 Id _name = pool_str2id(self->_pool, name, 1);
1381 @@ -156,11 +149,10 @@ PyObject *Request_update_solvable(RequestObject *self, PyObject *args) {
1382 SolvableObject *solv;
1384 if (!PyArg_ParseTuple(args, "O", &solv)) {
1385 - /* XXX raise exception */
1389 _Request_solvable(self, SOLVER_UPDATE, solv->_id);
1394 @@ -168,11 +160,10 @@ PyObject *Request_update_relation(RequestObject *self, PyObject *args) {
1395 RelationObject *rel;
1397 if (!PyArg_ParseTuple(args, "O", &rel)) {
1398 - /* XXX raise exception */
1402 _Request_relation(self, SOLVER_UPDATE, rel->_id);
1407 @@ -180,7 +171,7 @@ PyObject *Request_update_name(RequestObject *self, PyObject *args) {
1410 if (!PyArg_ParseTuple(args, "s", &name)) {
1411 - /* XXX raise exception */
1415 Id _name = pool_str2id(self->_pool, name, 1);
1416 @@ -193,11 +184,10 @@ PyObject *Request_lock_solvable(RequestObject *self, PyObject *args) {
1417 SolvableObject *solv;
1419 if (!PyArg_ParseTuple(args, "O", &solv)) {
1420 - /* XXX raise exception */
1424 _Request_solvable(self, SOLVER_LOCK, solv->_id);
1429 @@ -205,11 +195,10 @@ PyObject *Request_lock_relation(RequestObject *self, PyObject *args) {
1430 RelationObject *rel;
1432 if (!PyArg_ParseTuple(args, "O", &rel)) {
1433 - /* XXX raise exception */
1437 _Request_relation(self, SOLVER_LOCK, rel->_id);
1442 @@ -217,7 +206,7 @@ PyObject *Request_lock_name(RequestObject *self, PyObject *args) {
1445 if (!PyArg_ParseTuple(args, "s", &name)) {
1446 - /* XXX raise exception */
1450 Id _name = pool_str2id(self->_pool, name, 1);
1451 @@ -230,11 +219,10 @@ PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *args) {
1452 SolvableObject *solv;
1454 if (!PyArg_ParseTuple(args, "O", &solv)) {
1455 - /* XXX raise exception */
1459 _Request_solvable(self, SOLVER_NOOBSOLETES, solv->_id);
1464 @@ -242,11 +230,10 @@ PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args) {
1465 RelationObject *rel;
1467 if (!PyArg_ParseTuple(args, "O", &rel)) {
1468 - /* XXX raise exception */
1472 _Request_relation(self, SOLVER_NOOBSOLETES, rel->_id);
1477 @@ -254,7 +241,7 @@ PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) {
1480 if (!PyArg_ParseTuple(args, "s", &name)) {
1481 - /* XXX raise exception */
1485 Id _name = pool_str2id(self->_pool, name, 1);
1486 @@ -262,3 +249,18 @@ PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) {
1491 +PyObject *Request_updateall(RequestObject *self, PyObject *args) {
1492 + queue_push2(&self->_queue, SOLVER_UPDATE|SOLVER_SOLVABLE_ALL, 0);
1496 +PyObject *Request_distupgrade(RequestObject *self, PyObject *args) {
1497 + queue_push2(&self->_queue, SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL, 0);
1501 +PyObject *Request_verify(RequestObject *self, PyObject *args) {
1502 + queue_push2(&self->_queue, SOLVER_VERIFY|SOLVER_SOLVABLE_ALL, 0);
1505 diff --git a/python/src/request.h b/python/src/request.h
1506 index b936801..aa79274 100644
1507 --- a/python/src/request.h
1508 +++ b/python/src/request.h
1509 @@ -59,6 +59,10 @@ extern PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *arg
1510 extern PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args);
1511 extern PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args);
1513 +extern PyObject *Request_updateall(RequestObject *self, PyObject *args);
1514 +extern PyObject *Request_distupgrade(RequestObject *self, PyObject *args);
1515 +extern PyObject *Request_verify(RequestObject *self, PyObject *args);
1517 extern PyTypeObject RequestType;
1520 diff --git a/python/src/solution.c b/python/src/solution.c
1521 index b52a1b5..7360a37 100644
1522 --- a/python/src/solution.c
1523 +++ b/python/src/solution.c
1524 @@ -82,7 +82,7 @@ PyObject *Solution_string(SolutionObject *self) {
1526 switch (how & SOLVER_JOBMASK) {
1527 case SOLVER_INSTALL:
1528 - if (select == SOLVER_SOLVABLE && solver->installed && pool->solvables[what].repo == solver->installed)
1529 + if (select == SOLVER_SOLVABLE && pool->installed && pool->solvables[what].repo == pool->installed)
1530 snprintf(str, STRING_SIZE - 1, _("do not keep %s installed"),
1531 pool_solvid2str(pool, what));
1532 else if (select == SOLVER_SOLVABLE_PROVIDES)
1533 @@ -94,7 +94,7 @@ PyObject *Solution_string(SolutionObject *self) {
1537 - if (select == SOLVER_SOLVABLE && !(solver->installed && pool->solvables[what].repo == solver->installed))
1538 + if (select == SOLVER_SOLVABLE && !(pool->installed && pool->solvables[what].repo == pool->installed))
1539 snprintf(str, STRING_SIZE - 1, _("do not forbid installation of %s"),
1540 pool_solvid2str(pool, what));
1541 else if (select == SOLVER_SOLVABLE_PROVIDES)
1542 @@ -122,7 +122,7 @@ PyObject *Solution_string(SolutionObject *self) {
1544 } else if (p == SOLVER_SOLUTION_INFARCH) {
1545 s = pool->solvables + rp;
1546 - if (solver->installed && s->repo == solver->installed)
1547 + if (pool->installed && s->repo == pool->installed)
1548 snprintf(str, STRING_SIZE - 1, _("keep %s despite the inferior architecture"),
1549 pool_solvable2str(pool, s));
1551 @@ -131,7 +131,7 @@ PyObject *Solution_string(SolutionObject *self) {
1553 } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1554 s = pool->solvables + rp;
1555 - if (solver->installed && s->repo == solver->installed)
1556 + if (pool->installed && s->repo == pool->installed)
1557 snprintf(str, STRING_SIZE - 1, _("keep obsolete %s"),
1558 pool_solvable2str(pool, s));
1560 diff --git a/python/src/solver.c b/python/src/solver.c
1561 index 5079510..54e1294 100644
1562 --- a/python/src/solver.c
1563 +++ b/python/src/solver.c
1564 @@ -53,6 +53,9 @@ PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1568 + /* enable splitprovides by default */
1569 + solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, 1);
1571 return (PyObject *)self;
1574 @@ -63,138 +66,150 @@ PyObject *Solver_dealloc(SolverObject *self) {
1578 -PyObject *Solver_get_fix_system(SolverObject *self, PyObject *args) {
1579 - return Py_BuildValue("i", self->_solver->fixsystem);
1580 +PyObject *Solver_get_flag(SolverObject *self, PyObject *args) {
1583 + if (!PyArg_ParseTuple(args, "i", &flag)) {
1587 + int val = solver_get_flag(self->_solver, flag);
1588 + return Py_BuildValue("i", val);
1591 -PyObject *Solver_set_fix_system(SolverObject *self, PyObject *args) {
1593 +PyObject *Solver_set_flag(SolverObject *self, PyObject *args) {
1594 + int flag = 0, val = 0;
1596 - if (!PyArg_ParseTuple(args, "i", &val)) {
1597 - /* XXX raise exception */
1598 + if (!PyArg_ParseTuple(args, "ii", &flag, &val)) {
1602 - self->_solver->fixsystem = val;
1604 + solver_set_flag(self->_solver, flag, val);
1608 PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args) {
1609 - return Py_BuildValue("i", self->_solver->allowdowngrade);
1610 + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE);
1612 + return Py_BuildValue("i", val);
1615 PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args) {
1618 if (!PyArg_ParseTuple(args, "i", &val)) {
1619 - /* XXX raise exception */
1623 - self->_solver->allowdowngrade = val;
1625 + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE, val);
1629 PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args) {
1630 - return Py_BuildValue("i", self->_solver->allowarchchange);
1631 + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE);
1633 + return Py_BuildValue("i", val);
1636 PyObject *Solver_set_allow_archchange(SolverObject *self, PyObject *args) {
1639 if (!PyArg_ParseTuple(args, "i", &val)) {
1640 - /* XXX raise exception */
1644 - self->_solver->allowarchchange = val;
1646 + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE, val);
1650 PyObject *Solver_get_allow_vendorchange(SolverObject *self, PyObject *args) {
1651 - return Py_BuildValue("i", self->_solver->allowvendorchange);
1652 + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE);
1654 + return Py_BuildValue("i", val);
1657 PyObject *Solver_set_allow_vendorchange(SolverObject *self, PyObject *args) {
1660 if (!PyArg_ParseTuple(args, "i", &val)) {
1661 - /* XXX raise exception */
1665 - self->_solver->allowvendorchange = val;
1667 + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE, val);
1671 PyObject *Solver_get_allow_uninstall(SolverObject *self, PyObject *args) {
1672 - return Py_BuildValue("i", self->_solver->allowuninstall);
1673 + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL);
1675 + return Py_BuildValue("i", val);
1678 PyObject *Solver_set_allow_uninstall(SolverObject *self, PyObject *args) {
1681 if (!PyArg_ParseTuple(args, "i", &val)) {
1682 - /* XXX raise exception */
1686 - self->_solver->allowuninstall = val;
1688 + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL, val);
1692 PyObject *Solver_get_updatesystem(SolverObject *self, PyObject *args) {
1693 - return Py_BuildValue("i", self->_solver->updatesystem);
1694 + //return Py_BuildValue("i", self->_solver->updatesystem);
1698 PyObject *Solver_set_updatesystem(SolverObject *self, PyObject *args) {
1702 if (!PyArg_ParseTuple(args, "i", &val)) {
1703 - /* XXX raise exception */
1707 - self->_solver->updatesystem = val;
1708 + self->_solver->updatesystem = val; */
1713 PyObject *Solver_get_do_split_provides(SolverObject *self, PyObject *args) {
1714 - return Py_BuildValue("i", self->_solver->dosplitprovides);
1715 + int val = solver_get_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES);
1717 + return Py_BuildValue("i", val);
1720 PyObject *Solver_set_do_split_provides(SolverObject *self, PyObject *args) {
1723 if (!PyArg_ParseTuple(args, "i", &val)) {
1724 - /* XXX raise exception */
1728 - self->_solver->dosplitprovides = val;
1730 + solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, val);
1734 PyObject *Solver_solve(SolverObject *self, PyObject *args) {
1735 RequestObject *request;
1738 if (!PyArg_ParseTuple(args, "O", &request)) {
1739 - /* XXX raise exception */
1743 // Make sure, the pool is prepared.
1744 _Pool_prepare(self->_solver->pool);
1746 - solver_solve(self->_solver, &request->_queue);
1747 + res = solver_solve(self->_solver, &request->_queue);
1750 solver_printallsolutions(self->_solver);
1753 - if (self->_solver->problems.count == 0) {
1761 @@ -202,7 +217,6 @@ PyObject *Solver_get_problems(SolverObject *self, PyObject *args) {
1762 RequestObject *request;
1764 if (!PyArg_ParseTuple(args, "O", &request)) {
1765 - /* XXX raise exception */
1769 diff --git a/python/src/solver.h b/python/src/solver.h
1770 index 604cb83..8a4478b 100644
1771 --- a/python/src/solver.h
1772 +++ b/python/src/solver.h
1773 @@ -34,8 +34,9 @@ typedef struct {
1774 extern PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1775 extern PyObject *Solver_dealloc(SolverObject *self);
1777 -extern PyObject *Solver_get_fix_system(SolverObject *self, PyObject *args);
1778 -extern PyObject *Solver_set_fix_system(SolverObject *self, PyObject *args);
1779 +extern PyObject *Solver_get_flag(SolverObject *self, PyObject *args);
1780 +extern PyObject *Solver_set_flag(SolverObject *self, PyObject *args);
1782 extern PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args);
1783 extern PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args);
1784 extern PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args);