Author: jkupec
Date: Mon Oct 27 13:37:37 2008
New Revision: 11502
URL: http://svn.opensuse.org/viewcvs/zypp?rev=11502&view=rev
Log:
- fixing package selection (update candidate)
- preparing for install by arch (using .arch suffix)
Modified:
trunk/zypper/src/install.cc
trunk/zypper/src/update.cc
trunk/zypper/src/update.h
Modified: trunk/zypper/src/install.cc
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/zypper/src/install.cc?rev=11502&r1=11501&r2=11502&view=diff
==============================================================================
--- trunk/zypper/src/install.cc (original)
+++ trunk/zypper/src/install.cc Mon Oct 27 13:37:37 2008
@@ -1,5 +1,5 @@
#include
-
+//#include <iostream>
#include "zypp/ZYppFactory.h"
#include "zypp/base/Logger.h"
#include "zypp/base/Algorithm.h"
@@ -35,26 +35,34 @@
return result;
}
-// TODO edition, arch ?
-static void mark_for_install(Zypper & zypper,
+// TODO edition - need solver API
+static void
+mark_for_install(Zypper & zypper,
const ResObject::Kind &kind,
- const std::string &name,
- const std::string & repo = "")
+ const string &name,
+ const string & repo = "",
+ const string & arch = "")
{
// name and kind match:
- DBG << "Iterating over [" << kind << "]" << name << endl;
+ DBG << "Iterating over [" << kind << "] " << name;
+ if (!repo.empty())
+ DBG << ", repo: " << repo;
+ if (!arch.empty())
+ DBG << ", arch: " << arch;
+ DBG << "...";
PoolQuery q;
q.addAttribute(sat::SolvAttr::name, name);
if (!repo.empty())
q.addRepo(repo);
+ if (!arch.empty())
+ q.addAttribute(sat::SolvAttr::arch, arch);
q.setCaseSensitive(false);
q.setMatchExact();
- DBG << "... done" << endl;
-
if (q.empty())
{
+ DBG << "... done" << endl;
zypper.out().error(
// translators: meaning a package %s or provider of capability %s
str::form(_("'%s' not found"), name.c_str()));
@@ -66,36 +74,24 @@
}
ui::Selectable::Ptr s = *q.selectableBegin();
+ DBG << "... done" << endl;
+/*
+ for_(it, s->installedBegin(), s->installedEnd())
+ { cout << *it << endl; }
+ for_(it, s->availableBegin(), s->availableEnd())
+ { cout << *it << endl; }
+*/
bool force = copts.count("force");
+
#if USE_THE_ONE
PoolItem candidate = s->candidateObj();
#else
- PoolItem candidate = findUpdateItem(God->pool(), s->installedObj());
- if (!candidate)
- {
- if (force)
- {
- candidate = findInstalledItemInRepos(s->installedObj());
- if (!candidate)
- {
- zypper.out().info(str::form(
- // translators: %s-%s.%s is name-version.arch
- _("Package %s-%s.%s not found in repositories, cannot reinstall."),
- s->name().c_str(), s->installedObj().resolvable()->edition().c_str(),
- s->installedObj().resolvable()->arch().c_str()));
- zypper.setExitCode(ZYPPER_EXIT_ERR_ZYPP);
- return;
- }
- }
- else
- candidate = s->installedObj();
- }
+ PoolItem candidate = findTheBest(God->pool(), *s);
#endif
if (s->installedObj() &&
- s->installedObj().resolvable()->edition() == candidate.resolvable()->edition() &&
- s->installedObj().resolvable()->arch() == candidate.resolvable()->arch() &&
+ equalNVRA(*s->installedObj().resolvable(), *candidate.resolvable()) &&
!force)
{
// if it is broken install anyway, even if it is installed
@@ -108,12 +104,32 @@
_("skipping %s '%s' (the newest version already installed)"))
% kind_to_string_localized(kind,1) % name));
}
- else if (!candidate.status().setToBeInstalled(zypp::ResStatus::USER) && !force)
+ else
{
- zypper.out().error(boost::str(
- format(_("Failed to add '%s' to the list of packages to be installed."))
- % name));
- ERR << "Could not set " << name << " as to-be-installed" << endl;
+ if (force && !s->installedEmpty())
+ {
+ PoolItem repoitem = findInstalledItemInRepos(s->installedObj());
+ if (!repoitem)
+ {
+ zypper.out().info(str::form(
+ // translators: %s-%s.%s is name-version.arch
+ _("Package %s-%s.%s not found in repositories, cannot reinstall."),
+ s->name().c_str(), s->installedObj().resolvable()->edition().c_str(),
+ s->installedObj().resolvable()->arch().c_str()));
+ zypper.setExitCode(ZYPPER_EXIT_ERR_ZYPP);
+ return;
+ }
+ else if (candidate.status().isInstalled())
+ candidate = repoitem;
+ }
+
+ if (!candidate.status().setToBeInstalled(zypp::ResStatus::USER) && !force)
+ {
+ zypper.out().error(boost::str(
+ format(_("Failed to add '%s' to the list of packages to be installed."))
+ % name));
+ ERR << "Could not set " << name << " as to-be-installed" << endl;
+ }
}
}
@@ -177,10 +193,11 @@
bool install_not_remove,
const ResObject::Kind &kind,
const string &name,
- const string & repo = "")
+ const string & repo = "",
+ const string & arch = "")
{
if (install_not_remove)
- mark_for_install(zypper, kind, name, repo);
+ mark_for_install(zypper, kind, name, repo, arch);
else
mark_for_uninstall(zypper, kind, name);
}
@@ -281,14 +298,7 @@
#if USE_THE_ONE
PoolItem theone = s.theObj();
#else
- PoolItem theone;
- if (s.installedEmpty())
- theone = *s.availableBegin();
- else
- theone = findUpdateItem(God->pool(), *s.installedBegin());
-
- if (!theone)
- theone = *s.installedBegin();
+ PoolItem theone = findTheBest(God->pool(), s);
#endif
DBG << "the One: " << theone << endl;
@@ -497,14 +507,22 @@
force_by_name = true; // until there is a solver API for this
}
- //! \todo force arch with '.' or '@'???
- if ((pos = str.find('.')) != string::npos)
- { }
+ // force arch with '.'
+ if ((pos = str.rfind('.')) != string::npos)
+ {
+ arch = str.substr(pos + 1);
+ str = str.substr(0, pos);
+ if (Arch(arch).isBuiltIn())
+ force_by_name = true; // until there is a solver API for this
+ else
+ DBG << "Unknown arch (" << arch << ") in package " << str
+ << ", will treat it like capability name." << endl;
+ }
// mark by name by force
if (force_by_name)
{
- mark_by_name (zypper, install_not_remove, kind, str, repo);
+ mark_by_name (zypper, install_not_remove, kind, str, repo, arch);
continue;
}
Modified: trunk/zypper/src/update.cc
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/zypper/src/update.cc?rev=11502&r1=11501&r2=11502&view=diff
==============================================================================
--- trunk/zypper/src/update.cc (original)
+++ trunk/zypper/src/update.cc Mon Oct 27 13:37:37 2008
@@ -171,7 +171,7 @@
tr << patch->repoInfo().name();
tr << res->name () << res->edition ().asString();
tr << patch->category();
- tr << _("Needed");
+ tr << _("Needed");
if (patch->restartSuggested ())
pm_tbl << tr;
@@ -204,7 +204,7 @@
/*
* Collect items, select the best edition.
- * This is used to find the best available or installed pool item from a set.
+ * This is used to find the best available or installed pool item from a set.
*/
class SaveBetterEdition : public zypp::resfilter::PoolItemFilterFunctor
{
@@ -228,7 +228,7 @@
// does not allow changing the arch (#222140).
PoolItem
-findUpdateItem( const ResPool & pool, PoolItem item )
+findUpdateItem( const ResPool & pool, const PoolItem item )
{
SaveBetterEdition info;
@@ -246,6 +246,26 @@
return info.best;
}
+PoolItem
+findTheBest( const ResPool & pool, const ui::Selectable & s)
+{
+ PoolItem theone;
+ if (s.installedEmpty())
+ theone = findUpdateItem(God->pool(), *s.availableBegin());
+ else
+ theone = findUpdateItem(God->pool(), *s.installedBegin());
+
+ if (!theone)
+ {
+ if (s.installedEmpty())
+ theone = *s.availableBegin();
+ else
+ theone = *s.installedBegin();
+ }
+
+ return theone;
+}
+
// ----------------------------------------------------------------------------
typedef set<PoolItem> Candidates;
@@ -575,7 +595,7 @@
{
DBG << "marking all needed patches" << endl;
- for_(it, God->pool().proxy().byKindBegin(ResKind::patch),
+ for_(it, God->pool().proxy().byKindBegin(ResKind::patch),
God->pool().proxy().byKindEnd (ResKind::patch))
{
if (mark_patch_update((*it)->candidateObj(), skip_interactive, ignore_affects_pm))
@@ -590,7 +610,7 @@
PoolQuery q;
q.addKind(ResKind::patch);
q.addAttribute(sat::SolvAttr::name, *it);
- //! \todo should we look for patches requiring packages with matching name instead?
+ //! \todo should we look for patches requiring packages with matching name instead?
//q.addAttribute(sat::SolvAttr::require, *it);
q.setMatchGlob();
@@ -650,7 +670,7 @@
invokeOnEach (candidates.begin(), candidates.end(), require_item_update);
else
invokeOnEach (candidates.begin(), candidates.end(), mark_item_install);
- }
+ }
}
}
// treat arguments as package names (+allow wildcards)
@@ -666,7 +686,7 @@
q.addAttribute(sat::SolvAttr::name, *it);
q.setMatchGlob();
q.setInstalledOnly();
-
+
if (q.empty())
{
if (it->find_first_of("?*") != string::npos) // wildcards used
@@ -684,14 +704,7 @@
#if USE_THE_ONE
PoolItem theone = s.theObj();
#else
- PoolItem theone;
-
- if (s->installedEmpty())
- theone = *s->availableBegin();
- else
- theone = findUpdateItem(God->pool(), *s->installedBegin());
- if (!theone)
- theone = *s->installedBegin();
+ PoolItem theone = findTheBest(God->pool(), *s);
#endif
if (equalNVRA(*s->installedObj().resolvable(), *theone.resolvable()))
Modified: trunk/zypper/src/update.h
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/zypper/src/update.h?rev=11502&r1=11501&r2=11502&view=diff
==============================================================================
--- trunk/zypper/src/update.h (original)
+++ trunk/zypper/src/update.h Mon Oct 27 13:37:37 2008
@@ -14,7 +14,7 @@
* if repo_alias != "", restrict updates to this repository.
* if best_effort == true, any version greater than the installed one will do.
* Prints the table of updates to stdout.
- *
+ *
* \param kind resolvable type
* \param best_effort
*/
@@ -22,7 +22,7 @@
const ResKindSet & kinds,
bool best_effort);
-/** \todo remove from this header after xu is dropped */
+/** \todo remove from this header after xu is dropped */
bool xml_list_patches();
/** \todo remove from this header after xu is dropped */
void xml_list_updates(const ResKindSet & kinds);
@@ -40,8 +40,18 @@
/**
* Find best (according to edition) uninstalled item
* with same kind/name/arch as \a item.
- *
+ *
* Similar to zypp::solver::detail::Helper::findUpdateItem()
* but allows changing the vendor and does not allow chaning arch.
*/
-zypp::PoolItem findUpdateItem(const zypp::ResPool & pool, zypp::PoolItem item);
+zypp::PoolItem findUpdateItem(const zypp::ResPool & pool, const zypp::PoolItem item);
+
+/**
+ * Finds the best object in the Selectable.
+ *
+ * \todo FIXME if there is no installed object in the selectable, it chooses
+ * a random arch from the available objects (the availableBegin()). Choose
+ * the best compatible instead.
+ * \todo All of this should be done in libzypp, using defined policies.
+ */
+zypp::PoolItem findTheBest( const zypp::ResPool & pool, const zypp::ui::Selectable & s);
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org