[zypp-devel] How to get a packages' depends and requires from libzypp
I'm trying to implement: 1) GetDepends (http://www.packagekit.org/pk-reference.html#api-get-depends) - GetDepends should return packages that this package depends on. 2) GetRequires (http://www.packagekit.org/pk-reference.html#api-get-requires) - GetRequires should return packages that depend on this package. This is useful to know, as if package_id is being removed, we can warn the user what else would be removed. I can't figure out what to call. I've got a zypp::Resolvable::constPtr and I notice there's a ->deps(). I've cycled through that, but end up getting a long list of both packages and libraries. Does anyone have some sample C++ code that I could look at to see how I might implement these methods? Thanks, Boyd -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Wednesday 05 December 2007 00:11:06 you wrote:
I'm trying to implement:
1) GetDepends (http://www.packagekit.org/pk-reference.html#api-get-depends) - GetDepends should return packages that this package depends on. 2) GetRequires (http://www.packagekit.org/pk-reference.html#api-get-requires) - GetRequires should return packages that depend on this package. This is useful to know, as if package_id is being removed, we can warn the user what else would be removed.
From the documentation I can't figure what this method return. (it seems to return a list of package, but that would be broken as dependencies are indirect and require a solver tun) Can you explan more? Duncan -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Boyd Timothy wrote:
I'm trying to implement:
1) GetDepends (http://www.packagekit.org/pk-reference.html#api-get-depends) - GetDepends should return packages that this package depends on. 2) GetRequires (http://www.packagekit.org/pk-reference.html#api-get-requires) - GetRequires should return packages that depend on this package.
I am interested in this, too, since i need to get that functionality into zypper. Using this code: CapSet capSet = pool_item.resolvable()->dep(zypp::Dep::PROVIDES); for (CapSet::const_iterator it = capSet.begin(); it != capSet.end(); ++it) { cout << it->refers().asString() << ": " << it->asString() << " --> " << it->kind() << endl; } cout << endl << _("Requires:") << endl; capSet = pool_item.resolvable()->dep(zypp::Dep::REQUIRES); for (CapSet::const_iterator it = capSet.begin(); it != capSet.end(); ++it) { cout << it->refers().asString() << ": " << it->asString() << " --> " << it->kind() << endl; } yields the following result (for zypper package): Provides: package: y2pmsh --> namedcap package: zypper == 0.9.2-4 --> namedcap package: /etc/logrotate.d/zypper.lr --> filecap package: /usr/bin/installation_sources --> filecap package: /usr/bin/zypper --> filecap package: /usr/sbin/zypp-checkpatches --> filecap package: /usr/sbin/zypp-checkpatches-wrapper --> filecap Requires: package: procps --> namedcap package: permissions --> namedcap package: libc.so.6(GLIBC_2.2.5)(64bit) --> namedcap package: libpthread.so.0()(64bit) --> namedcap package: libstdc++.so.6()(64bit) --> namedcap package: libm.so.6()(64bit) --> namedcap package: libc.so.6()(64bit) --> namedcap package: libpthread.so.0(GLIBC_2.2.5)(64bit) --> namedcap package: libstdc++.so.6(CXXABI_1.3)(64bit) --> namedcap package: libc.so.6(GLIBC_2.4)(64bit) --> namedcap package: libstdc++.so.6(GLIBCXX_3.4)(64bit) --> namedcap package: libgcc_s.so.1()(64bit) --> namedcap package: libgcc_s.so.1(GCC_3.0)(64bit) --> namedcap package: libstdc++.so.6(GLIBCXX_3.4.9)(64bit) --> namedcap package: libreadline.so.5()(64bit) --> namedcap package: libboost_regex.so.1.33.1()(64bit) --> namedcap package: libzypp.so.401()(64bit) --> namedcap package: /bin/sh --> filecap For example, i wonder about the dependency of zypper on libzypp _package_ (specified through BuildRequires in the spec file) which is represented by package: libzypp.so.401()(64bit) --> namedcap in the list above. How do i get 'libzypp > 3.23.1' out of it? Is it possible at all? It is not even in the generated (yum factory) metadata: <rpm:entry name="libzypp.so.401"/> I can imagine searching byName "libzypp" byKind package and checking which one of them provides libzypp.so.401. But i won't figure out libzypp > 3.23.1 out of it. Jano -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Yes, and if you want to see which packages in the pool match a capability, you can use CapMatchHelper See example in Locks, which creates a capability (dependency) from a user string, then patch packages, and lock them. http://svn.opensuse.org/svn/zypp/trunk/libzypp/zypp/Locks.cc The API is here: http://svn.opensuse.org/svn/zypp/trunk/libzypp/zypp/CapMatchHelper.h Duncan -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Wed, Dec 05, Duncan Mac-Vicar Prett wrote:
The API is here: http://svn.opensuse.org/svn/zypp/trunk/libzypp/zypp/CapMatchHelper.h
In short: struct Action { bool operator()( const PoolItem & poolitem_r ) const { // ... return true; } }; ResPool my_pool; Poolitem my_item; Action my_action; // For all items in my_pool which match a my_item OBSOLETES // invoke my_action. // // - i.e. for all items obsoleted by my_item. // forEachPoolItemMatchedBy( my_pool, my_item, Dep::OBSOLETES, OncePerPoolItem( my_action ) ); // For all items in my_pool whose OBSOLETES match my_item // invoke my_action. // // - i.e. for all items obsoleting my_item. // forEachPoolItemMatching( my_pool, dep::OBSOLETES, my_item, OncePerPoolItem( my_action ) ); The actual functor signature is 'function<bool(const CapAndItem &)> '. CapAndItem is a 'Capability/PoolItem' pair containing the Capability that matched and the PoolItem the Capability belongs to. It's not unusual that multiple CapAndItems refer to the same PoolItem. In many cases you want to avoid multiple invocations for the same PoolItem. You may use OncePerPoolItem to perform an action ony once for each PoolItem. -- cu, Michael Andres +------------------------------------------------------------------+ Key fingerprint = 2DFA 5D73 18B1 E7EF A862 27AC 3FB8 9E3A 27C6 B0E4 +------------------------------------------------------------------+ Michael Andres YaST Development ma@novell.com SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg) Maxfeldstrasse 5, D-90409 Nuernberg, Germany, ++49 (0)911 - 740 53-0 +------------------------------------------------------------------+ -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Wednesday 05 December 2007 19:40:50 Michael Andres wrote:
On Wed, Dec 05, Duncan Mac-Vicar Prett wrote:
The API is here: http://svn.opensuse.org/svn/zypp/trunk/libzypp/zypp/CapMatchHelper.h
In short:
What we figured yesterday on irc, is that PackageKit GetDepends and GetRequires methods intend to return the list of packages that package depends on, which is really wrong: - Packages depend on capabilities other packages can provide - You can not know which one will be the candidate selected for providing that (can be one, can be none) until you have a solver run. The only things you can emulate using this workaround: - Look a package requires and use CapMatchHelper to see wich packages in the pool are matched by that capability, this means if foo requires libc.so.6 and bar1 and bar2 provides that, you will get both packages back. - Do a solver run for the case of installing a single package and see which packages the solver mark for installation (isToBeInstalled() isBySolver()) but this also would mark a broken requires for another package for installation, like you have mplayer installed which depends on libsdl, but libsdl was uninstalled by rpm -force, the solver will mark for installation even if it is not a requires of foo, anyway I am not 100% sure if this is the behavior libzypp does right now (moving the system automatically to a consistant state). At the beginning I thought libzypp was making everything more complex, but I think PackageKit is also asking the wrong question. I tried looking yum backend source code but they don't have it implemented. Duncan -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Dňa Thursday 06 December 2007 10:56:01 Duncan Mac-Vicar Prett ste napísal:
On Wednesday 05 December 2007 19:40:50 Michael Andres wrote:
On Wed, Dec 05, Duncan Mac-Vicar Prett wrote:
The API is here: http://svn.opensuse.org/svn/zypp/trunk/libzypp/zypp/CapMatchHelper.h
In short:
What we figured yesterday on irc, is that PackageKit GetDepends and GetRequires methods intend to return the list of packages that package depends on, which is really wrong:
- Packages depend on capabilities other packages can provide - You can not know which one will be the candidate selected for providing that (can be one, can be none) until you have a solver run.
The only things you can emulate using this workaround:
- Look a package requires and use CapMatchHelper to see wich packages in the pool are matched by that capability, this means if foo requires libc.so.6 and bar1 and bar2 provides that, you will get both packages back.
- Do a solver run for the case of installing a single package and see which packages the solver mark for installation (isToBeInstalled() isBySolver()) but this also would mark a broken requires for another package for installation, like you have mplayer installed which depends on libsdl, but libsdl was uninstalled by rpm -force, the solver will mark for installation even if it is not a requires of foo, anyway I am not 100% sure if this is the behavior libzypp does right now (moving the system automatically to a consistant state).
At the beginning I thought libzypp was making everything more complex, but I think PackageKit is also asking the wrong question.
Yes, it sounds like they are oversimplifying dependency resolution. Stano -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On 06/12/2007, Stanislav Visnovsky <visnov@suse.cz> wrote:
At the beginning I thought libzypp was making everything more complex, but I think PackageKit is also asking the wrong question.
Yes, it sounds like they are oversimplifying dependency resolution.
Hmm, sent this earlier, seems to have vanished into the aether, sorry if it arrives twice. Bear in mind that the whole point of packagekit is that it has to be possible to implement it with fairly disparate package management systems. As I understand it RPM packages both provide and require things (ignoring other types of dependency), and provides are used to resolve requires. However, as I understand it debian packages only have requirements which must be packages. If more than one package can provide something they have to require a metapackage, which is still a valid package. So listing the packages a package requires makes more sense on debian systems. If the packagekit API were too close to the RPM way of doing things it could become difficult or impossible to implement on other package management systems. There are plenty of things possible on other package management systems such as conary which would not be possible with zypp, so it's good that they don't have to be implemented. Packagekit implementation is always doomed to be a lowest common denominator of what can be achieved with all package management systems. Nevertheless it is still worthwhile doing, because even this subset of package management functionality is still very useful to be able to use from desktop applications in a distribution agnostic way. -- Benjamin Weber -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Thu, Dec 06, 2007 at 06:16:11PM +0000, Benji Weber wrote:
On 06/12/2007, Stanislav Visnovsky <visnov@suse.cz> wrote:
At the beginning I thought libzypp was making everything more complex, but I think PackageKit is also asking the wrong question.
Yes, it sounds like they are oversimplifying dependency resolution.
Hmm, sent this earlier, seems to have vanished into the aether, sorry if it arrives twice.
Bear in mind that the whole point of packagekit is that it has to be possible to implement it with fairly disparate package management systems.
As I understand it RPM packages both provide and require things (ignoring other types of dependency), and provides are used to resolve requires. However, as I understand it debian packages only have requirements which must be packages.
Not true, debian has virtaul requires like rpm. The even have a dependency "OR", which makes things even more complicated... Cheers, Michael. -- Michael Schroeder mls@suse.de SUSE LINUX Products GmbH, GF Markus Rex, HRB 16746 AG Nuernberg main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);} -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On 06/12/2007, Michael Schroeder <mls@suse.de> wrote:
Not true, debian has virtaul requires like rpm. The even have a dependency "OR", which makes things even more complicated...
Interesting, I didn't realise about the OR. Can the virtual packages be freeform to be a filename or pci-id etc? -- Benjamin Weber -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Am Donnerstag 06 Dezember 2007 schrieb Benji Weber:
On 06/12/2007, Michael Schroeder <mls@suse.de> wrote:
Not true, debian has virtaul requires like rpm. The even have a dependency "OR", which makes things even more complicated...
Interesting, I didn't realise about the OR. Can the virtual packages be freeform to be a filename or pci-id etc?
No, they do not support that. Only based on packages or virtual packages. Greetings, Stephan -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Thu, Dec 06, 2007 at 06:51:57PM +0000, Benji Weber wrote:
On 06/12/2007, Michael Schroeder <mls@suse.de> wrote:
Not true, debian has virtaul requires like rpm. The even have a dependency "OR", which makes things even more complicated...
Interesting, I didn't realise about the OR. Can the virtual packages be freeform to be a filename or pci-id etc?
Debian doesn't support 'auto-provide' of filenames. And I don't think that the '/' character is allowed in a dependency. Furthermore, the list of allowed virtual packages is pretty limited. If you want to add some new virtual package, you must first ask for permission to do so. Here's a list of virtual packages: http://www.debian.org/doc/packaging-manuals/virtual-package-names-list.txt You don't need so many virtual packages in debian because of the package OR. (This makes it harder for 3rd party packagers to provide alternatives, though.) Cheers, Michael. -- Michael Schroeder mls@suse.de SUSE LINUX Products GmbH, GF Markus Rex, HRB 16746 AG Nuernberg main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);} -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Am Donnerstag 06 Dezember 2007 schrieb Benji Weber:
As I understand it RPM packages both provide and require things (ignoring other types of dependency), and provides are used to resolve requires. However, as I understand it debian packages only have requirements which must be packages. If more than one package can provide something they have to require a metapackage, which is still a valid package. So listing the packages a package requires makes more sense on debian systems.
No, this is not true. Debian packages can require "bash | tcsh | zsh", which rpms can't. Greetings, Stephan -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Duncan Mac-Vicar Prett schrieb:
- Do a solver run for the case of installing a single package and see which packages the solver mark for installation (isToBeInstalled() isBySolver()) but this also would mark a broken requires for another package for installation, like you have mplayer installed which depends on libsdl, but libsdl was uninstalled by rpm -force, the solver will mark for installation even if it is not a requires of foo, anyway I am not 100% sure if this is the behavior libzypp does right now (moving the system automatically to a consistant state).
Ähm, the solver does regard dependencies of to be installed packages only. So, if libsdl is not required by foo the solver will not blame the requirements of libsdl from mplayer. Anyway, you need a solver run here. In this case you can use following API of the solver: /** * Gives information about WHO has pused an installation of an given item. * * \param item Evaluate additional information for this resolvable. * \return A list of structures which contains: * item Item which has triggered the installation of the given param item. * cap Capability which has triggerd this installation * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) * * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. * */ const solver::detail::ItemCapKindList isInstalledBy (const PoolItem_Ref item); /** * Gives information about WHICH additional items will be installed due the installation of an item. * * \param item Evaluate additional information for this resolvable. * \return A list of structures which contains: * item Item which will be installed due to the installation of the given param item too. * cap Capability which causes the installation * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) * * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. * */ const solver::detail::ItemCapKindList installs (const PoolItem_Ref item); I am not sure if we can provide this information in the future by the new SAT-solver. But we will try it. :-) The other way (without solving) has been already described by Michl Andres on this mailing-list. Greetings Stefan -- ******************************************************************************* Stefan Schubert SUSE LINUX GmbH - Maxfeldstrasse 5 - D-90409 Nuernberg, Germany e-mail: schubi@suse.de ------------------------------------------------------------------------------- SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg) -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Dec 6, 2007 3:54 AM, Stefan Schubert <schubi@suse.de> wrote:
Duncan Mac-Vicar Prett schrieb: const solver::detail::ItemCapKindList isInstalledBy (const PoolItem_Ref item);
const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
Been trying to figure out how to call this. Right now in my code, I iterate through the pool looking for the main package, mark it to be installed, run the solver, and now I'm to the point where I'd call installs(). Where do I get a PoolItem_Ref? Sample code here: http://pastebin.com/f78dc52da Line 98 is where I'm stumped. installs() takes a PoolItem_Ref, but where do I get one of those? Line #65 doesn't compile either, for what it's worth. -Boyd -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
Boyd Timothy schrieb:
On Dec 6, 2007 3:54 AM, Stefan Schubert <schubi@suse.de> wrote:
Duncan Mac-Vicar Prett schrieb: const solver::detail::ItemCapKindList isInstalledBy (const PoolItem_Ref item);
const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
Been trying to figure out how to call this. Right now in my code, I iterate through the pool looking for the main package, mark it to be installed, run the solver, and now I'm to the point where I'd call installs(). Where do I get a PoolItem_Ref?
Sample code here: http://pastebin.com/f78dc52da
Line 98 is where I'm stumped. installs() takes a PoolItem_Ref, but where do I get one of those? Line #65 doesn't compile either, for what it's worth.
-Boyd
It is defined in the return value: /** * Gives information about WHICH additional items will be installed due the installation of an item. * * \param item Evaluate additional information for this resolvable. * \return A list of structures which contains: * item Item which will be installed due to the installation of the given param item too. * cap Capability which causes the installation * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) * * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. * */ const solver::detail::ItemCapKindList installs (const PoolItem_Ref item); The class ItemCapKindList is defined solver/details/Resolver.h: /////////////////////////////////////////////////////////////////// // // CLASS NAME : ItemCapKind // /** */ struct ItemCapKind { public: Capability cap; //Capability which has triggerd this selection Dep capKind; //Kind of that capability PoolItem_Ref item; //Item which has triggered this selection bool initialInstallation; //This item has triggered the installation //Not already fullfilled requierement only. ItemCapKind() : capKind("FRESHENS") {} ItemCapKind( PoolItem i, Capability c, Dep k, bool initial) : cap( c ) , capKind( k ) , item( i ) , initialInstallation( initial ) { } }; typedef std::multimap<PoolItem_Ref,ItemCapKind> ItemCapKindMap; typedef std::list<ItemCapKind> ItemCapKindList; Here is a little example: zypp::solver::detail::ItemCapKindList installList = resolver->installs (item); zypp::solver::detail::ItemCapKindList installedList = resolver->isInstalledBy (item); installListView->clear(); installedListView->clear(); for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installedList.begin(); iter != installedList.end(); ++iter) { QListViewItem *element = new QListViewItem( installedListView, iter->item->name(), iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString()); } for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installList.begin(); iter != installList.end(); ++iter) { QListViewItem *element = new QListViewItem( installListView, iter->item->name(), iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString()); } Greetings Stefan -- ******************************************************************************* Stefan Schubert SUSE LINUX GmbH - Maxfeldstrasse 5 - D-90409 Nuernberg, Germany e-mail: schubi@suse.de ------------------------------------------------------------------------------- SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg) -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Dec 7, 2007 1:30 AM, Stefan Schubert <schubi@suse.de> wrote:
Boyd Timothy schrieb:
On Dec 6, 2007 3:54 AM, Stefan Schubert <schubi@suse.de> wrote:
Duncan Mac-Vicar Prett schrieb: const solver::detail::ItemCapKindList isInstalledBy (const PoolItem_Ref item);
const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
Been trying to figure out how to call this. Right now in my code, I iterate through the pool looking for the main package, mark it to be installed, run the solver, and now I'm to the point where I'd call installs(). Where do I get a PoolItem_Ref?
Sample code here: http://pastebin.com/f78dc52da
Line 98 is where I'm stumped. installs() takes a PoolItem_Ref, but where do I get one of those? Line #65 doesn't compile either, for what it's worth.
-Boyd
It is defined in the return value:
/** * Gives information about WHICH additional items will be installed due the installation of an item. * * \param item Evaluate additional information for this resolvable. * \return A list of structures which contains: * item Item which will be installed due to the installation of the given param item too. * cap Capability which causes the installation * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) * * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. * */ const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
The class ItemCapKindList is defined solver/details/Resolver.h:
/////////////////////////////////////////////////////////////////// // // CLASS NAME : ItemCapKind // /** */ struct ItemCapKind { public: Capability cap; //Capability which has triggerd this selection Dep capKind; //Kind of that capability PoolItem_Ref item; //Item which has triggered this selection bool initialInstallation; //This item has triggered the installation //Not already fullfilled requierement only.
ItemCapKind() : capKind("FRESHENS") {} ItemCapKind( PoolItem i, Capability c, Dep k, bool initial) : cap( c ) , capKind( k ) , item( i ) , initialInstallation( initial ) { } }; typedef std::multimap<PoolItem_Ref,ItemCapKind> ItemCapKindMap; typedef std::list<ItemCapKind> ItemCapKindList;
Here is a little example:
zypp::solver::detail::ItemCapKindList installList = resolver->installs (item); zypp::solver::detail::ItemCapKindList installedList = resolver->isInstalledBy (item); installListView->clear(); installedListView->clear();
for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installedList.begin(); iter != installedList.end(); ++iter) { QListViewItem *element = new QListViewItem( installedListView, iter->item->name(),
iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString()); } for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installList.begin(); iter != installList.end(); ++iter) { QListViewItem *element = new QListViewItem( installListView, iter->item->name(),
iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString());
}
Okay, well, once you have the PoolItem_Ref, the code makes sense, but I'm still unsure where I get the PoolItem_Ref originally. What call can I make to get that? -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Dec 7, 2007 8:48 AM, Boyd Timothy <btimothy@gmail.com> wrote:
On Dec 7, 2007 1:30 AM, Stefan Schubert <schubi@suse.de> wrote:
Boyd Timothy schrieb:
On Dec 6, 2007 3:54 AM, Stefan Schubert <schubi@suse.de> wrote:
Duncan Mac-Vicar Prett schrieb: const solver::detail::ItemCapKindList isInstalledBy (const PoolItem_Ref item);
const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
Been trying to figure out how to call this. Right now in my code, I iterate through the pool looking for the main package, mark it to be installed, run the solver, and now I'm to the point where I'd call installs(). Where do I get a PoolItem_Ref?
Sample code here: http://pastebin.com/f78dc52da
Line 98 is where I'm stumped. installs() takes a PoolItem_Ref, but where do I get one of those? Line #65 doesn't compile either, for what it's worth.
-Boyd
It is defined in the return value:
/** * Gives information about WHICH additional items will be installed due the installation of an item. * * \param item Evaluate additional information for this resolvable. * \return A list of structures which contains: * item Item which will be installed due to the installation of the given param item too. * cap Capability which causes the installation * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) * * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. * */ const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
The class ItemCapKindList is defined solver/details/Resolver.h:
/////////////////////////////////////////////////////////////////// // // CLASS NAME : ItemCapKind // /** */ struct ItemCapKind { public: Capability cap; //Capability which has triggerd this selection Dep capKind; //Kind of that capability PoolItem_Ref item; //Item which has triggered this selection bool initialInstallation; //This item has triggered the installation //Not already fullfilled requierement only.
ItemCapKind() : capKind("FRESHENS") {} ItemCapKind( PoolItem i, Capability c, Dep k, bool initial) : cap( c ) , capKind( k ) , item( i ) , initialInstallation( initial ) { } }; typedef std::multimap<PoolItem_Ref,ItemCapKind> ItemCapKindMap; typedef std::list<ItemCapKind> ItemCapKindList;
Here is a little example:
zypp::solver::detail::ItemCapKindList installList = resolver->installs (item); zypp::solver::detail::ItemCapKindList installedList = resolver->isInstalledBy (item); installListView->clear(); installedListView->clear();
for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installedList.begin(); iter != installedList.end(); ++iter) { QListViewItem *element = new QListViewItem( installedListView, iter->item->name(),
iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString()); } for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installList.begin(); iter != installList.end(); ++iter) { QListViewItem *element = new QListViewItem( installListView, iter->item->name(),
iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString());
}
Okay, well, once you have the PoolItem_Ref, the code makes sense, but I'm still unsure where I get the PoolItem_Ref originally. What call can I make to get that?
Ah, thanks to mvidner in #zypp, we learned that you can get it from Selectable::candidatePoolItem (). Cheers, Boyd -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Dec 7, 2007 9:55 AM, Boyd Timothy <btimothy@gmail.com> wrote:
On Dec 7, 2007 8:48 AM, Boyd Timothy <btimothy@gmail.com> wrote:
On Dec 7, 2007 1:30 AM, Stefan Schubert <schubi@suse.de> wrote:
Boyd Timothy schrieb:
On Dec 6, 2007 3:54 AM, Stefan Schubert <schubi@suse.de> wrote:
Duncan Mac-Vicar Prett schrieb: const solver::detail::ItemCapKindList isInstalledBy (const PoolItem_Ref item);
const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
Been trying to figure out how to call this. Right now in my code, I iterate through the pool looking for the main package, mark it to be installed, run the solver, and now I'm to the point where I'd call installs(). Where do I get a PoolItem_Ref?
Sample code here: http://pastebin.com/f78dc52da
Line 98 is where I'm stumped. installs() takes a PoolItem_Ref, but where do I get one of those? Line #65 doesn't compile either, for what it's worth.
-Boyd
It is defined in the return value:
/** * Gives information about WHICH additional items will be installed due the installation of an item. * * \param item Evaluate additional information for this resolvable. * \return A list of structures which contains: * item Item which will be installed due to the installation of the given param item too. * cap Capability which causes the installation * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) * * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. * */ const solver::detail::ItemCapKindList installs (const PoolItem_Ref item);
The class ItemCapKindList is defined solver/details/Resolver.h:
/////////////////////////////////////////////////////////////////// // // CLASS NAME : ItemCapKind // /** */ struct ItemCapKind { public: Capability cap; //Capability which has triggerd this selection Dep capKind; //Kind of that capability PoolItem_Ref item; //Item which has triggered this selection bool initialInstallation; //This item has triggered the installation //Not already fullfilled requierement only.
ItemCapKind() : capKind("FRESHENS") {} ItemCapKind( PoolItem i, Capability c, Dep k, bool initial) : cap( c ) , capKind( k ) , item( i ) , initialInstallation( initial ) { } }; typedef std::multimap<PoolItem_Ref,ItemCapKind> ItemCapKindMap; typedef std::list<ItemCapKind> ItemCapKindList;
Here is a little example:
zypp::solver::detail::ItemCapKindList installList = resolver->installs (item); zypp::solver::detail::ItemCapKindList installedList = resolver->isInstalledBy (item); installListView->clear(); installedListView->clear();
for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installedList.begin(); iter != installedList.end(); ++iter) { QListViewItem *element = new QListViewItem( installedListView, iter->item->name(),
iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString()); } for (zypp::solver::detail::ItemCapKindList::const_iterator iter = installList.begin(); iter != installList.end(); ++iter) { QListViewItem *element = new QListViewItem( installListView, iter->item->name(),
iter->item->edition().asString()+"."+iter->item->arch().asString(), iter->cap.asString(), iter->capKind.asString());
}
Okay, well, once you have the PoolItem_Ref, the code makes sense, but I'm still unsure where I get the PoolItem_Ref originally. What call can I make to get that?
Ah, thanks to mvidner in #zypp, we learned that you can get it from Selectable::candidatePoolItem ().
Please take a minute and review the following code: http://pastebin.ca/812178 Is this what you had in mind? Isn't there an easier way to get this information? I noticed that this only works for packages that are not installed. Is there a mechanism that would work for packages that are installed? Thanks, Boyd -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Tue, Dec 11, Boyd Timothy wrote:
Please take a minute and review the following code:
In general: const char *edition_str = installable->edition().asString().c_str(); if (strcmp (edition_str, pi->version) == 0) { c_str returns a pointer to a std::strings internal data. This pointer is not valid past the lifetime of the std::string. Edition::asString returns a temporary, so edition_str is no longer valid at the time you do the strcmp. These should be safe: std::string edition_str( installable->edition().asString() ); if (strcmp (edition_str.c_str(), pi->version) == 0) { or std::string edition_str( installable->edition().asString() ); if (edition_str == pi->version) { or if (installable->edition().asString() == pi->version) { std::string uses a shared data representation and performs copy on write, so creating a local edition_str is cheap. And it supports comparison with char*.
Is this what you had in mind? Isn't there an easier way to get this information?
I noticed that this only works for packages that are not installed. Is there a mechanism that would work for packages that are installed?
Too keep in mind: Inside the ui::Selectable("name") is a list of all available packages with that "name". The default/guess returned by ->candidateObj() actually depends on properties of an installed package if there is one (at least it's architecture and it's vendor). As you do not load the Target (installed) packages into the pool, it might be that the candidate returned is not the best choice for the real system. And the solver will assume there is no package installed, so he will always choose the best available version for a package. This is not necessarily what you'll get, if you actually install the selected package. It might always be that an already installed version fits as well. But if you include the target packages, the solver (most probably) no longer tells you about required but already installed packages... I'll think about a better solution... -- cu, Michael Andres +------------------------------------------------------------------+ Key fingerprint = 2DFA 5D73 18B1 E7EF A862 27AC 3FB8 9E3A 27C6 B0E4 +------------------------------------------------------------------+ Michael Andres YaST Development ma@novell.com SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg) Maxfeldstrasse 5, D-90409 Nuernberg, Germany, ++49 (0)911 - 740 53-0 +------------------------------------------------------------------+ -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
On Thu, Dec 13, Michael Andres wrote:
Please take a minute and review the following code:
http://pastebin.ca/812178 [...] Is this what you had in mind? Isn't there an easier way to get this information?
I noticed that this only works for packages that are not installed. Is there a mechanism that would work for packages that are installed?
Attached a small test program. Maybe you want to give it a try and see whether it matches your expectations. It computes 'dependent packages' (whatever this exacly means) for both, installed and available packages. 'NAME [EDITION [ARCH]]:' is a prompt. Enter a name and it looks for the best available package. If you specify an edition, it will first look for an installed one: NAME [EDITION [ARCH]]: A AdobeICCProfiles (I 2.0-74)(A 2.0-74.1 2.0-74 2.0-74) NAME [EDITION [ARCH]]: AdobeICCProfiles Package: U__s_[S1:1][package]AdobeICCProfiles-2.0-74.1.noarch depends on (0) {} NAME [EDITION [ARCH]]: AdobeICCProfiles 2.0-74 Package: I_TsU[S0:0][package]AdobeICCProfiles-2.0-74.noarch depends on (0) {} U__s_.. - U means uninstalled I_TsU.. - I means installed A more exiting ;=O example: NAME [EDITION [ARCH]]: sendmail Package: U__s_[S1:1][package]sendmail-8.14.1-53.1.x86_64 depends on (16) { I__s_[S0:0][package]filesystem-10.3-50.x86_64 I__s_[S0:0][package]sed-4.1.5-64.x86_64 I__s_[S0:0][package]fillup-1.42-179.x86_64 I__s_[S0:0][package]coreutils-6.9-43.x86_64 I__s_[S0:0][package]glibc-2.6.1-18.3.x86_64 I__s_[S0:0][package]libopenssl0_9_8-0.9.8e-45.5.x86_64 I__s_[S0:0][package]libdb-4_5-4.5.20-29.x86_64 I__s_[S0:0][package]openldap2-client-2.3.37-20.x86_64 I__s_[S0:0][package]cyrus-sasl-2.1.22-82.x86_64 I__s_[S0:0][package]tcpd-7.6-791.x86_64 I__s_[S0:0][package]m4-1.4.10-17.x86_64 I__s_[S0:0][package]netcfg-10.3-39.noarch I__s_[S0:0][package]procmail-3.22-139.x86_64 I__s_[S0:0][package]bash-3.2-61.x86_64 I__s_[S0:0][package]perl-base-5.8.8-76.2.x86_64 I__s_[S0:0][package]insserv-1.09.0-46.x86_64 } NAME [EDITION [ARCH]]: postfix Package: U__s_[S1:1][package]postfix-2.4.5-20.1.x86_64 depends on (15) { I__s_[S0:0][package]openldap2-client-2.3.37-20.x86_64 I__s_[S0:0][package]insserv-1.09.0-46.x86_64 I__s_[S0:0][package]sed-4.1.5-64.x86_64 I__s_[S0:0][package]fillup-1.42-179.x86_64 I__s_[S0:0][package]coreutils-6.9-43.x86_64 I__s_[S0:0][package]glibc-2.6.1-18.3.x86_64 I__s_[S0:0][package]libopenssl0_9_8-0.9.8e-45.5.x86_64 I__s_[S0:0][package]pcre-7.2-14.2.x86_64 I__s_[S0:0][package]libdb-4_5-4.5.20-29.x86_64 I__s_[S0:0][package]cyrus-sasl-2.1.22-82.x86_64 I__s_[S0:0][package]netcfg-10.3-39.noarch I__s_[S0:0][package]bash-3.2-61.x86_64 I__s_[S0:0][package]grep-2.5.2-28.x86_64 I__s_[S0:0][package]pwdutils-3.1.4-27.x86_64 I__s_[S0:0][package]gawk-3.1.5g-25.x86_64 } Compared to http://pastebin.ca/812178: - I load all the repos AND the target system. This is necessary to process installed packages and IMO gives a better result for available packages. - In 'FindDependent' I get the interesting PoolItem via 'getPi'. You use the PoolProxy class and get the selectable->candidateObj(). Even if the candidateObj's edition does not match the one you're looking for, it might be that a package with a matching edition is in the Selctable. 'getPi' tries a bit harder to find a package with your edition. - For solving I use 'setForceResolve( true )' to minimize the cases where the solver fails. Otherwise sendmail in the example above would not succeed, because it conflicts with my postfix installed. And I don't solve installed items, which is ok provided the system is in a consistent state. But one could as well solve in any case. - Finaly zypp::forEachPoolItemMatchedBy extracts the dependent packages. @ // TODO: Figure out how to determine whether a package is installed or not - You usually have a PoolItem pi - A PoolItem has a status: pi.status() - The status tells (among other things) whether it is installed: pi.status().isInstalled() In your case: it->item.status().isInstalled() -- cu, Michael Andres +------------------------------------------------------------------+ Key fingerprint = 2DFA 5D73 18B1 E7EF A862 27AC 3FB8 9E3A 27C6 B0E4 +------------------------------------------------------------------+ Michael Andres YaST Development ma@novell.com SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg) Maxfeldstrasse 5, D-90409 Nuernberg, Germany, ++49 (0)911 - 740 53-0 +------------------------------------------------------------------+
On Dec 14, 2007 2:54 PM, Michael Andres <ma@suse.de> wrote:
On Thu, Dec 13, Michael Andres wrote:
Please take a minute and review the following code:
http://pastebin.ca/812178 [...] Is this what you had in mind? Isn't there an easier way to get this information?
I noticed that this only works for packages that are not installed. Is there a mechanism that would work for packages that are installed?
Attached a small test program. Maybe you want to give it a try and see whether it matches your expectations. It computes 'dependent packages' (whatever this exacly means) for both, installed and available packages.
'NAME [EDITION [ARCH]]:' is a prompt. Enter a name and it looks for the best available package. If you specify an edition, it will first look for an installed one:
NAME [EDITION [ARCH]]: A AdobeICCProfiles (I 2.0-74)(A 2.0-74.1 2.0-74 2.0-74)
NAME [EDITION [ARCH]]: AdobeICCProfiles Package: U__s_[S1:1][package]AdobeICCProfiles-2.0-74.1.noarch depends on (0) {}
NAME [EDITION [ARCH]]: AdobeICCProfiles 2.0-74 Package: I_TsU[S0:0][package]AdobeICCProfiles-2.0-74.noarch depends on (0) {}
U__s_.. - U means uninstalled I_TsU.. - I means installed
A more exiting ;=O example:
NAME [EDITION [ARCH]]: sendmail Package: U__s_[S1:1][package]sendmail-8.14.1-53.1.x86_64 depends on (16) { I__s_[S0:0][package]filesystem-10.3-50.x86_64 I__s_[S0:0][package]sed-4.1.5-64.x86_64 I__s_[S0:0][package]fillup-1.42-179.x86_64 I__s_[S0:0][package]coreutils-6.9-43.x86_64 I__s_[S0:0][package]glibc-2.6.1-18.3.x86_64 I__s_[S0:0][package]libopenssl0_9_8-0.9.8e-45.5.x86_64 I__s_[S0:0][package]libdb-4_5-4.5.20-29.x86_64 I__s_[S0:0][package]openldap2-client-2.3.37-20.x86_64 I__s_[S0:0][package]cyrus-sasl-2.1.22-82.x86_64 I__s_[S0:0][package]tcpd-7.6-791.x86_64 I__s_[S0:0][package]m4-1.4.10-17.x86_64 I__s_[S0:0][package]netcfg-10.3-39.noarch I__s_[S0:0][package]procmail-3.22-139.x86_64 I__s_[S0:0][package]bash-3.2-61.x86_64 I__s_[S0:0][package]perl-base-5.8.8-76.2.x86_64 I__s_[S0:0][package]insserv-1.09.0-46.x86_64 } NAME [EDITION [ARCH]]: postfix Package: U__s_[S1:1][package]postfix-2.4.5-20.1.x86_64 depends on (15) { I__s_[S0:0][package]openldap2-client-2.3.37-20.x86_64 I__s_[S0:0][package]insserv-1.09.0-46.x86_64 I__s_[S0:0][package]sed-4.1.5-64.x86_64 I__s_[S0:0][package]fillup-1.42-179.x86_64 I__s_[S0:0][package]coreutils-6.9-43.x86_64 I__s_[S0:0][package]glibc-2.6.1-18.3.x86_64 I__s_[S0:0][package]libopenssl0_9_8-0.9.8e-45.5.x86_64 I__s_[S0:0][package]pcre-7.2-14.2.x86_64 I__s_[S0:0][package]libdb-4_5-4.5.20-29.x86_64 I__s_[S0:0][package]cyrus-sasl-2.1.22-82.x86_64 I__s_[S0:0][package]netcfg-10.3-39.noarch I__s_[S0:0][package]bash-3.2-61.x86_64 I__s_[S0:0][package]grep-2.5.2-28.x86_64 I__s_[S0:0][package]pwdutils-3.1.4-27.x86_64 I__s_[S0:0][package]gawk-3.1.5g-25.x86_64 }
Compared to http://pastebin.ca/812178:
- I load all the repos AND the target system. This is necessary to process installed packages and IMO gives a better result for available packages.
- In 'FindDependent' I get the interesting PoolItem via 'getPi'. You use the PoolProxy class and get the selectable->candidateObj().
Even if the candidateObj's edition does not match the one you're looking for, it might be that a package with a matching edition is in the Selctable. 'getPi' tries a bit harder to find a package with your edition.
- For solving I use 'setForceResolve( true )' to minimize the cases where the solver fails. Otherwise sendmail in the example above would not succeed, because it conflicts with my postfix installed.
And I don't solve installed items, which is ok provided the system is in a consistent state. But one could as well solve in any case.
- Finaly zypp::forEachPoolItemMatchedBy extracts the dependent packages.
@ // TODO: Figure out how to determine whether a package is installed or not
- You usually have a PoolItem pi - A PoolItem has a status: pi.status() - The status tells (among other things) whether it is installed: pi.status().isInstalled()
In your case: it->item.status().isInstalled()
Thanks Michael for the code, suggestions, and review. I'll let you know how the progress goes. Boyd -- To unsubscribe, e-mail: zypp-devel+unsubscribe@opensuse.org For additional commands, e-mail: zypp-devel+help@opensuse.org
participants (9)
-
Benji Weber
-
Boyd Timothy
-
Duncan Mac-Vicar Prett
-
Jan Kupec
-
Michael Andres
-
Michael Schroeder
-
Stanislav Visnovsky
-
Stefan Schubert
-
Stephan Kulow