[yast-devel] Adding missing API to libzypp (or between libzypp and apps)

Hi there! Check out this idea page and see what's needed and who intends to do what: http://idea.opensuse.org/content/ideas/better-api-for-applications-using-lib... This idea might be of interest for people writing applications using libzypp who were missing some functionalities and libzypp devels. In particular: YaST package manager UI (qt, gtk, curses), zypper, YaST online update. If you have any comments or want to participate, edit that page and use the discussion facility there and describe what would you like to do. Jano -- To unsubscribe, e-mail: yast-devel+unsubscribe@opensuse.org For additional commands, e-mail: yast-devel+help@opensuse.org

Seg, 2007-06-25 às 11:08 +0200, Jan Kupec escreveu:
Hi there!
Check out this idea page and see what's needed and who intends to do what:
http://idea.opensuse.org/content/ideas/better-api-for-applications-using-lib...
This idea might be of interest for people writing applications using libzypp who were missing some functionalities and libzypp devels. In particular: YaST package manager UI (qt, gtk, curses), zypper, YaST online update.
Hi, I don't have any feature request for libzypp; we can work out things pretty easily (say, dependencies listing), and I think it already has enough bloat. :P I don't really have much to criticize; its a decent library, at least API wise. In any case, libzypp API feels a bit overwhelming for someone just wanting to get some simple stuff done with it, so I would like to see some effort to make it more intuitive. I would suggest putting all the basic headers on the root (like ui/), and more specific stuff into some folder (like ByteCount.h). Also, merging classes, or simply putting classes that serve the same function in the same file. I also wonder if a lot of stuff is really necessary to have in your public API. And avoid the need to grep for stuff; don't do typedefs of your own typedefs for instance. I would also like to know the sense behind doing a typedef of the class type to call it "Self" (of course you get used to it, but all this small things accumulated, make the API not much intuitive I think). On the other hand, I find stuff like "using boost::shared_ptr;" to be evil. I personally don't like to import namespaces and I don't like being forced that practice (so, don't propagate that on your public headers). Not a big issue, but I would also rather you didn't use Boost pointers; it doesn't integrate well with other stuff. In our case, we store a few pointers in the data model that power the GTK+ list/tree widget. I also dislike the long nomenclature used; it forces people to do a translation layer to short them down, which sucks for the reader. libzypp is a relatively small library (or should be), so I don't understand, for instance, why the inner namespaces. All in all, I think it just requires polishing, nothing major. Cheers, Ricardo
If you have any comments or want to participate, edit that page and use the discussion facility there and describe what would you like to do.
Jano
-- To unsubscribe, e-mail: yast-devel+unsubscribe@opensuse.org For additional commands, e-mail: yast-devel+help@opensuse.org

I don't have any feature request for libzypp; we can work out things pretty easily (say, dependencies listing), and I think it already has enough bloat. :P
Well, the idea steadily evolved into something like 'writing a wrapper over libzypp' (called 'zypp4ui' for the time being) so that an application that needs to call libzypp function doesn't have to use libzypp low-level functions. Example: in your application, instead of doing: list <ZyppSelectable> patchList; for ( ZyppPoolIterator it = zyppPatchesBegin(); it != zyppPatchesEnd(); ++it ) { ZyppSel selectable = *it; ZyppPatch zyppPatch = tryCastToZyppPatch( selectable->theObj() ); if ( zyppPatch ) { patchList.push_back (*it) } } do_something_with_all_patches( patchList ); //example_end one just does: list <ZyppSelectable> patchList = zypp4ui::Patch::listAll(); do_something_with_all_patches(patchList); This low-level iteration through zypp pool would be wrapped into zypp4ui::Patch::listAll(), so that your application just calls this function, without adding the iteration code itself into the code of your library. I'll update the idea page by adding some information what I've done in this project so far. B. -- \\\\\ Katarina Machalkova \\\\\\\__o YaST developer __\\\\\\\'/_ & hedgehog painter

Qua, 2007-06-27 às 14:53 +0200, Katarina Machalkova escreveu:
I don't have any feature request for libzypp; we can work out things pretty easily (say, dependencies listing), and I think it already has enough bloat. :P
Well, the idea steadily evolved into something like 'writing a wrapper over libzypp' (called 'zypp4ui' for the time being) so that an application that needs to call libzypp function doesn't have to use libzypp low-level functions. Example: in your application, instead of doing:
Your example is a bit too simplistic (without knowing the use case, I don't see how you can't write simpler code using the pool instead of the list structure). But okay, I think the Zypp pool is deficient for some purposes, and having more, specific managers could help cut on code, and the usage of auxiliary structures in our part (though it is a bit wasteful...). For instance, to build a tree for the package groups, you would need to iterate the pool, asking each package for their group string (which would be something like "Productivity/Office"). Since they are not sorted, you need an auxiliary structure to map the groups to the node of the interface tree that you create as you iterate the pool. There could be ways to avoid this by either returning a more fit structure, or use better sorting. The first breaks way with the pool, the second asks for it be decentralized. The pool would also be completely bloated if it allowed one to set it possible to only iterate packages of a certain pattern, and other settings in a centralized way. So, having this specific managers would be better. However, I hope this library will be seen as more of a stub to be eventually adopted to libzypp (it's not even like you don't have the resources), rather than a serious, permanent library (a wrapper of a wrapper is undesirable on several accounts). Cheers, Ricardo -- To unsubscribe, e-mail: yast-devel+unsubscribe@opensuse.org For additional commands, e-mail: yast-devel+help@opensuse.org

On Wed, Jun 27, Katarina Machalkova wrote:
I don't have any feature request for libzypp; we can work out things pretty easily (say, dependencies listing), and I think it already has enough bloat. :P
Well, the idea steadily evolved into something like 'writing a wrapper over libzypp' (called 'zypp4ui' for the time being) so that an application that
Not wrap - fix, improve and cleanup zypp.
needs to call libzypp function doesn't have to use libzypp low-level functions.
What is a 'libzypp low-level function'?
Example: in your application, instead of doing:
list <ZyppSelectable> patchList; for ( ZyppPoolIterator it = zyppPatchesBegin(); it != zyppPatchesEnd(); ++it ) { ZyppSel selectable = *it; ZyppPatch zyppPatch = tryCastToZyppPatch( selectable->theObj() );
if ( zyppPatch ) { patchList.push_back (*it) } } do_something_with_all_patches( patchList ); //example_end
one just does:
list <ZyppSelectable> patchList = zypp4ui::Patch::listAll(); do_something_with_all_patches(patchList);
This low-level iteration through zypp pool would be wrapped into zypp4ui::Patch::listAll(), so that your application just calls this function, without adding the iteration code itself into the code of your library.
The larger the ammount of objects you process, the worse it is to build a temporary conatiner just to process these items. Avoiding them and becoming more flexible is one idea behind the concept of using iterators, algorithms and functors. We have basic support for this. It for shure needs polishing before Huha happily uses it. ;) The Selectable IMO has a big drawback: It's the UIs request to have one Selectable for each installed item. While the Pool contains all individual items (packages, patterns,...), the Selectable groups them by name and kind. A Selectable(package,kernel) contians a link to one installed and all available kernel packages. This is fine as long as there are 0 or 1 kernel packages installed. Each kernel package known by the Pool is 'conected' to the same Selectable. Pool Selectables i:kernel-1.0 ---+ | a:kernel-1.2 ---+---- S(package,kernel) a:kernel-2.0 ---+ Unfortunately we support installing multiple versions in parallel. So if there are 2 kernel packages installed, we have 2 Selectables for (package,kernel). Each one connected to all available, but a different installed version. Pool Selectables i:kernel-1.0 ---+---- S1(package,kernel) ----+ | i:kernel-1.2 ---+---- S2(package,kernel) --+ | | | a:kernel-1.2 ---+--------------------------+-+ a:kernel-2.0 ---+ This missing one-to-one relation is basically the reason why Selectables were not integated into the Pool. A Selectable is not that helpfull because it does not neccessarily link to ALL (package,kernel) items in the Pool. It lacks information that might be required to make decisions. And vice versa a Pool item as result of some query does not necessary lead to only one Selectable. Pool NameKindProxy i:kernel-1.0 ---+ i:kernel-1.2 ---+ +---- NKP(package,kernel) a:kernel-1.2 ---+ a:kernel-2.0 ---+ NameKindProxy does, what Selectables IMO should do, it links to all known Pool items of certain name and kind. And each Pool items is connected to one NameKindProxy. An object like this can easily be kept and maintained in the Pool. Pool items can contain a backlink to the corresponding NameKindProxy It would be a good place to provide convenient status manipulating methods. It could use the same policies as the solver to e.g propose the 'best' package for install or upgrade. Everything you improve here, will be available to all zypp based applications (zypper, pkg-bindings,..), and not just for the YaST UI. The UI Selectable would be a good candidate, IF it could avoid the duplicate Selectables. -- 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: yast-devel+unsubscribe@opensuse.org For additional commands, e-mail: yast-devel+help@opensuse.org

Well, the idea steadily evolved into something like 'writing a wrapper over libzypp' (called 'zypp4ui' for the time being) so that an application that
Not wrap - fix, improve and cleanup zypp.
Michaeli, mohl bys priste prosim psat sve komentare a pripominky v takovem jazyku, kteremu rozumi i normalni lide, jako treba ja? Dekuji Now let's get serious: Seems that we misunderstood each other and I admit that I was not that good at explaining what I am doing right now and what is the purpose of my work. I am not a zypp developer and I very often do not completely understand the black magic of zypp. But what I perceive as a real problem is that there are hundreds of lines of zypp code in yast UI libraries. The code is mostly doing things such as listing and filtering objects (i.e. selectables) and it's almost identical in all UI's. Example (maybe more obvious than a previous one): What do we want to do: Show pending licence agreements to the user (i.e. iterate through zypp pool, find packages/patterns that have licence agreement and show EULAs to the user - and yes, what I call 'low-level zypp function' is e.g. iterating through zypp pool and looking for something) How do we do it: in yast2-qt in 62 lines of code (http://svn.opensuse.org/viewcvs/yast/trunk/qt/src/pkg/YQPackageSelectorBase.... ), in yast2-ncurses in 56 lines of virtually identical code (http://svn.opensuse.org/viewcvs/yast/trunk/ncurses/src/pkg/NCPackageSelector...) My idea was to implement this function (showPendingLicenseAgreements()) in a wrapper library over zypp and have UI library link it and the code of UI library call it. Why to have the same code doing the same things on N different places (where N is the number of applications using concept of selectables), implementing features and doing bugfixes on N libraries, if we can have the code and the functionality in the single place and make all N applications use it? It would make maintenance much easier than now Just to make things work, I started up with function prototypes such as list <ZyppSell> filterFunction( some filter_variable) but I'm aware of the fact that it would potentially slow the whole thing down. First zypp4ui would iterate through zypp pool, return filtered list of selectables, and only after that UI application would process this list. I'm going to change it to something like; void filterFunction (some filter_variable, consumerFunction(ZyppSelectable &) where filterFunction would iterate through the zypp pool, check if selectable matches filter_variable and if so, call consumerFunction, which would be a function object actually processing the selectable - e.g. make a line in package table out of it, display its EULA text etc. All that in single pass through the pool. Hopefully I've now expressed myself more clearly B. -- \\\\\ Katarina Machalkova \\\\\\\__o YaST developer __\\\\\\\'/_ & hedgehog painter
participants (4)
-
Jan Kupec
-
Katarina Machalkova
-
Michael Andres
-
Ricardo Cruz