In the current 0.3x series aptdaemon can simulate a transaction and caculate the required dependencies. Furthermore it creates a new dpkg status file with the queued changes. This allows to calculate dependencies for a new transaction at the state when the last queued transaction would habe been applied.
What should happen to a (queued) transaction if a previous transaction which would have e.g. installed required dependencies failed? Should we still process the transaction without any user interaction?
Should we treat a failed download or dpkg differently?
What about a broken cache?
Currently I favor to let all afterwards queued transaction fail. Especially since after a failed dpkg call you would have to call "dpkg --configure -a" or run a ?FixIncompleteInstall transaction.
There is also a ?FixBrokenDepends transaction in aptdaemon.
We could also recalculate all queued transactions and check if it requires any changes that are part of the failed one. But it could be a quite slow operation if a lot of transactions are queued. If we choose this approach: Should we fail only if the initial action could not be done successfully anymore (installing specific packages) or even if a confirmed dependcy would no longer be needed or another depending package won't have to be removed.
It is basically the same pattern as above: Can we figure out if a cancellation would affect other transactions?
Dependency confirmation dialog
Since the dependencies are now handled by aptdaemon it makes sense to provide an unified dependency confirmation dialog in the gtkwidgets.
The dialog should inform the user about additional changes that are needed to perform the initial task and give him/her a chance to cancel the action/transaction.
The following types of dependencies are available: install, reinstalls (only theorectically), removals (purges), upgrades, downgrades and kept backs (or better called skipped upgrades in the case of system upgrades).
Finally it should show the required download size and to be used to freed disk space.
On the code side the dialog should allow an easy mapping of package names or injection to allow e.g. software-center to show applications instead of packages.
You have to create a local branch of aptdaemon: bzr branch lp:aptdaemon Then download the
1 #!/usr/bin/python 2 3 import apt 4 from aptdaemon import gtkwidgets 5 6 class MockTrans(object): 7 def __init__(self, dep): 8 self.dependencies = dep 9 self.download = 1024 * 12 10 self.space = 1024 * 35 * 1024 11 12 def main(): 13 cache = apt.Cache() 14 for dep in ([["xterm"], , , , , , ], 15 [["xterm", "synaptic"], , , , , , ], 16 [["xterm", "synaptic"], , ["cw"], , , , ]): 17 trans = MockTrans(dep) 18 dia = gtkwidgets.AptConfirmDialog(trans, cache=cache) 19 dia.run() 20 dia.hide() 21 22 if __name__ == "__main__": 23 main()
The test shows three dialogs:
- requires the installation of one additional package
- requires the installation of two additional packages
- requires installation and removal of other packages
Current approaches of other package managers
Other package manager solved this issue by showing a tree view, tabs, a flat list or even ignoring additional required changes.
Provides a classic tree view with a subtree for every operation type (installs, removals, ...)
Can show complex operations (e.g. removal and installation at the same time) by using pseudo tabs.
PackageKit can present the removal of conflicting packages, but the GNOME dialog text assumes that an installation only installs furhter packages and that a removal only removes further packages.
Currently only shows a confirmation dialog for remove actions. The dependencies of installations are not confirmed. This seems to be a design bug since an installation could also require the removal of an already installed, but conflicting package.
The following packages will be upgraded (10): empathy empathy-common libgupnp-1.0-3 libstreamanalyzer0 libstreams0 libstrigiqtdbusclient0 nautilus-sendto-empathy python-paste tzdata tzdata-java The following package has been kept back (1): python-twisted-conch Need to get 5984kB of archives. After this operation, 98.3kB of additional disk space will be freed. Do you want to continue [Y/n]?