{"repo", required_argument, 0, 'r'},
// rug compatibility option, we have --repo
{"catalog", required_argument, 0, 'c'},
+ {"from", required_argument, 0, 0 },
{"type", required_argument, 0, 't'},
// the default (ignored)
{"name", no_argument, 0, 'n'},
// rug uses -N shorthand
{"dry-run", no_argument, 0, 'N'},
{"no-recommends", no_argument, 0, 0 },
+ // rug compatibility - will mark all packages for installation (like 'in *')
+ {"entire-catalog", required_argument, 0, 0 },
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
{
if (runningHelp()) { out().info(_command_help, Out::QUIET); return; }
- if (_arguments.size() < 1)
+ if (_arguments.size() < 1 && !_copts.count("entire-catalog"))
{
- out().error(string(_("Too few arguments.")) + " " +
- _("At least one package name is required.") + "\n");
+ out().error(
+ _("Too few arguments."),
+ _("At least one package name is required."));
out().info(_command_help);
setExitCode(ZYPPER_EXIT_ERR_INVALID_ARGS);
return;
if (copts.count("no-confirm"))
_gopts.non_interactive = true;
+ // rug compatibility code
+ parsed_opts::const_iterator optit;
+ if ((optit = _copts.find("entire-catalog")) != _copts.end())
+ {
+ if (!_arguments.empty())
+ out().warning(_("Ingoring arguments, marking the entire repository."));
+ _arguments.clear();
+ _arguments.push_back("*");
+ _copts["from"] = _copts["entire-catalog"];
+ }
// read resolvable type
string skind = copts.count("type")? copts["type"].front() : "package";
#include "install.h"
#include "update.h"
+#include "repos.h"
using namespace std;
using namespace zypp;
const ResObject::Kind &kind,
const string &name,
const string & repo = "",
- const string & arch = "")
+ const string & arch = "",
+ bool report_already_installed = true)
{
// name and kind match:
DBG << "Iterating over [" << kind << "] " << name;
PoolQuery q;
q.addAttribute(sat::SolvAttr::name, name);
+ q.addKind(kind);
if (!repo.empty())
q.addRepo(repo);
if (!arch.empty())
q.setCaseSensitive(false);
q.setMatchExact();
- if (q.empty())
+// if (q.empty())
+ if (q.begin() == q.end())
{
DBG << "... done" << endl;
zypper.out().error(
// if it is broken install anyway, even if it is installed
if (candidate.isBroken())
candidate.status().setToBeInstalled(zypp::ResStatus::USER);
- else
+ else if (report_already_installed)
zypper.out().info(boost::str(format(
// translators: e.g. skipping package 'zypper' (the newest version already installed)
//! \todo capitalize the first letter
const ResObject::Kind &kind,
const string &name,
const string & repo = "",
- const string & arch = "")
+ const string & arch = "",
+ bool report_already_installed = true) // might be a CLI option
{
if (install_not_remove)
- mark_for_install(zypper, kind, name, repo, arch);
+ mark_for_install(zypper, kind, name, repo, arch, report_already_installed);
else
mark_for_uninstall(zypper, kind, name);
}
Zypper::ArgList argsnew;
install_remove_preprocess_args(args, argsnew);
+ // --from
+
+ parsed_opts::const_iterator optit;
+ if (install_not_remove &&
+ (optit = zypper.cOpts().find("from")) != zypper.cOpts().end())
+ {
+ list<string> not_found;
+ list<RepoInfo> repos;
+ get_repos(zypper, optit->second.begin(), optit->second.end(), repos, not_found);
+ if (!not_found.empty())
+ {
+ report_unknown_repos(zypper.out(), not_found);
+ zypper.setExitCode(ZYPPER_EXIT_ERR_INVALID_ARGS);
+ return;
+ }
+
+ // for each argument search (glob) & mark
+ for_(strit, argsnew.begin(), argsnew.end())
+ {
+ bool found = false;
+ for_(it, repos.begin(), repos.end())
+ {
+ PoolQuery q;
+ q.addAttribute(sat::SolvAttr::name, *strit);
+ q.setMatchGlob();
+ q.addRepo(it->alias());
+ q.addKind(kind);
+
+ for_(sit, q.selectableBegin(), q.selectableEnd())
+ {
+ mark_by_name(zypper, true, kind, (*sit)->name(), it->alias(), "", false);
+ found = true;
+ }
+ }
+
+ if (!found)
+ {
+ // translators: meaning a package %s or provider of capability %s
+ zypper.out().error(str::form(_("'%s' not found."), strit->c_str()));
+ WAR << str::form("'%s' not found", strit->c_str()) << endl;
+ zypper.setExitCode(ZYPPER_EXIT_INF_CAP_NOT_FOUND);
+ if (zypper.globalOpts().non_interactive)
+ ZYPP_THROW(ExitRequestException());
+ }
+ }
+ return;
+ }
+
string str, arch, repo;
bool by_capability;
const ResPool & pool = God->pool();
/**
* Say "Repository %s not found" for all strings in \a not_found list.
*/
-static void report_unknown_repos(Out & out, list<string> not_found)
+void report_unknown_repos(Out & out, list<string> not_found)
{
for_(it, not_found.begin(), not_found.end())
out.error(boost::str(format(
#ifndef ZMART_SOURCES_H
#define ZMART_SOURCES_H
+#include <list>
+
#include "zypp/TriBool.h"
#include "zypp/Url.h"
#include "zypp/RepoInfo.h"
/**
* The same as \ref init_repos(), but allows to specify repos to initialize.
*
- * \param zypper The zypper instance.
+ * \param zypper The zypper instance.
* \param container A string container of identifier (alias|#|URI) to init.
*/
template <typename Container>
void init_repos(Zypper & zypper, const Container & container = Container());
+template<typename T>
+void get_repos(Zypper & zypper,
+ const T & begin, const T & end,
+ std::list<zypp::RepoInfo> & repos, std::list<std::string> & not_found);
+
+void report_unknown_repos(Out & out, std::list<std::string> not_found);
+
/**
* Reads known enabled repositories and stores them in gData.
* This command also refreshes repos with auto-refresh enabled.
- *
+ *
* sets exit status to
* - ZYPPER_EXIT_ERR_INVALID_ARGS if --repo does not specify a valid repository,
* - ZYPPER_EXIT_ERR_ZYPP on error
/**
* Try match given string with any known repository.
- *
+ *
* \param str string to match
* \param repo pointer to fill with found repository
* \return success if respository is found
/**
* Add repository specified by \url to system repositories.
- *
+ *
* \param url Valid URL of the repository.
* \param alias
* \param type
- * \param enabled Whether the repo should be enabled
+ * \param enabled Whether the repo should be enabled
* \param autorefresh Whether the repo should have autorefresh turned on
*/
void add_repo_by_url(Zypper & zypper,
* Add repository specified in given repo file on \a repo_file_url. All repos
* will be added enabled and with autorefresh turned on. The enabled and
* autorefresh values provided in the files will be ignored.
- *
+ *
* \param repo_file_url Valid URL of the repo file.
- * \param enabled Whether the repo should be enabled
+ * \param enabled Whether the repo should be enabled
* \param autorefresh Whether the repo should have autorefresh turned on
*/
void add_repo_from_file(Zypper & zypper,
/**
- * Add repository specified by \repo to system repositories.
+ * Add repository specified by \repo to system repositories.
*/
void add_repo(Zypper & zypper, zypp::RepoInfo & repo);
/**
* Modify repository properties.
- *
+ *
* \param alias repository alias
*/
void modify_repo(Zypper & zypper, const std::string & alias);
/**
* Modify all repositories properties.
- *
+ *
*/
void modify_all_repos(Zypper & zypper);
void modify_services_by_option( Zypper & zypper );
/**
- * Initialize rpm database on target, if not already initialized.
+ * Initialize rpm database on target, if not already initialized.
*/
void init_target(Zypper & zypper);
/**
* Reads resolvables from the RPM database (installed resolvables) into the pool.
- *
+ *
*/
void load_target_resolvables(Zypper & zypper);
/**
- * Reads resolvables from the repository solv cache.
+ * Reads resolvables from the repository solv cache.
*/
void load_repo_resolvables(Zypper & zypper);
/**
* If ZMD process found, notify user that ZMD is running and that changes
* to repositories will not be synchronized with it. To be used with commands
- * manipulating repositories like <tt>addrepo</tt> or <tt>rmrepo</tt>.
+ * manipulating repositories like <tt>addrepo</tt> or <tt>rmrepo</tt>.
*/
void warn_if_zmd();