- --from added to install command to mark packages
authorJan Kupec <jkupec@suse.cz>
Thu, 30 Oct 2008 17:27:03 +0000 (17:27 +0000)
committerJan Kupec <jkupec@suse.cz>
Thu, 30 Oct 2008 17:27:03 +0000 (17:27 +0000)
  for installation (by glob/name) from specified
  repos
- --entire-catalog option for rug compatibility
  (does 'zypper in --from repo '*') (bnc #439806)

src/Zypper.cc
src/install.cc
src/repos.cc
src/repos.h

index 3776790..54f5174 100644 (file)
@@ -852,6 +852,7 @@ void Zypper::processCommandOptions()
       {"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'},
@@ -869,6 +870,8 @@ void Zypper::processCommandOptions()
       // 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}
     };
@@ -2955,10 +2958,11 @@ void Zypper::doCommand()
   {
     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;
@@ -2982,6 +2986,16 @@ void Zypper::doCommand()
     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";
index 37b8f80..e0a74ea 100755 (executable)
@@ -11,6 +11,7 @@
 
 #include "install.h"
 #include "update.h"
+#include "repos.h"
 
 using namespace std;
 using namespace zypp;
@@ -41,7 +42,8 @@ mark_for_install(Zypper & zypper,
                       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;
@@ -53,6 +55,7 @@ mark_for_install(Zypper & zypper,
 
   PoolQuery q;
   q.addAttribute(sat::SolvAttr::name, name);
+  q.addKind(kind);
   if (!repo.empty())
     q.addRepo(repo);
   if (!arch.empty())
@@ -60,7 +63,8 @@ mark_for_install(Zypper & zypper,
   q.setCaseSensitive(false);
   q.setMatchExact();
 
-  if (q.empty())
+//  if (q.empty())
+  if (q.begin() == q.end())
   {
     DBG << "... done" << endl;
     zypper.out().error(
@@ -97,7 +101,7 @@ mark_for_install(Zypper & zypper,
     // 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
@@ -194,10 +198,11 @@ mark_by_name (Zypper & zypper,
               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);
 }
@@ -478,6 +483,54 @@ void install_remove(Zypper & zypper,
   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();
index af7bd50..518b2b3 100644 (file)
@@ -415,7 +415,7 @@ void get_repos(Zypper & zypper,
 /**
  * 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(
index 8d9882e..30c1fcf 100644 (file)
@@ -8,6 +8,8 @@
 #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
@@ -60,7 +69,7 @@ void clean_repos(Zypper & zypper);
 
 /**
  * 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
@@ -70,11 +79,11 @@ bool match_repo(Zypper & zypper, const std::string str, zypp::RepoInfo *repo);
 
 /**
  * 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,
@@ -89,9 +98,9 @@ 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,
@@ -102,7 +111,7 @@ 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);
 
@@ -119,14 +128,14 @@ void rename_repo(Zypper & zypper,
 
 /**
  * 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);
 
@@ -159,7 +168,7 @@ bool match_service(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);
 
@@ -173,12 +182,12 @@ void load_resolvables(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);
 
@@ -186,7 +195,7 @@ 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();