const ZypperCommand ZypperCommand::PATCHES(ZypperCommand::PATCHES_e);
const ZypperCommand ZypperCommand::PATTERNS(ZypperCommand::PATTERNS_e);
const ZypperCommand ZypperCommand::PRODUCTS(ZypperCommand::PRODUCTS_e);
+const ZypperCommand ZypperCommand::WHAT_PROVIDES(ZypperCommand::WHAT_PROVIDES_e);
+//const ZypperCommand ZypperCommand::WHAT_REQUIRES(ZypperCommand::WHAT_REQUIRES_e);
+//const ZypperCommand ZypperCommand::WHAT_CONFLICTS(ZypperCommand::WHAT_CONFLICTS_e);
const ZypperCommand ZypperCommand::XML_LIST_UPDATES_PATCHES(ZypperCommand::XML_LIST_UPDATES_PATCHES_e);
const ZypperCommand ZypperCommand::ADD_LOCK(ZypperCommand::ADD_LOCK_e);
_table["patches"] = _table["pch"] = ZypperCommand::PATCHES_e;
_table["patterns"] = _table["pt"] = ZypperCommand::PATTERNS_e;
_table["products"] = _table["pd"] = ZypperCommand::PRODUCTS_e;
+ _table["what-provides"] = _table["wp"] = ZypperCommand::WHAT_PROVIDES_e;
+ //_table["what-requires"] = _table["wr"] = ZypperCommand::WHAT_REQUIRES_e;
+ //_table["what-conflicts"] = _table["wc"] = ZypperCommand::WHAT_CONFLICTS_e;
_table["xml-updates"] = _table["xu"] = ZypperCommand::XML_LIST_UPDATES_PATCHES_e;
_table["addlock"] = _table["al"] = _table["lock-add"] = _table["la"] = ZypperCommand::ADD_LOCK_e;
static const ZypperCommand PATCHES;
static const ZypperCommand PATTERNS;
static const ZypperCommand PRODUCTS;
+ static const ZypperCommand WHAT_PROVIDES;
+ //static const ZypperCommand WHAT_REQUIRES;
+ //static const ZypperCommand WHAT_CONFLICTS;
static const ZypperCommand XML_LIST_UPDATES_PATCHES;
static const ZypperCommand ADD_LOCK;
PATCHES_e,
PATTERNS_e,
PRODUCTS_e,
+ WHAT_PROVIDES_e,
+ //WHAT_REQUIRES_e,
+ //WHAT_CONFLICTS_e,
XML_LIST_UPDATES_PATCHES_e,
ADD_LOCK_e,
// converts a user-supplied kind to a zypp kind object
// returns an empty one if not recognized
-ResObject::Kind string_to_kind (const string &skind)
+ResKind string_to_kind (const string &skind)
{
ResObject::Kind empty;
string lskind = str::toLower (skind);
return true;
}
-/**
- * Stops iterations on first item and stores edition of the found item.
- *
- * If no item has been found, the \ref found variable is set to false.
- */
-struct VersionGetter
-{
- Edition edition;
- bool found;
-
- VersionGetter() : found(false) {}
-
- bool operator()(const zypp::PoolItem& item)
- {
- edition = item.resolvable()->edition();
- found = true;
- return false; // don't iterate further
- }
-};
-
-/**
- * Stops iterations on first item having revision newer than edition passed in
- * contructor. Stores the edition of the found item.
- *
- * If no item has been found, the \ref found variable is set to false.
- */
-struct NewerVersionGetter
-{
- const Edition & old_edition;
- Edition edition;
- bool found;
-
- NewerVersionGetter(const Edition & edition) : old_edition(edition), found(false) {}
-
- bool operator()(const zypp::PoolItem& item)
- {
- if (item.resolvable()->edition() > old_edition)
- {
- edition = item.resolvable()->edition();
- found = true;
- return false; // don't iterate further
- }
-
- return true;
- }
-};
-
-// on error print a message and return noCap
-static Capability safe_parse_cap (Zypper & zypper,
- const ResObject::Kind &kind, const string & capstr)
-{
- Capability cap;
- try {
- // expect named caps as NAME[OP<EDITION>]
- // transform to NAME[ OP <EDITION>] (add spaces)
- string new_capstr = capstr;
- DBG << "capstr: " << capstr << endl;
- string::size_type op_pos = capstr.find_first_of("<>=");
- if (op_pos != string::npos)
- {
- new_capstr.insert(op_pos, " ");
- DBG << "new capstr: " << new_capstr << endl;
- op_pos = new_capstr.find_first_not_of("<>=", op_pos + 1);
- if (op_pos != string::npos && new_capstr.size() > op_pos)
- {
- new_capstr.insert(op_pos, " ");
- DBG << "new capstr: " << new_capstr << endl;
- }
- }
- // if we are about to install stuff and
- // if this is not a candidate for a versioned capability, take it like
- // a package name and check if it is already installed
- else if (zypper.command() == ZypperCommand::INSTALL)
- {
- using namespace zypp::functor;
- using namespace zypp::resfilter;
-
- // get the installed version
- VersionGetter vg;
- invokeOnEach(
- God->pool().byIdentBegin(kind, capstr),
- God->pool().byIdentEnd(kind,capstr),
- ByInstalled(),
- functorRef<bool,const zypp::PoolItem&> (vg));
- // installed found
- if (vg.found)
- {
- // check for newer version of that resolvable
- NewerVersionGetter nvg(vg.edition);
- invokeOnEach(
- God->pool().byIdentBegin(kind, capstr),
- God->pool().byIdentEnd(kind,capstr),
- not_c(ByInstalled()),
- functorRef<bool,const zypp::PoolItem&> (nvg));
- // newer version found
- if (nvg.found)
- {
- DBG << "installed resolvable named " << capstr
- << " found, changing capability to " << new_capstr << endl;
- new_capstr = capstr + " > " + vg.edition.asString();
- }
- }
- }
- cap = Capability( new_capstr.c_str(), kind );
- }
- catch (const Exception& e) {
- //! \todo check this handling (should we fail or set a special exit code?)
- ZYPP_CAUGHT(e);
- zypper.out().error(boost::str(
- format(_("Cannot parse capability '%s'.")) % capstr));
- }
- return cap;
-}
-
// this does only resolvables with this _name_.
// we could also act on _provides_
// TODO edition, arch
DBG << "trying: " << trythis << endl;
- Capability cap = safe_parse_cap (zypper, kind, trythis);
+ Capability cap = safe_parse_cap (zypper, trythis, kind);
sat::WhatProvides q(cap);
if (!q.empty())
// try by capability
- Capability cap = safe_parse_cap (zypper, kind, str);
+ Capability cap = safe_parse_cap (zypper, str, kind);
sat::WhatProvides q(cap);
// is there a provider for the requested capability?
#define ZMART_MISC_H
#include <string>
+
#include "zypp/ResKind.h"
#include "zypp/PoolItem.h"
#include "zypper-utils.h"
-zypp::ResObject::Kind string_to_kind (const std::string &skind);
+zypp::ResKind string_to_kind (const std::string & skind);
/**
* Run the solver.
cout << tbl;
}
+
+void list_what_provides(Zypper & zypper, const string & str)
+{
+ Capability cap = safe_parse_cap (zypper, /*kind,*/ str);
+ sat::WhatProvides q(cap);
+
+ // is there a provider for the requested capability?
+ if (q.empty())
+ {
+ zypper.out().info(str::form(_("No providers of '%s' found."), str.c_str()));
+ return;
+ }
+
+ Table t;
+ invokeOnEach(q.selectableBegin(), q.selectableEnd(), FillSearchTableSolvable(t) );
+ cout << t;
+}
+
// Local Variables:
// c-basic-offset: 2
// End:
/** List all products with specific info in specified repos */
void list_products(Zypper & zypper);
+/** List all providers of given capability */
+void list_what_provides(Zypper & zypper, const std::string & capstr);
+
#endif /*ZYPPERSEARCH_H_*/
#include "zypp/base/Logger.h"
#include "zypp/media/MediaManager.h"
#include "zypp/parser/xml_escape_parser.hpp"
+#include "zypp/Capability.h"
#include "zypper.h"
#include "zypper-main.h"
void report_too_many_arguments(const string & specific_help)
{
+ report_too_many_arguments(Zypper::instance()->out(), specific_help);
+}
+
+void report_too_many_arguments(Out & out, const string & specific_help)
+{
//! \todo make this more explanatory, e.g. "Ingoring arg1 arg2. This command does not take arguments. See %s for more information."
ostringstream s;
s << _("Usage") << ':' << endl << specific_help;
- Zypper::instance()->out().error(_("Too many arguments."), s.str());
+ out.error(_("Too many arguments."), s.str());
}
// ----------------------------------------------------------------------------
text.insert(0, string(columns, ' '));
return text;
}
+
+static string preparse_cap_str(const string & capstr)
+{
+ // expect versioned caps as NAME[OP<EDITION>]
+ // transform to NAME[ OP <EDITION>] (add spaces)
+ string new_capstr = capstr;
+ DBG << "capstr: " << capstr << endl;
+ string::size_type op_pos = capstr.find_first_of("<>=");
+ if (op_pos != string::npos)
+ {
+ new_capstr.insert(op_pos, " ");
+ DBG << "new capstr: " << new_capstr << endl;
+ op_pos = new_capstr.find_first_not_of("<>=", op_pos + 1);
+ if (op_pos != string::npos && new_capstr.size() > op_pos)
+ {
+ new_capstr.insert(op_pos, " ");
+ DBG << "new capstr: " << new_capstr << endl;
+ }
+ }
+
+ return new_capstr;
+}
+
+Capability safe_parse_cap (Zypper & zypper,
+ const string & capstr,
+ const ResKind & kind)
+{
+ try
+ {
+ if (kind == ResKind::nokind)
+ return Capability(preparse_cap_str(capstr));
+ else
+ return Capability(preparse_cap_str(capstr), kind);
+ }
+ catch (const Exception& e)
+ {
+ //! \todo check this handling (should we fail or set a special exit code?)
+ ZYPP_CAUGHT(e);
+ zypper.out().error(str::form(_("Cannot parse capability '%s'."), capstr.c_str()));
+ }
+ return Capability();
+}
void report_a_bug (Out & out);
/** Say that too many arguments have been specified */
-void report_too_many_arguments(const std::string & specific_help);
+void report_too_many_arguments(const std::string & specific_help); // deprecated
+void report_too_many_arguments(Out & out, const std::string & specific_help);
/** Say the specified option has no effect */
void report_dummy_option(Out & out, const std::string & longoption_str);
std::string & indent(std::string & text, int columns);
+zypp::Capability safe_parse_cap (Zypper & zypper,
+ const std::string & capstr,
+ const zypp::ResKind & kind = zypp::ResKind::nokind);
+
+
//comparator for RepoInfo set
class RepoInfoAliasComparator{
public: bool operator()(const zypp::RepoInfo &a, const zypp::RepoInfo& b){
"\tpackages, pa\t\tList all available packages.\n"
"\tpatterns, pt\t\tList all available patterns.\n"
"\tproducts, pd\t\tList all available products.\n"
+ "\twhat-provides, wp\tList packages providing specified capability.\n"
+ //"\twhat-requires, wr\tList packages requiring specified capability.\n"
+ //"\twhat-conflicts, wc\tList packages conflicting with specified capability.\n"
);
static string help_lock_commands = _("\tPackage Locks:\n"
break;
}
+ case ZypperCommand::WHAT_PROVIDES_e:
+ {
+ static struct option options[] = {
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+ specific_options = options;
+ _command_help = _(
+ "what-provides (wp) <capability>\n"
+ "\n"
+ "List all packages providing the specified capability.\n"
+ "\n"
+ "This command has no additional options.\n"
+ );
+ break;
+ }
+/*
+ case ZypperCommand::WHAT_REQUIRES_e:
+ {
+ static struct option options[] = {
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+ specific_options = options;
+ _command_help = _(
+ "what-requires (wr) <capability>\n"
+ "\n"
+ "List all packages requiring the specified capability.\n"
+ "\n"
+ "This command has no additional options.\n"
+ );
+ break;
+ }
+
+ case ZypperCommand::WHAT_CONFLICTS_e:
+ {
+ static struct option options[] = {
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+ specific_options = options;
+ _command_help = _(
+ "what-conflicts (wc) <capability>\n"
+ "\n"
+ "List all packages conflicting with the specified capability.\n"
+ "\n"
+ "This command has no additional options.\n"
+ );
+ break;
+ }
+*/
case ZypperCommand::MOO_e:
{
static struct option moo_options[] = {
break;
}
- // --------------------------( patches )------------------------------------
+ // --------------------------( misc queries )--------------------------------
case ZypperCommand::PATCHES_e:
case ZypperCommand::PATTERNS_e:
break;
}
+ case ZypperCommand::WHAT_PROVIDES_e:
+ {
+ if (runningHelp()) { out().info(_command_help, Out::QUIET); return; }
+
+ if (_arguments.empty())
+ report_required_arg_missing(out(), _command_help);
+ else if (_arguments.size() > 1)
+ report_too_many_arguments(out(), _command_help);
+
+ init_target(*this);
+ init_repos(*this);
+ if (exitCode() != ZYPPER_EXIT_OK)
+ return;
+ load_resolvables(*this);
+
+ switch (command().toEnum())
+ {
+ case ZypperCommand::WHAT_PROVIDES_e:
+ list_what_provides(*this, _arguments[0]);
+ break;
+ default:;
+ }
+
+ break;
+ }
+
// --------------------------( list updates )-------------------------------
case ZypperCommand::LIST_UPDATES_e: